From 5ebfaa88917ebcef1dd69e31e40014ce237c60e2 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Thu, 30 Nov 2017 21:41:16 -0500 Subject: [PATCH] deps: upgrade libuv to 1.18.0 PR-URL: https://github.com/nodejs/node/pull/17282 Reviewed-By: Ben Noordhuis --- deps/uv/AUTHORS | 3 + deps/uv/CONTRIBUTING.md | 2 +- deps/uv/ChangeLog | 52 +++++ deps/uv/Makefile.am | 2 +- deps/uv/appveyor.yml | 2 +- deps/uv/checksparse.sh | 10 + deps/uv/configure.ac | 2 +- deps/uv/docs/src/fs.rst | 4 +- deps/uv/docs/src/loop.rst | 3 +- deps/uv/docs/src/misc.rst | 6 + deps/uv/docs/src/signal.rst | 8 +- deps/uv/include/uv-unix.h | 2 + deps/uv/include/uv-version.h | 4 +- deps/uv/include/uv-win.h | 8 +- deps/uv/include/uv.h | 1 + deps/uv/src/unix/aix-common.c | 292 ++++++++++++++++++++++++++++ deps/uv/src/unix/aix.c | 237 +--------------------- deps/uv/src/unix/core.c | 5 + deps/uv/src/unix/ibmi.c | 112 +++++++++++ deps/uv/src/unix/os390-syscalls.c | 9 + deps/uv/src/unix/os390-syscalls.h | 1 + deps/uv/src/unix/process.c | 14 +- deps/uv/src/unix/stream.c | 5 +- deps/uv/src/unix/tcp.c | 101 +++++++--- deps/uv/src/win/fs.c | 9 +- deps/uv/src/win/pipe.c | 4 +- deps/uv/src/win/thread.c | 1 + deps/uv/src/win/util.c | 5 + deps/uv/test/run-tests.c | 5 + deps/uv/test/test-fs.c | 62 +++++- deps/uv/test/test-list.h | 8 + deps/uv/test/test-platform-output.c | 4 + deps/uv/test/test-spawn.c | 79 ++++++++ deps/uv/test/test-thread.c | 32 ++- deps/uv/uv.gyp | 38 +++- 35 files changed, 817 insertions(+), 315 deletions(-) create mode 100644 deps/uv/src/unix/aix-common.c create mode 100644 deps/uv/src/unix/ibmi.c diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 03255534fa1de3..b227123e4ac35c 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -318,3 +318,6 @@ Scott Parker Wade Brainerd rayrase Pekka Nikander +Ed Schouten +Xu Meng +Matt Harrison diff --git a/deps/uv/CONTRIBUTING.md b/deps/uv/CONTRIBUTING.md index aa97506dbc6923..d9bf0472fb1fc3 100644 --- a/deps/uv/CONTRIBUTING.md +++ b/deps/uv/CONTRIBUTING.md @@ -164,6 +164,6 @@ not send out notifications when you add commits. [issue tracker]: https://github.com/libuv/libuv/issues [libuv mailing list]: http://groups.google.com/group/libuv -[IRC]: http://webchat.freelibuv.net/?channels=libuv +[IRC]: http://webchat.freenode.net/?channels=libuv [Google C/C++ style guide]: https://google.github.io/styleguide/cppguide.html [project maintainers]: https://github.com/libuv/libuv/blob/master/MAINTAINERS.md diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 595b3871278898..113c28aed136a7 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,55 @@ +2017.12.02, Version 1.18.0 (Stable), 1489c98b7fc17f1702821a269eb0c5e730c5c813 + +Changes since version 1.17.0: + +* aix: fix -Wmaybe-uninitialized warning (cjihrig) + +* doc: remove note about SIGWINCH on Windows (Bartosz Sosnowski) + +* Revert "unix,win: wait for threads to start" (Ben Noordhuis) + +* unix,win: add uv_os_getpid() (Bartosz Sosnowski) + +* unix: remove incorrect assertion in uv_shutdown() (Jameson Nash) + +* doc: fix IRC URL in CONTRIBUTING.md (Matt Harrison) + + +2017.11.25, Version 1.17.0 (Stable), 1344d2bb82e195d0eafc0b40ba103f18dfd04cc5 + +Changes since version 1.16.1: + +* unix: avoid malloc() call in uv_spawn() (Ben Noordhuis) + +* doc: clarify the description of uv_loop_alive() (Ed Schouten) + +* win: map UV_FS_O_EXLOCK to a share mode of 0 (Joran Dirk Greef) + +* win: fix build on case-sensitive file systems (Ben Noordhuis) + +* win: fix test runner build with mingw64 (Ben Noordhuis) + +* win: remove unused variable in test/test-fs.c (Ben Noordhuis) + +* zos: add strnlen() implementation (jBarz) + +* unix: keep track of bound sockets sent via spawn (jBarz) + +* unix,win: wait for threads to start (Ben Noordhuis) + +* test: add threadpool init/teardown test (Bartosz Sosnowski) + +* test: avoid malloc() in threadpool test (Ben Noordhuis) + +* test: lower number of tasks in threadpool test (Ben Noordhuis) + +* win: issue memory barrier in uv_thread_join() (Ben Noordhuis) + +* ibmi: add support for new platform (Xu Meng) + +* test: fix test-spawn compilation (Bartosz Sosnowski) + + 2017.11.11, Version 1.16.1 (Stable), 4056fbe46493ef87237e307e0025e551db875e13 Changes since version 1.16.0: diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index 6e548a69c374e6..e01cf416638bfe 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -329,7 +329,7 @@ libuv_la_CFLAGS += -D_ALL_SOURCE \ -D_THREAD_SAFE \ -DHAVE_SYS_AHAFS_EVPRODS_H include_HEADERS += include/uv-aix.h -libuv_la_SOURCES += src/unix/aix.c +libuv_la_SOURCES += src/unix/aix.c src/unix/aix-common.c endif if ANDROID diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml index 8ad69718b6e619..f77e640eb10f09 100644 --- a/deps/uv/appveyor.yml +++ b/deps/uv/appveyor.yml @@ -1,4 +1,4 @@ -version: v1.16.1.build{build} +version: v1.18.0.build{build} init: - git config --global core.autocrlf true diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh index ae0e5374f5efba..d4a983d02618b5 100755 --- a/deps/uv/checksparse.sh +++ b/deps/uv/checksparse.sh @@ -177,8 +177,18 @@ case `uname -s` in AIX) SPARSE_FLAGS="$SPARSE_FLAGS -D_AIX=1" SOURCES="$SOURCES + src/unix/aix-common.c src/unix/aix.c" ;; +OS400) + SPARSE_FLAGS="$SPARSE_FLAGS -D_PASE=1" + SOURCES="$SOURCES + src/unix/aix-common.c + src/unix/ibmi.c + src/unix/posix-poll.c + src/unix/no-fsevents.c + src/unix/no-proctitle.c" + ;; Darwin) SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1" SOURCES="$SOURCES diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 5fc0f72434d92e..7eb1674dbaa7fb 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.16.1], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.18.0], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst index f46c4e761a5d2f..16d5e05c7834cf 100644 --- a/deps/uv/docs/src/fs.rst +++ b/deps/uv/docs/src/fs.rst @@ -409,7 +409,9 @@ File open constants Atomically obtain an exclusive lock. .. note:: - `UV_FS_O_EXLOCK` is only supported on macOS. + `UV_FS_O_EXLOCK` is only supported on macOS and Windows. + + .. versionchanged:: 1.17.0 support is added for Windows. .. c:macro:: UV_FS_O_NOATIME diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst index c63f813993ff4b..18dd135cd63834 100644 --- a/deps/uv/docs/src/loop.rst +++ b/deps/uv/docs/src/loop.rst @@ -109,7 +109,8 @@ API .. c:function:: int uv_loop_alive(const uv_loop_t* loop) - Returns non-zero if there are active handles or request in the loop. + Returns non-zero if there are referenced active handles, active + requests or closing handles in the loop. .. c:function:: void uv_stop(uv_loop_t* loop) diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index 2968d1cea1cc2b..a653413e0927bd 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -227,6 +227,12 @@ API On Windows not all fields are set, the unsupported fields are filled with zeroes. See :c:type:`uv_rusage_t` for more details. +.. c:function:: uv_pid_t uv_os_getpid(void) + + Returns the current process ID. + + .. versionadded:: 1.18.0 + .. c:function:: uv_pid_t uv_os_getppid(void) Returns the parent process ID. diff --git a/deps/uv/docs/src/signal.rst b/deps/uv/docs/src/signal.rst index 5b3b352bdd257d..24354e4f7c1329 100644 --- a/deps/uv/docs/src/signal.rst +++ b/deps/uv/docs/src/signal.rst @@ -17,13 +17,6 @@ Reception of some signals is emulated on Windows: program is given approximately 10 seconds to perform cleanup. After that Windows will unconditionally terminate it. -* SIGWINCH is raised whenever libuv detects that the console has been - resized. SIGWINCH is emulated by libuv when the program uses a :c:type:`uv_tty_t` - handle to write to the console. SIGWINCH may not always be delivered in a - timely manner; libuv will only detect size changes when the cursor is - being moved. When a readable :c:type:`uv_tty_t` handle is used in raw mode, - resizing the console buffer will also trigger a SIGWINCH signal. - Watchers for other signals can be successfully created, but these signals are never received. These signals are: `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`, `SIGTERM` and `SIGKILL.` @@ -36,6 +29,7 @@ not detected by libuv; these will not trigger a signal watcher. manage threads. Installing watchers for those signals will lead to unpredictable behavior and is strongly discouraged. Future versions of libuv may simply reject them. +.. versionchanged:: 1.15.0 SIGWINCH support on Windows was improved. Data types ---------- diff --git a/deps/uv/include/uv-unix.h b/deps/uv/include/uv-unix.h index 6565ff441ef292..da32f86e8476fa 100644 --- a/deps/uv/include/uv-unix.h +++ b/deps/uv/include/uv-unix.h @@ -48,6 +48,8 @@ # include "uv-linux.h" #elif defined (__MVS__) # include "uv-os390.h" +#elif defined(_PASE) +# include "uv-posix.h" #elif defined(_AIX) # include "uv-aix.h" #elif defined(__sun) diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h index 1c9113cdc9f7ee..831ee54de4486e 100644 --- a/deps/uv/include/uv-version.h +++ b/deps/uv/include/uv-version.h @@ -31,8 +31,8 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 16 -#define UV_VERSION_PATCH 1 +#define UV_VERSION_MINOR 18 +#define UV_VERSION_PATCH 0 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/include/uv-win.h b/deps/uv/include/uv-win.h index be150fc482f92e..b96bed22ace759 100644 --- a/deps/uv/include/uv-win.h +++ b/deps/uv/include/uv-win.h @@ -664,13 +664,13 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s); #define UV_FS_O_WRONLY _O_WRONLY /* fs open() flags supported on other platforms (or mapped on this platform): */ -#define UV_FS_O_DIRECT 0x2000000 /* FILE_FLAG_NO_BUFFERING */ +#define UV_FS_O_DIRECT 0x02000000 /* FILE_FLAG_NO_BUFFERING */ #define UV_FS_O_DIRECTORY 0 -#define UV_FS_O_DSYNC 0x4000000 /* FILE_FLAG_WRITE_THROUGH */ -#define UV_FS_O_EXLOCK 0 +#define UV_FS_O_DSYNC 0x04000000 /* FILE_FLAG_WRITE_THROUGH */ +#define UV_FS_O_EXLOCK 0x10000000 /* EXCLUSIVE SHARING MODE */ #define UV_FS_O_NOATIME 0 #define UV_FS_O_NOCTTY 0 #define UV_FS_O_NOFOLLOW 0 #define UV_FS_O_NONBLOCK 0 #define UV_FS_O_SYMLINK 0 -#define UV_FS_O_SYNC 0x8000000 /* FILE_FLAG_WRITE_THROUGH */ +#define UV_FS_O_SYNC 0x08000000 /* FILE_FLAG_WRITE_THROUGH */ diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 3f61812081da5e..b11666e2e65806 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -1070,6 +1070,7 @@ UV_EXTERN int uv_os_homedir(char* buffer, size_t* size); UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size); UV_EXTERN int uv_os_get_passwd(uv_passwd_t* pwd); UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd); +UV_EXTERN uv_pid_t uv_os_getpid(void); UV_EXTERN uv_pid_t uv_os_getppid(void); UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count); diff --git a/deps/uv/src/unix/aix-common.c b/deps/uv/src/unix/aix-common.c new file mode 100644 index 00000000000000..2cfe8be6f11830 --- /dev/null +++ b/deps/uv/src/unix/aix-common.c @@ -0,0 +1,292 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +uint64_t uv__hrtime(uv_clocktype_t type) { + uint64_t G = 1000000000; + timebasestruct_t t; + read_wall_time(&t, TIMEBASE_SZ); + time_base_to_time(&t, TIMEBASE_SZ); + return (uint64_t) t.tb_high * G + t.tb_low; +} + + +/* + * We could use a static buffer for the path manipulations that we need outside + * of the function, but this function could be called by multiple consumers and + * we don't want to potentially create a race condition in the use of snprintf. + * There is no direct way of getting the exe path in AIX - either through /procfs + * or through some libc APIs. The below approach is to parse the argv[0]'s pattern + * and use it in conjunction with PATH environment variable to craft one. + */ +int uv_exepath(char* buffer, size_t* size) { + int res; + char args[PATH_MAX]; + char abspath[PATH_MAX]; + size_t abspath_size; + struct procsinfo pi; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + pi.pi_pid = getpid(); + res = getargs(&pi, sizeof(pi), args, sizeof(args)); + if (res < 0) + return -EINVAL; + + /* + * Possibilities for args: + * i) an absolute path such as: /home/user/myprojects/nodejs/node + * ii) a relative path such as: ./node or ../myprojects/nodejs/node + * iii) a bare filename such as "node", after exporting PATH variable + * to its location. + */ + + /* Case i) and ii) absolute or relative paths */ + if (strchr(args, '/') != NULL) { + if (realpath(args, abspath) != abspath) + return -errno; + + abspath_size = strlen(abspath); + + *size -= 1; + if (*size > abspath_size) + *size = abspath_size; + + memcpy(buffer, abspath, *size); + buffer[*size] = '\0'; + + return 0; + } else { + /* Case iii). Search PATH environment variable */ + char trypath[PATH_MAX]; + char *clonedpath = NULL; + char *token = NULL; + char *path = getenv("PATH"); + + if (path == NULL) + return -EINVAL; + + clonedpath = uv__strdup(path); + if (clonedpath == NULL) + return -ENOMEM; + + token = strtok(clonedpath, ":"); + while (token != NULL) { + snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, args); + if (realpath(trypath, abspath) == abspath) { + /* Check the match is executable */ + if (access(abspath, X_OK) == 0) { + abspath_size = strlen(abspath); + + *size -= 1; + if (*size > abspath_size) + *size = abspath_size; + + memcpy(buffer, abspath, *size); + buffer[*size] = '\0'; + + uv__free(clonedpath); + return 0; + } + } + token = strtok(NULL, ":"); + } + uv__free(clonedpath); + + /* Out of tokens (path entries), and no match found */ + return -EINVAL; + } +} + +void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { + int i; + + for (i = 0; i < count; ++i) { + uv__free(cpu_infos[i].model); + } + + uv__free(cpu_infos); +} + + +int uv_interface_addresses(uv_interface_address_t** addresses, + int* count) { + uv_interface_address_t* address; + int sockfd, inet6, size = 1; + struct ifconf ifc; + struct ifreq *ifr, *p, flg; + struct sockaddr_dl* sa_addr; + + *count = 0; + + if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) { + return -errno; + } + + if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) { + uv__close(sockfd); + return -errno; + } + + ifc.ifc_req = (struct ifreq*)uv__malloc(size); + ifc.ifc_len = size; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { + uv__close(sockfd); + return -errno; + } + +#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p)) + + /* Count all up and running ipv4/ipv6 addresses */ + ifr = ifc.ifc_req; + while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { + p = ifr; + ifr = (struct ifreq*) + ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); + + if (!(p->ifr_addr.sa_family == AF_INET6 || + p->ifr_addr.sa_family == AF_INET)) + continue; + + memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { + uv__close(sockfd); + return -errno; + } + + if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) + continue; + + (*count)++; + } + + /* Alloc the return interface structs */ + *addresses = uv__malloc(*count * sizeof(uv_interface_address_t)); + if (!(*addresses)) { + uv__close(sockfd); + return -ENOMEM; + } + address = *addresses; + + ifr = ifc.ifc_req; + while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { + p = ifr; + ifr = (struct ifreq*) + ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); + + if (!(p->ifr_addr.sa_family == AF_INET6 || + p->ifr_addr.sa_family == AF_INET)) + continue; + + inet6 = (p->ifr_addr.sa_family == AF_INET6); + + memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { + uv__close(sockfd); + return -ENOSYS; + } + + if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) + continue; + + /* All conditions above must match count loop */ + + address->name = uv__strdup(p->ifr_name); + + if (inet6) + address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); + else + address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr); + + sa_addr = (struct sockaddr_dl*) &p->ifr_addr; + memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); + + if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) { + uv__close(sockfd); + return -ENOSYS; + } + + if (inet6) + address->netmask.netmask6 = *((struct sockaddr_in6*) &p->ifr_addr); + else + address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr); + + address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0; + + address++; + } + +#undef ADDR_SIZE + + uv__close(sockfd); + return 0; +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + int i; + + for (i = 0; i < count; ++i) { + uv__free(addresses[i].name); + } + + uv__free(addresses); +} \ No newline at end of file diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c index 56a8f4ffe753e8..06f19a4fc9fc54 100644 --- a/deps/uv/src/unix/aix.c +++ b/deps/uv/src/unix/aix.c @@ -1,4 +1,5 @@ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the @@ -316,104 +317,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - uint64_t G = 1000000000; - timebasestruct_t t; - read_wall_time(&t, TIMEBASE_SZ); - time_base_to_time(&t, TIMEBASE_SZ); - return (uint64_t) t.tb_high * G + t.tb_low; -} - - -/* - * We could use a static buffer for the path manipulations that we need outside - * of the function, but this function could be called by multiple consumers and - * we don't want to potentially create a race condition in the use of snprintf. - * There is no direct way of getting the exe path in AIX - either through /procfs - * or through some libc APIs. The below approach is to parse the argv[0]'s pattern - * and use it in conjunction with PATH environment variable to craft one. - */ -int uv_exepath(char* buffer, size_t* size) { - int res; - char args[PATH_MAX]; - char abspath[PATH_MAX]; - size_t abspath_size; - struct procsinfo pi; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - pi.pi_pid = getpid(); - res = getargs(&pi, sizeof(pi), args, sizeof(args)); - if (res < 0) - return -EINVAL; - - /* - * Possibilities for args: - * i) an absolute path such as: /home/user/myprojects/nodejs/node - * ii) a relative path such as: ./node or ../myprojects/nodejs/node - * iii) a bare filename such as "node", after exporting PATH variable - * to its location. - */ - - /* Case i) and ii) absolute or relative paths */ - if (strchr(args, '/') != NULL) { - if (realpath(args, abspath) != abspath) - return -errno; - - abspath_size = strlen(abspath); - - *size -= 1; - if (*size > abspath_size) - *size = abspath_size; - - memcpy(buffer, abspath, *size); - buffer[*size] = '\0'; - - return 0; - } else { - /* Case iii). Search PATH environment variable */ - char trypath[PATH_MAX]; - char *clonedpath = NULL; - char *token = NULL; - char *path = getenv("PATH"); - - if (path == NULL) - return -EINVAL; - - clonedpath = uv__strdup(path); - if (clonedpath == NULL) - return -ENOMEM; - - token = strtok(clonedpath, ":"); - while (token != NULL) { - snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, args); - if (realpath(trypath, abspath) == abspath) { - /* Check the match is executable */ - if (access(abspath, X_OK) == 0) { - abspath_size = strlen(abspath); - - *size -= 1; - if (*size > abspath_size) - *size = abspath_size; - - memcpy(buffer, abspath, *size); - buffer[*size] = '\0'; - - uv__free(clonedpath); - return 0; - } - } - token = strtok(NULL, ":"); - } - uv__free(clonedpath); - - /* Out of tokens (path entries), and no match found */ - return -EINVAL; - } -} - - uint64_t uv_get_free_memory(void) { perfstat_memory_total_t mem_total; int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1); @@ -1018,6 +921,7 @@ int uv_uptime(double* uptime) { size_t entries = 0; time_t boot_time; + boot_time = 0; utmpname(UTMP_FILE); setutent(); @@ -1094,143 +998,6 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { } -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; ++i) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { - uv_interface_address_t* address; - int sockfd, inet6, size = 1; - struct ifconf ifc; - struct ifreq *ifr, *p, flg; - struct sockaddr_dl* sa_addr; - - *count = 0; - - if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) { - return -errno; - } - - if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) { - uv__close(sockfd); - return -errno; - } - - ifc.ifc_req = (struct ifreq*)uv__malloc(size); - ifc.ifc_len = size; - if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { - uv__close(sockfd); - return -errno; - } - -#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p)) - - /* Count all up and running ipv4/ipv6 addresses */ - ifr = ifc.ifc_req; - while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { - p = ifr; - ifr = (struct ifreq*) - ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); - - if (!(p->ifr_addr.sa_family == AF_INET6 || - p->ifr_addr.sa_family == AF_INET)) - continue; - - memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { - uv__close(sockfd); - return -errno; - } - - if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) - continue; - - (*count)++; - } - - /* Alloc the return interface structs */ - *addresses = (uv_interface_address_t*) - uv__malloc(*count * sizeof(uv_interface_address_t)); - if (!(*addresses)) { - uv__close(sockfd); - return -ENOMEM; - } - address = *addresses; - - ifr = ifc.ifc_req; - while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { - p = ifr; - ifr = (struct ifreq*) - ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); - - if (!(p->ifr_addr.sa_family == AF_INET6 || - p->ifr_addr.sa_family == AF_INET)) - continue; - - inet6 = (p->ifr_addr.sa_family == AF_INET6); - - memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { - uv__close(sockfd); - return -ENOSYS; - } - - if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) - continue; - - /* All conditions above must match count loop */ - - address->name = uv__strdup(p->ifr_name); - - if (inet6) - address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); - else - address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr); - - sa_addr = (struct sockaddr_dl*) &p->ifr_addr; - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - - if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) { - uv__close(sockfd); - return -ENOSYS; - } - - if (inet6) - address->netmask.netmask6 = *((struct sockaddr_in6*) &p->ifr_addr); - else - address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr); - - address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0; - - address++; - } - -#undef ADDR_SIZE - - uv__close(sockfd); - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; ++i) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} - void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { struct pollfd* events; uintptr_t i; diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index d64593a3134729..c7e431e5295d1b 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -1345,6 +1345,11 @@ uv_os_fd_t uv_get_osfhandle(int fd) { } +uv_pid_t uv_os_getpid(void) { + return getpid(); +} + + uv_pid_t uv_os_getppid(void) { return getppid(); } diff --git a/deps/uv/src/unix/ibmi.c b/deps/uv/src/unix/ibmi.c new file mode 100644 index 00000000000000..8380d02db7616d --- /dev/null +++ b/deps/uv/src/unix/ibmi.c @@ -0,0 +1,112 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +uint64_t uv_get_free_memory(void) { + return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES); +} + + +uint64_t uv_get_total_memory(void) { + return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES); +} + + +void uv_loadavg(double avg[3]) { + avg[0] = avg[1] = avg[2] = 0; + return; +} + + +int uv_resident_set_memory(size_t* rss) { + return UV_ENOSYS; +} + + +int uv_uptime(double* uptime) { + return UV_ENOSYS; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + unsigned int numcpus, idx = 0; + uv_cpu_info_t* cpu_info; + + *cpu_infos = NULL; + *count = 0; + + numcpus = sysconf(_SC_NPROCESSORS_ONLN); + + *cpu_infos = uv__malloc(numcpus * sizeof(uv_cpu_info_t)); + if (!*cpu_infos) { + return -ENOMEM; + } + + cpu_info = *cpu_infos; + for (idx = 0; idx < numcpus; idx++) { + cpu_info->speed = 0; + cpu_info->model = uv__strdup("unknown"); + cpu_info->cpu_times.user = 0; + cpu_info->cpu_times.sys = 0; + cpu_info->cpu_times.idle = 0; + cpu_info->cpu_times.irq = 0; + cpu_info->cpu_times.nice = 0; + cpu_info++; + } + *count = numcpus; + + return 0; +} \ No newline at end of file diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c index 86c6852b4b608c..5bc489387ef3c5 100644 --- a/deps/uv/src/unix/os390-syscalls.c +++ b/deps/uv/src/unix/os390-syscalls.c @@ -427,3 +427,12 @@ ssize_t os390_readlink(const char* path, char* buf, size_t len) { return rlen; } + + +size_t strnlen(const char* str, size_t maxlen) { + void* p = memchr(str, 0, maxlen); + if (p == NULL) + return maxlen; + else + return p - str; +} diff --git a/deps/uv/src/unix/os390-syscalls.h b/deps/uv/src/unix/os390-syscalls.h index 7aba3d27da7f9b..5ce6a681bf1cb3 100644 --- a/deps/uv/src/unix/os390-syscalls.h +++ b/deps/uv/src/unix/os390-syscalls.h @@ -66,5 +66,6 @@ int scandir(const char* maindir, struct dirent*** namelist, const struct dirent **)); char *mkdtemp(char* path); ssize_t os390_readlink(const char* path, char* buf, size_t len); +size_t strnlen(const char* str, size_t maxlen); #endif /* UV_OS390_SYSCALL_H_ */ diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 80b9686ec828f4..9842710d0ea159 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -419,6 +419,7 @@ int uv_spawn(uv_loop_t* loop, return -ENOSYS; #else int signal_pipe[2] = { -1, -1 }; + int pipes_storage[8][2]; int (*pipes)[2]; int stdio_count; ssize_t r; @@ -443,7 +444,10 @@ int uv_spawn(uv_loop_t* loop, stdio_count = 3; err = -ENOMEM; - pipes = uv__malloc(stdio_count * sizeof(*pipes)); + pipes = pipes_storage; + if (stdio_count > (int) ARRAY_SIZE(pipes_storage)) + pipes = uv__malloc(stdio_count * sizeof(*pipes)); + if (pipes == NULL) goto error; @@ -548,7 +552,9 @@ int uv_spawn(uv_loop_t* loop, process->pid = pid; process->exit_cb = options->exit_cb; - uv__free(pipes); + if (pipes != pipes_storage) + uv__free(pipes); + return exec_errorno; error: @@ -562,7 +568,9 @@ int uv_spawn(uv_loop_t* loop, if (pipes[i][1] != -1) uv__close_nocheckstdio(pipes[i][1]); } - uv__free(pipes); + + if (pipes != pipes_storage) + uv__free(pipes); } return err; diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 672a7e2d6c65f6..6fc0a01f5a51a6 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -1261,8 +1261,9 @@ static void uv__read(uv_stream_t* stream) { int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) { - assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE) && - "uv_shutdown (unix) only supports uv_handle_t right now"); + assert(stream->type == UV_TCP || + stream->type == UV_TTY || + stream->type == UV_NAMED_PIPE); if (!(stream->flags & UV_STREAM_WRITABLE) || stream->flags & UV_STREAM_SHUT || diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c index c423dcb15fe11d..c7c8d21c668080 100644 --- a/deps/uv/src/unix/tcp.c +++ b/deps/uv/src/unix/tcp.c @@ -28,15 +28,12 @@ #include -static int maybe_new_socket(uv_tcp_t* handle, int domain, int flags) { +static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { + struct sockaddr_storage saddr; + socklen_t slen; int sockfd; int err; - if (domain == AF_UNSPEC || uv__stream_fd(handle) != -1) { - handle->flags |= flags; - return 0; - } - err = uv__socket(domain, SOCK_STREAM, 0); if (err < 0) return err; @@ -48,10 +45,74 @@ static int maybe_new_socket(uv_tcp_t* handle, int domain, int flags) { return err; } + if (flags & UV_HANDLE_BOUND) { + /* Bind this new socket to an arbitrary port */ + slen = sizeof(saddr); + memset(&saddr, 0, sizeof(saddr)); + err = getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen); + if (err) { + uv__close(sockfd); + return err; + } + + err = bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen); + if (err) { + uv__close(sockfd); + return err; + } + } + return 0; } +static int maybe_new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { + struct sockaddr_storage saddr; + socklen_t slen; + + if (domain == AF_UNSPEC) { + handle->flags |= flags; + return 0; + } + + if (uv__stream_fd(handle) != -1) { + + if (flags & UV_HANDLE_BOUND) { + + if (handle->flags & UV_HANDLE_BOUND) { + /* It is already bound to a port. */ + handle->flags |= flags; + return 0; + } + + /* Query to see if tcp socket is bound. */ + slen = sizeof(saddr); + memset(&saddr, 0, sizeof(saddr)); + if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) + return -errno; + + if ((saddr.ss_family == AF_INET6 && + ((struct sockaddr_in6*) &saddr)->sin6_port != 0) || + (saddr.ss_family == AF_INET && + ((struct sockaddr_in*) &saddr)->sin_port != 0)) { + /* Handle is already bound to a port. */ + handle->flags |= flags; + return 0; + } + + /* Bind to arbitrary port */ + if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) + return -errno; + } + + handle->flags |= flags; + return 0; + } + + return new_socket(handle, domain, flags); +} + + int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* tcp, unsigned int flags) { int domain; @@ -260,6 +321,7 @@ int uv_tcp_getpeername(const uv_tcp_t* handle, int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { static int single_accept = -1; + unsigned long flags; int err; if (tcp->delayed_error) @@ -273,30 +335,17 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { if (single_accept) tcp->flags |= UV_TCP_SINGLE_ACCEPT; - err = maybe_new_socket(tcp, AF_INET, UV_STREAM_READABLE); - if (err) - return err; - -#ifdef __MVS__ + flags = UV_STREAM_READABLE; +#if defined(__MVS__) /* on zOS the listen call does not bind automatically if the socket is unbound. Hence the manual binding to an arbitrary port is required to be done manually */ - - if (!(tcp->flags & UV_HANDLE_BOUND)) { - struct sockaddr_storage saddr; - socklen_t slen = sizeof(saddr); - memset(&saddr, 0, sizeof(saddr)); - - if (getsockname(tcp->io_watcher.fd, (struct sockaddr*) &saddr, &slen)) - return -errno; - - if (bind(tcp->io_watcher.fd, (struct sockaddr*) &saddr, slen)) - return -errno; - - tcp->flags |= UV_HANDLE_BOUND; - } -#endif + flags |= UV_HANDLE_BOUND; +#endif + err = maybe_new_socket(tcp, AF_INET, flags); + if (err) + return err; if (listen(tcp->io_watcher.fd, backlog)) return -errno; diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index b90eaa7548969a..11c7c13edd04d6 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -439,8 +439,15 @@ void fs__open(uv_fs_t* req) { * does. We indiscriminately use all the sharing modes, to match * UNIX semantics. In particular, this ensures that the file can * be deleted even whilst it's open, fixing issue #1449. + * We still support exclusive sharing mode, since it is necessary + * for opening raw block devices, otherwise Windows will prevent + * any attempt to write past the master boot record. */ - share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + if (flags & UV_FS_O_EXLOCK) { + share = 0; + } else { + share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + } switch (flags & (UV_FS_O_CREAT | UV_FS_O_EXCL | UV_FS_O_TRUNC)) { case 0: diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 642213bc8886c2..1a7c4dc15e0b30 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -31,8 +31,8 @@ #include "stream-inl.h" #include "req-inl.h" -#include -#include +#include +#include typedef struct uv__ipc_queue_item_s uv__ipc_queue_item_t; diff --git a/deps/uv/src/win/thread.c b/deps/uv/src/win/thread.c index 30b2d7793cf906..9eaad77cd02c97 100644 --- a/deps/uv/src/win/thread.c +++ b/deps/uv/src/win/thread.c @@ -182,6 +182,7 @@ int uv_thread_join(uv_thread_t *tid) { else { CloseHandle(*tid); *tid = 0; + MemoryBarrier(); /* For feature parity with pthread_join(). */ return 0; } } diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 2aec9f8dfe3e2b..3100bc23ad3e09 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -331,6 +331,11 @@ uint64_t uv_get_total_memory(void) { } +uv_pid_t uv_os_getpid(void) { + return GetCurrentProcessId(); +} + + uv_pid_t uv_os_getppid(void) { int parent_pid = -1; HANDLE handle; diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c index 4e10b68f3b42f7..da4ac82e431124 100644 --- a/deps/uv/test/run-tests.c +++ b/deps/uv/test/run-tests.c @@ -43,6 +43,7 @@ int ipc_send_recv_helper(void); int ipc_helper_bind_twice(void); int stdio_over_pipes_helper(void); int spawn_stdin_stdout(void); +int spawn_tcp_server_helper(void); static int maybe_run_test(int argc, char **argv); @@ -111,6 +112,10 @@ static int maybe_run_test(int argc, char **argv) { return 1; } + if (strcmp(argv[1], "spawn_tcp_server_helper") == 0) { + return spawn_tcp_server_helper(); + } + if (strcmp(argv[1], "spawn_helper3") == 0) { char buffer[256]; ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin)); diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 6afa650793e670..cae02dd1fddec8 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -32,8 +32,12 @@ defined(__APPLE__) || defined(_AIX) || defined(__MVS__) #include /* unlink, rmdir, etc. */ #else +# include # include # include +# ifndef ERROR_SYMLINK_NOT_SUPPORTED +# define ERROR_SYMLINK_NOT_SUPPORTED 1464 +# endif # define unlink _unlink # define rmdir _rmdir # define open _open @@ -2167,7 +2171,6 @@ TEST_IMPL(fs_utime) { #ifdef _WIN32 TEST_IMPL(fs_stat_root) { int r; - uv_loop_t* loop = uv_default_loop(); r = uv_fs_stat(NULL, &stat_req, "\\", NULL); ASSERT(r == 0); @@ -3061,3 +3064,60 @@ TEST_IMPL(fs_null_req) { return 0; } + +#ifdef _WIN32 +TEST_IMPL(fs_exclusive_sharing_mode) { + int r; + + /* Setup. */ + unlink("test_file"); + + ASSERT(UV_FS_O_EXLOCK > 0); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_RDWR | O_CREAT | UV_FS_O_EXLOCK, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + r = uv_fs_open(NULL, + &open_req2, + "test_file", + O_RDONLY | UV_FS_O_EXLOCK, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r < 0); + ASSERT(open_req2.result < 0); + uv_fs_req_cleanup(&open_req2); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, + &open_req2, + "test_file", + O_RDONLY | UV_FS_O_EXLOCK, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req2.result >= 0); + uv_fs_req_cleanup(&open_req2); + + r = uv_fs_close(NULL, &close_req, open_req2.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 3e88e6c928d096..2adbe6a017cfc3 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -260,6 +260,7 @@ TEST_DECLARE (spawn_closed_process_io) TEST_DECLARE (spawn_reads_child_path) TEST_DECLARE (spawn_inherit_streams) TEST_DECLARE (spawn_quoted_path) +TEST_DECLARE (spawn_tcp_server) TEST_DECLARE (fs_poll) TEST_DECLARE (fs_poll_getpath) TEST_DECLARE (kill) @@ -321,6 +322,9 @@ TEST_DECLARE (fs_write_alotof_bufs) TEST_DECLARE (fs_write_alotof_bufs_with_offset) TEST_DECLARE (fs_file_pos_after_op_with_offset) TEST_DECLARE (fs_null_req) +#ifdef _WIN32 +TEST_DECLARE (fs_exclusive_sharing_mode) +#endif TEST_DECLARE (threadpool_queue_work_simple) TEST_DECLARE (threadpool_queue_work_einval) TEST_DECLARE (threadpool_multiple_event_loops) @@ -740,6 +744,7 @@ TASK_LIST_START TEST_ENTRY (spawn_reads_child_path) TEST_ENTRY (spawn_inherit_streams) TEST_ENTRY (spawn_quoted_path) + TEST_ENTRY (spawn_tcp_server) TEST_ENTRY (fs_poll) TEST_ENTRY (fs_poll_getpath) TEST_ENTRY (kill) @@ -832,6 +837,9 @@ TASK_LIST_START TEST_ENTRY (fs_read_write_null_arguments) TEST_ENTRY (fs_file_pos_after_op_with_offset) TEST_ENTRY (fs_null_req) +#ifdef _WIN32 + TEST_ENTRY (fs_exclusive_sharing_mode) +#endif TEST_ENTRY (get_osfhandle_valid_handle) TEST_ENTRY (threadpool_queue_work_simple) TEST_ENTRY (threadpool_queue_work_einval) diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c index 50ed59a6d23a02..4025fba540e61e 100644 --- a/deps/uv/test/test-platform-output.c +++ b/deps/uv/test/test-platform-output.c @@ -29,6 +29,7 @@ TEST_IMPL(platform_output) { size_t rss; size_t size; double uptime; + uv_pid_t pid; uv_pid_t ppid; uv_rusage_t rusage; uv_cpu_info_t* cpus; @@ -145,6 +146,9 @@ TEST_IMPL(platform_output) { printf(" shell: %s\n", pwd.shell); printf(" home directory: %s\n", pwd.homedir); + pid = uv_os_getpid(); + ASSERT(pid > 0); + printf("uv_os_getpid: %d\n", (int) pid); ppid = uv_os_getppid(); ASSERT(ppid > 0); printf("uv_os_getppid: %d\n", (int) ppid); diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index d3958fe216f983..4b138265a5bc51 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -50,6 +50,7 @@ static size_t exepath_size = 1024; static char* args[5]; static int no_term_signal; static int timer_counter; +static uv_tcp_t tcp_server; #define OUTPUT_SIZE 1024 static char output[OUTPUT_SIZE]; @@ -622,6 +623,84 @@ TEST_IMPL(spawn_stdio_greater_than_3) { } +int spawn_tcp_server_helper(void) { + uv_tcp_t tcp; + uv_os_sock_t handle; + int r; + + r = uv_tcp_init(uv_default_loop(), &tcp); + ASSERT(r == 0); + +#ifdef _WIN32 + handle = _get_osfhandle(3); +#else + handle = 3; +#endif + r = uv_tcp_open(&tcp, handle); + ASSERT(r == 0); + + /* Make sure that we can listen on a socket that was + * passed down from the parent process + */ + r = uv_listen((uv_stream_t*)&tcp, SOMAXCONN, NULL); + ASSERT(r == 0); + + return 1; +} + + +TEST_IMPL(spawn_tcp_server) { + uv_stdio_container_t stdio[4]; + struct sockaddr_in addr; + int fd; + int r; +#ifdef _WIN32 + uv_os_fd_t handle; +#endif + + init_process_options("spawn_tcp_server_helper", exit_cb); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + fd = -1; + r = uv_tcp_init_ex(uv_default_loop(), &tcp_server, AF_INET); + ASSERT(r == 0); + r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); +#ifdef _WIN32 + r = uv_fileno((uv_handle_t*)&tcp_server, &handle); + fd = _open_osfhandle((intptr_t) handle, 0); +#else + r = uv_fileno((uv_handle_t*)&tcp_server, &fd); + #endif + ASSERT(r == 0); + ASSERT(fd > 0); + + options.stdio = stdio; + options.stdio[0].flags = UV_INHERIT_FD; + options.stdio[0].data.fd = 0; + options.stdio[1].flags = UV_INHERIT_FD; + options.stdio[1].data.fd = 1; + options.stdio[2].flags = UV_INHERIT_FD; + options.stdio[2].data.fd = 2; + options.stdio[3].flags = UV_INHERIT_FD; + options.stdio[3].data.fd = fd; + options.stdio_count = 4; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + TEST_IMPL(spawn_ignored_stdio) { int r; diff --git a/deps/uv/test/test-thread.c b/deps/uv/test/test-thread.c index b0e87e208155ea..955c9f2f1be149 100644 --- a/deps/uv/test/test-thread.c +++ b/deps/uv/test/test-thread.c @@ -44,7 +44,7 @@ struct fs_req { struct test_thread { uv_thread_t thread_id; - volatile int thread_called; + int thread_called; }; static void getaddrinfo_do(struct getaddrinfo_req* req); @@ -54,7 +54,7 @@ static void getaddrinfo_cb(uv_getaddrinfo_t* handle, static void fs_do(struct fs_req* req); static void fs_cb(uv_fs_t* handle); -static volatile int thread_called; +static int thread_called; static uv_key_t tls_key; @@ -105,36 +105,30 @@ static void fs_cb(uv_fs_t* handle) { static void do_work(void* arg) { - struct getaddrinfo_req getaddrinfo_reqs[16]; - struct fs_req fs_reqs[16]; - uv_loop_t* loop; + struct getaddrinfo_req getaddrinfo_reqs[4]; + struct fs_req fs_reqs[4]; + uv_loop_t loop; size_t i; - int r; struct test_thread* thread = arg; - loop = malloc(sizeof *loop); - ASSERT(loop != NULL); - ASSERT(0 == uv_loop_init(loop)); + ASSERT(0 == uv_loop_init(&loop)); for (i = 0; i < ARRAY_SIZE(getaddrinfo_reqs); i++) { struct getaddrinfo_req* req = getaddrinfo_reqs + i; - req->counter = 16; - req->loop = loop; + req->counter = 4; + req->loop = &loop; getaddrinfo_do(req); } for (i = 0; i < ARRAY_SIZE(fs_reqs); i++) { struct fs_req* req = fs_reqs + i; - req->counter = 16; - req->loop = loop; + req->counter = 4; + req->loop = &loop; fs_do(req); } - r = uv_run(loop, UV_RUN_DEFAULT); - ASSERT(r == 0); - - ASSERT(0 == uv_loop_close(loop)); - free(loop); + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + ASSERT(0 == uv_loop_close(&loop)); thread->thread_called = 1; } @@ -179,7 +173,7 @@ TEST_IMPL(threadpool_multiple_event_loops) { for (i = 0; i < ARRAY_SIZE(threads); i++) { r = uv_thread_join(&threads[i].thread_id); ASSERT(r == 0); - ASSERT(threads[i].thread_called); + ASSERT(threads[i].thread_called == 1); } return 0; diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 9d9bb4b735a310..96fb801a77b034 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -274,19 +274,43 @@ }, }], [ 'OS=="aix"', { - 'sources': [ 'src/unix/aix.c' ], + 'variables': { + 'os_name': '