diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap index da4214365c4155..5bbe5b26bb5c5e 100644 --- a/deps/uv/.mailmap +++ b/deps/uv/.mailmap @@ -16,6 +16,7 @@ Frank Denis Imran Iqbal Isaac Z. Schlueter Jason Williams +Jesse Gorzinski Justin Venus Keno Fischer Keno Fischer diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index fcb0aac3e83b10..c704527a970647 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -330,3 +330,5 @@ Mason X Jesse Gorzinski Ryuichi KAWAMATA Joyee Cheung +Michael Kilburn +Ruslan Bekenev diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 509a1d1571d498..3ae9d2023e9178 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,53 @@ +2018.04.03, Version 1.20.0 (Stable), 0012178ee2b04d9e4a2c66c27cf8891ad8325ceb + +Changes since version 1.19.2: + +* unix,spawn: respect user stdio flags for new pipe (Jameson Nash) + +* Revert "Revert "unix,tcp: avoid marking server sockets connected"" (Jameson + Nash) + +* req: revisions to uv_req_t handling (Jameson Nash) + +* win: remove unnecessary initialization (cjihrig) + +* win: update uv_os_homedir() to use uv_os_getenv() (cjihrig) + +* test: fix tcp_oob test flakiness (Santiago Gimeno) + +* posix: fix uv__pollfds_del() for invalidated fd's (Jesse Gorzinski) + +* doc: README: add note on installing gyp (Jamie Davis) + +* unix: refactor uv_os_homedir to use uv_os_getenv (Santiago Gimeno) + +* unix: fix several instances of lost errno (Michael Kilburn) + +* win,tty: update several TODO comments (Ruslan Bekenev) + +* unix: add UV_FS_COPYFILE_FICLONE support (cjihrig) + +* test: fix connect_unspecified (Santiago Gimeno) + +* unix,win: add UV_FS_COPYFILE_FICLONE_FORCE support (cjihrig) + +* win: use long directory name for handle->dirw (Nicholas Vavilov) + +* build: build with -D_FILE_OFFSET_BITS=64 again (Ben Noordhuis) + +* win, fs: fix uv_fs_unlink for +R -A files (Bartosz Sosnowski) + +* win, fs: use FILE_WRITE_ATTRIBUTES when opening files (Bartosz Sosnowski) + +* unix: use __PASE__ on IBM i platforms (Jesse Gorzinski) + +* test,freebsd: fix flaky poll tests (Santiago Gimeno) + +* test: increase connection timeout to 1 second (jBarz) + +* win,tcp: handle canceled connect with ECANCELED (Jameson Nash) + + 2018.02.22, Version 1.19.2 (Stable), c5afc37e2a8a70d8ab0da8dac10b77ba78c0488c Changes since version 1.19.1: diff --git a/deps/uv/README.md b/deps/uv/README.md index 733171be085ab5..1aaed1a88e7f10 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -169,6 +169,12 @@ $ make check $ make install ``` +To build with GYP, first run: + +```bash +$ git clone https://chromium.googlesource.com/external/gyp build/gyp +``` + ### Windows Prerequisites: diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh index 27eb529bcae13c..d8b50bc4fec5b8 100755 --- a/deps/uv/checksparse.sh +++ b/deps/uv/checksparse.sh @@ -184,7 +184,7 @@ AIX) src/unix/aix.c" ;; OS400) - SPARSE_FLAGS="$SPARSE_FLAGS -D_PASE=1" + SPARSE_FLAGS="$SPARSE_FLAGS -D__PASE__=1" SOURCES="$SOURCES src/unix/aix-common.c src/unix/ibmi.c diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 4074e77841d489..ee8571ea921034 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.19.2], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.20.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 87af828a28a7fa..29227be0d64c9c 100644 --- a/deps/uv/docs/src/fs.rst +++ b/deps/uv/docs/src/fs.rst @@ -249,6 +249,12 @@ API - `UV_FS_COPYFILE_EXCL`: If present, `uv_fs_copyfile()` will fail with `UV_EEXIST` if the destination path already exists. The default behavior is to overwrite the destination if it exists. + - `UV_FS_COPYFILE_FICLONE`: If present, `uv_fs_copyfile()` will attempt to + create a copy-on-write reflink. If the underlying platform does not + support copy-on-write, then a fallback copy mechanism is used. + - `UV_FS_COPYFILE_FICLONE_FORCE`: If present, `uv_fs_copyfile()` will + attempt to create a copy-on-write reflink. If the underlying platform does + not support copy-on-write, then an error is returned. .. warning:: If the destination path is created, but an error occurs while copying @@ -258,6 +264,9 @@ API .. versionadded:: 1.14.0 + .. versionchanged:: 1.20.0 `UV_FS_COPYFILE_FICLONE` and + `UV_FS_COPYFILE_FICLONE_FORCE` are supported. + .. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb) Limited equivalent to :man:`sendfile(2)`. diff --git a/deps/uv/include/uv-unix.h b/deps/uv/include/uv-unix.h index da32f86e8476fa..480a0691ea3e10 100644 --- a/deps/uv/include/uv-unix.h +++ b/deps/uv/include/uv-unix.h @@ -48,7 +48,7 @@ # include "uv-linux.h" #elif defined (__MVS__) # include "uv-os390.h" -#elif defined(_PASE) +#elif defined(__PASE__) # include "uv-posix.h" #elif defined(_AIX) # include "uv-aix.h" diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h index c2753d51c7c36e..392b4d646675cc 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 19 -#define UV_VERSION_PATCH 2 +#define UV_VERSION_MINOR 20 +#define UV_VERSION_PATCH 0 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 9794d9969b620e..41fad45108ba23 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -378,8 +378,7 @@ UV_EXTERN const char* uv_err_name(int err); /* read-only */ \ uv_req_type type; \ /* private */ \ - void* active_queue[2]; \ - void* reserved[4]; \ + void* reserved[6]; \ UV_REQ_PRIVATE_FIELDS \ /* Abstract base class of all requests. */ @@ -1191,6 +1190,18 @@ UV_EXTERN int uv_fs_write(uv_loop_t* loop, */ #define UV_FS_COPYFILE_EXCL 0x0001 +/* + * This flag can be used with uv_fs_copyfile() to attempt to create a reflink. + * If copy-on-write is not supported, a fallback copy mechanism is used. + */ +#define UV_FS_COPYFILE_FICLONE 0x0002 + +/* + * This flag can be used with uv_fs_copyfile() to attempt to create a reflink. + * If copy-on-write is not supported, an error is returned. + */ +#define UV_FS_COPYFILE_FICLONE_FORCE 0x0004 + UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop, uv_fs_t* req, const char* path, @@ -1531,7 +1542,10 @@ struct uv_loop_s { /* Loop reference counting. */ unsigned int active_handles; void* handle_queue[2]; - void* active_reqs[2]; + union { + void* unused[2]; + unsigned int count; + } active_reqs; /* Internal flag to signal loop stop. */ unsigned int stop_flag; UV_LOOP_PRIVATE_FIELDS diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 3741c1d06b2d79..18c8fcd808ba2a 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -536,7 +536,7 @@ int uv__close_nocheckstdio(int fd) { int uv__close(int fd) { assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */ #if defined(__MVS__) - epoll_file_close(fd); + SAVE_ERRNO(epoll_file_close(fd)); #endif return uv__close_nocheckstdio(fd); } @@ -1048,29 +1048,16 @@ int uv__dup2_cloexec(int oldfd, int newfd) { int uv_os_homedir(char* buffer, size_t* size) { uv_passwd_t pwd; - char* buf; size_t len; int r; - if (buffer == NULL || size == NULL || *size == 0) - return UV_EINVAL; - - /* Check if the HOME environment variable is set first */ - buf = getenv("HOME"); - - if (buf != NULL) { - len = strlen(buf); + /* Check if the HOME environment variable is set first. The task of + performing input validation on buffer and size is taken care of by + uv_os_getenv(). */ + r = uv_os_getenv("HOME", buffer, size); - if (len >= *size) { - *size = len + 1; - return UV_ENOBUFS; - } - - memcpy(buffer, buf, len + 1); - *size = len; - - return 0; - } + if (r != UV_ENOENT) + return r; /* HOME is not set, so call uv__getpwuid_r() */ r = uv__getpwuid_r(&pwd); diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index 92e2d255702fd7..de678733a9c179 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -62,6 +62,9 @@ #if defined(__APPLE__) # include +#elif defined(__linux__) && !defined(FICLONE) +# include +# define FICLONE _IOW(0x94, 9, int) #endif #define INIT(subtype) \ @@ -790,6 +793,19 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { if (req->flags & UV_FS_COPYFILE_EXCL) flags |= COPYFILE_EXCL; +#ifdef COPYFILE_CLONE + if (req->flags & UV_FS_COPYFILE_FICLONE) + flags |= COPYFILE_CLONE; +#endif + + if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { +#ifdef COPYFILE_CLONE_FORCE + flags |= COPYFILE_CLONE_FORCE; +#else + return UV_ENOSYS; +#endif + } + return copyfile(req->path, req->new_path, NULL, flags); #else uv_fs_t fs_req; @@ -842,6 +858,29 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { goto out; } +#ifdef FICLONE + if (req->flags & UV_FS_COPYFILE_FICLONE || + req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { + if (ioctl(dstfd, FICLONE, srcfd) == -1) { + /* If an error occurred that the sendfile fallback also won't handle, or + this is a force clone then exit. Otherwise, fall through to try using + sendfile(). */ + if ((errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) || + req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { + err = -errno; + goto out; + } + } else { + goto out; + } + } +#else + if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { + err = UV_ENOSYS; + goto out; + } +#endif + bytes_to_send = statsbuf.st_size; in_offset = 0; while (bytes_to_send != 0) { @@ -1504,8 +1543,11 @@ int uv_fs_copyfile(uv_loop_t* loop, uv_fs_cb cb) { INIT(COPYFILE); - if (flags & ~UV_FS_COPYFILE_EXCL) + if (flags & ~(UV_FS_COPYFILE_EXCL | + UV_FS_COPYFILE_FICLONE | + UV_FS_COPYFILE_FICLONE_FORCE)) { return UV_EINVAL; + } PATH2; req->flags = flags; diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 2bb3773c068d8e..b6df1ab9d3e52d 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -190,7 +190,7 @@ int uv__cloexec_ioctl(int fd, int set); int uv__cloexec_fcntl(int fd, int set); int uv__nonblock_ioctl(int fd, int set); int uv__nonblock_fcntl(int fd, int set); -int uv__close(int fd); +int uv__close(int fd); /* preserves errno */ int uv__close_nocheckstdio(int fd); int uv__socket(int domain, int type, int protocol); int uv__dup(int fd); diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c index 5b5b0e095bbc2f..99ead6cbc0cac2 100644 --- a/deps/uv/src/unix/loop.c +++ b/deps/uv/src/unix/loop.c @@ -38,13 +38,14 @@ int uv_loop_init(uv_loop_t* loop) { heap_init((struct heap*) &loop->timer_heap); QUEUE_INIT(&loop->wq); - QUEUE_INIT(&loop->active_reqs); QUEUE_INIT(&loop->idle_handles); QUEUE_INIT(&loop->async_handles); QUEUE_INIT(&loop->check_handles); QUEUE_INIT(&loop->prepare_handles); QUEUE_INIT(&loop->handle_queue); + loop->active_handles = 0; + loop->active_reqs.count = 0; loop->nfds = 0; loop->watchers = NULL; loop->nwatchers = 0; diff --git a/deps/uv/src/unix/posix-poll.c b/deps/uv/src/unix/posix-poll.c index f356e76c79daec..f3181f9b726278 100644 --- a/deps/uv/src/unix/posix-poll.c +++ b/deps/uv/src/unix/posix-poll.c @@ -107,7 +107,7 @@ static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) { static void uv__pollfds_del(uv_loop_t* loop, int fd) { size_t i; assert(!loop->poll_fds_iterating); - for (i = 0; i < loop->poll_fds_used; ++i) { + for (i = 0; i < loop->poll_fds_used;) { if (loop->poll_fds[i].fd == fd) { /* swap to last position and remove */ --loop->poll_fds_used; @@ -115,7 +115,17 @@ static void uv__pollfds_del(uv_loop_t* loop, int fd) { loop->poll_fds[loop->poll_fds_used].fd = -1; loop->poll_fds[loop->poll_fds_used].events = 0; loop->poll_fds[loop->poll_fds_used].revents = 0; - return; + /* This method is called with an fd of -1 to purge the invalidated fds, + * so we may possibly have multiples to remove. + */ + if (-1 != fd) + return; + } else { + /* We must only increment the loop counter when the fds do not match. + * Otherwise, when we are purging an invalidated fd, the value just + * swapped here from the previous end of the array will be skipped. + */ + ++i; } } } diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 74113e3a696cc2..3a3cfd6f092fa4 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -223,8 +223,7 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) { static int uv__process_open_stream(uv_stdio_container_t* container, - int pipefds[2], - int writable) { + int pipefds[2]) { int flags; int err; @@ -238,13 +237,11 @@ static int uv__process_open_stream(uv_stdio_container_t* container, pipefds[1] = -1; uv__nonblock(pipefds[0], 1); - if (container->data.stream->type == UV_NAMED_PIPE && - ((uv_pipe_t*)container->data.stream)->ipc) - flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE; - else if (writable) - flags = UV_STREAM_WRITABLE; - else - flags = UV_STREAM_READABLE; + flags = 0; + if (container->flags & UV_WRITABLE_PIPE) + flags |= UV_STREAM_READABLE; + if (container->flags & UV_READABLE_PIPE) + flags |= UV_STREAM_WRITABLE; return uv__stream_open(container->data.stream, pipefds[0], flags); } @@ -533,7 +530,7 @@ int uv_spawn(uv_loop_t* loop, uv__close_nocheckstdio(signal_pipe[0]); for (i = 0; i < options->stdio_count; i++) { - err = uv__process_open_stream(options->stdio + i, pipes[i], i == 0); + err = uv__process_open_stream(options->stdio + i, pipes[i]); if (err == 0) continue; diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 3e786abee015c4..5ec6bf4de29efc 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -1417,6 +1417,9 @@ int uv_write2(uv_write_t* req, if (uv__stream_fd(stream) < 0) return UV_EBADF; + if (!(stream->flags & UV_STREAM_WRITABLE)) + return -EPIPE; + if (send_handle) { if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) return UV_EINVAL; @@ -1568,6 +1571,9 @@ int uv_read_start(uv_stream_t* stream, if (stream->flags & UV_CLOSING) return UV_EINVAL; + if (!(stream->flags & UV_STREAM_READABLE)) + return -ENOTCONN; + /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just * expresses the desired state of the user. */ diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c index 96f89312def0eb..336d8e29205390 100644 --- a/deps/uv/src/unix/tcp.c +++ b/deps/uv/src/unix/tcp.c @@ -49,16 +49,14 @@ static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { /* 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) { + if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) { uv__close(sockfd); - return err; + return UV__ERR(errno); } - err = bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen); - if (err) { + if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) { uv__close(sockfd); - return err; + return UV__ERR(errno); } } @@ -158,9 +156,7 @@ int uv__tcp_bind(uv_tcp_t* tcp, if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) return UV_EINVAL; - err = maybe_new_socket(tcp, - addr->sa_family, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); + err = maybe_new_socket(tcp, addr->sa_family, 0); if (err) return err; @@ -335,14 +331,14 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { if (single_accept) tcp->flags |= UV_TCP_SINGLE_ACCEPT; - flags = UV_STREAM_READABLE; + flags = 0; #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 */ flags |= UV_HANDLE_BOUND; -#endif +#endif err = maybe_new_socket(tcp, AF_INET, flags); if (err) return err; diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c index bc7d1379d131f2..71345895697732 100644 --- a/deps/uv/src/uv-common.c +++ b/deps/uv/src/uv-common.c @@ -627,7 +627,7 @@ int uv_loop_close(uv_loop_t* loop) { void* saved_data; #endif - if (!QUEUE_EMPTY(&(loop)->active_reqs)) + if (uv__has_active_reqs(loop)) return UV_EBUSY; QUEUE_FOREACH(q, &loop->handle_queue) { diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index d4fa22aaef6add..c497d014fd77f7 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -133,18 +133,18 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value); void uv__fs_scandir_cleanup(uv_fs_t* req); #define uv__has_active_reqs(loop) \ - (QUEUE_EMPTY(&(loop)->active_reqs) == 0) + ((loop)->active_reqs.count > 0) #define uv__req_register(loop, req) \ do { \ - QUEUE_INSERT_TAIL(&(loop)->active_reqs, &(req)->active_queue); \ + (loop)->active_reqs.count++; \ } \ while (0) #define uv__req_unregister(loop, req) \ do { \ assert(uv__has_active_reqs(loop)); \ - QUEUE_REMOVE(&(req)->active_queue); \ + (loop)->active_reqs.count--; \ } \ while (0) diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c index 9ed4e824c6e96b..5fa9b6666dab5a 100644 --- a/deps/uv/src/win/core.c +++ b/deps/uv/src/win/core.c @@ -239,7 +239,7 @@ int uv_loop_init(uv_loop_t* loop) { QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->handle_queue); - QUEUE_INIT(&loop->active_reqs); + loop->active_reqs.count = 0; loop->active_handles = 0; loop->pending_reqs_tail = NULL; @@ -470,8 +470,8 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) { static int uv__loop_alive(const uv_loop_t* loop) { - return loop->active_handles > 0 || - !QUEUE_EMPTY(&loop->active_reqs) || + return uv__has_active_handles(loop) || + uv__has_active_reqs(loop) || loop->endgame_handles != NULL; } diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c index 95f843ad08edee..14c9af9ad754d6 100644 --- a/deps/uv/src/win/fs-event.c +++ b/deps/uv/src/win/fs-event.c @@ -69,6 +69,7 @@ static void uv_relative_path(const WCHAR* filename, size_t relpathlen; size_t filenamelen = wcslen(filename); size_t dirlen = wcslen(dir); + assert(!_wcsnicmp(filename, dir, dirlen)); if (dirlen > 0 && dir[dirlen - 1] == '\\') dirlen--; relpathlen = filenamelen - dirlen - 1; @@ -151,11 +152,11 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) { - int name_size, is_path_dir; + int name_size, is_path_dir, size; DWORD attr, last_error; WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; WCHAR short_path_buffer[MAX_PATH]; - WCHAR* short_path; + WCHAR* short_path, *long_path; if (uv__is_active(handle)) return UV_EINVAL; @@ -197,6 +198,30 @@ int uv_fs_event_start(uv_fs_event_t* handle, if (is_path_dir) { /* path is a directory, so that's the directory that we will watch. */ + + /* Convert to long path. */ + size = GetLongPathNameW(pathw, NULL, 0); + + if (size) { + long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); + if (!long_path) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + size = GetLongPathNameW(pathw, long_path, size); + if (size) { + long_path[size] = '\0'; + } else { + uv__free(long_path); + long_path = NULL; + } + } + + if (long_path) { + uv__free(pathw); + pathw = long_path; + } + dir_to_watch = pathw; } else { /* diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 6e0bdc7bb20e66..b07d47cf56be6a 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -245,7 +245,6 @@ INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, req->ptr = NULL; req->path = NULL; req->cb = cb; - req->fs.info.bufs = NULL; memset(&req->fs, 0, sizeof(req->fs)); } @@ -435,6 +434,8 @@ void fs__open(uv_fs_t* req) { access |= FILE_APPEND_DATA; } + access |= FILE_WRITE_ATTRIBUTES; + /* * Here is where we deviate significantly from what CRT's _open() * does. We indiscriminately use all the sharing modes, to match @@ -784,7 +785,9 @@ void fs__unlink(uv_fs_t* req) { /* Remove read-only attribute */ FILE_BASIC_INFORMATION basic = { 0 }; - basic.FileAttributes = info.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY); + basic.FileAttributes = info.dwFileAttributes + & ~(FILE_ATTRIBUTE_READONLY) + | FILE_ATTRIBUTE_ARCHIVE; status = pNtSetInformationFile(handle, &iosb, @@ -1391,6 +1394,12 @@ static void fs__copyfile(uv_fs_t* req) { int overwrite; flags = req->fs.info.file_flags; + + if (flags & UV_FS_COPYFILE_FICLONE_FORCE) { + SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED); + return; + } + overwrite = flags & UV_FS_COPYFILE_EXCL; if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) { @@ -2335,8 +2344,11 @@ int uv_fs_copyfile(uv_loop_t* loop, INIT(UV_FS_COPYFILE); - if (flags & ~UV_FS_COPYFILE_EXCL) + if (flags & ~(UV_FS_COPYFILE_EXCL | + UV_FS_COPYFILE_FICLONE | + UV_FS_COPYFILE_FICLONE_FORCE)) { return UV_EINVAL; + } err = fs__capture_path(req, path, new_path, cb != NULL); diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h index 217fcdb5d7678e..cce4e204d26552 100644 --- a/deps/uv/src/win/internal.h +++ b/deps/uv/src/win/internal.h @@ -221,10 +221,16 @@ void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle, uv_req_t* req); void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, uv_write_t* req); -/* TODO: remove me */ +/* + * uv_process_tty_accept_req() is a stub to keep DELEGATE_STREAM_REQ working + * TODO: find a way to remove it + */ void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, uv_req_t* raw_req); -/* TODO: remove me */ +/* + * uv_process_tty_connect_req() is a stub to keep DELEGATE_STREAM_REQ working + * TODO: find a way to remove it + */ void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, uv_connect_t* req); diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 1a7c4dc15e0b30..0ecfbf1f0e5145 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -847,6 +847,7 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle, return; } + /* Wait for completion via IOCP */ handle->reqs_pending++; } diff --git a/deps/uv/src/win/stream-inl.h b/deps/uv/src/win/stream-inl.h index dba03747043be7..40f5ddd51ea5a5 100644 --- a/deps/uv/src/win/stream-inl.h +++ b/deps/uv/src/win/stream-inl.h @@ -37,11 +37,6 @@ INLINE static void uv_stream_init(uv_loop_t* loop, handle->write_queue_size = 0; handle->activecnt = 0; handle->stream.conn.shutdown_req = NULL; -} - - -INLINE static void uv_connection_init(uv_stream_t* handle) { - handle->flags |= UV_HANDLE_CONNECTION; handle->stream.conn.write_reqs_pending = 0; UV_REQ_INIT(&handle->read_req, UV_READ); @@ -51,4 +46,9 @@ INLINE static void uv_connection_init(uv_stream_t* handle) { } +INLINE static void uv_connection_init(uv_stream_t* handle) { + handle->flags |= UV_HANDLE_CONNECTION; +} + + #endif /* UV_WIN_STREAM_INL_H_ */ diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index fd6efbaf891d64..39c1ff05658c5d 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -459,8 +459,6 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { INFINITE, WT_EXECUTEINWAITTHREAD)) { SET_REQ_ERROR(req, GetLastError()); uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - return; } } else { /* Make this req pending reporting an error. */ @@ -1173,11 +1171,14 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, err = 0; if (REQ_SUCCESS(req)) { - if (setsockopt(handle->socket, - SOL_SOCKET, - SO_UPDATE_CONNECT_CONTEXT, - NULL, - 0) == 0) { + if (handle->flags & UV__HANDLE_CLOSING) { + /* use UV_ECANCELED for consistency with Unix */ + err = ERROR_OPERATION_ABORTED; + } else if (setsockopt(handle->socket, + SOL_SOCKET, + SO_UPDATE_CONNECT_CONTEXT, + NULL, + 0) == 0) { uv_connection_init((uv_stream_t*)handle); handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; loop->active_tcp_streams++; diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 05a11e88305ff4..ecf7bc9b5b6710 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -2235,14 +2235,20 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { } -/* TODO: remove me */ +/* + * uv_process_tty_accept_req() is a stub to keep DELEGATE_STREAM_REQ working + * TODO: find a way to remove it + */ void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, uv_req_t* raw_req) { abort(); } -/* TODO: remove me */ +/* + * uv_process_tty_connect_req() is a stub to keep DELEGATE_STREAM_REQ working + * TODO: find a way to remove it + */ void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, uv_connect_t* req) { abort(); diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 3100bc23ad3e09..3c1d9bed1dbd4b 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -1148,53 +1148,17 @@ int uv_getrusage(uv_rusage_t *uv_rusage) { int uv_os_homedir(char* buffer, size_t* size) { uv_passwd_t pwd; - wchar_t path[MAX_PATH]; - DWORD bufsize; size_t len; int r; - if (buffer == NULL || size == NULL || *size == 0) - return UV_EINVAL; - - /* Check if the USERPROFILE environment variable is set first */ - len = GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH); - - if (len == 0) { - r = GetLastError(); - - /* Don't return an error if USERPROFILE was not found */ - if (r != ERROR_ENVVAR_NOT_FOUND) - return uv_translate_sys_error(r); - } else if (len > MAX_PATH) { - /* This should not be possible */ - return UV_EIO; - } else { - /* Check how much space we need */ - bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL); - - if (bufsize == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (bufsize > *size) { - *size = bufsize; - return UV_ENOBUFS; - } - - /* Convert to UTF-8 */ - bufsize = WideCharToMultiByte(CP_UTF8, - 0, - path, - -1, - buffer, - *size, - NULL, - NULL); - - if (bufsize == 0) - return uv_translate_sys_error(GetLastError()); + /* Check if the USERPROFILE environment variable is set first. The task of + performing input validation on buffer and size is taken care of by + uv_os_getenv(). */ + r = uv_os_getenv("USERPROFILE", buffer, size); - *size = bufsize - 1; - return 0; - } + /* Don't return an error if USERPROFILE was not found. */ + if (r != UV_ENOENT) + return r; /* USERPROFILE is not set, so call uv__getpwuid_r() */ r = uv__getpwuid_r(&pwd); diff --git a/deps/uv/test/test-connect-unspecified.c b/deps/uv/test/test-connect-unspecified.c index 04e1c8a5f7c682..5f32b67a6a4daa 100644 --- a/deps/uv/test/test-connect-unspecified.c +++ b/deps/uv/test/test-connect-unspecified.c @@ -48,12 +48,14 @@ TEST_IMPL(connect_unspecified) { (const struct sockaddr*) &addr4, connect_4) == 0); - ASSERT(uv_tcp_init(loop, &socket6) == 0); - ASSERT(uv_ip6_addr("::", TEST_PORT, &addr6) == 0); - ASSERT(uv_tcp_connect(&connect6, - &socket6, - (const struct sockaddr*) &addr6, - connect_6) == 0); + if (can_ipv6()) { + ASSERT(uv_tcp_init(loop, &socket6) == 0); + ASSERT(uv_ip6_addr("::", TEST_PORT, &addr6) == 0); + ASSERT(uv_tcp_connect(&connect6, + &socket6, + (const struct sockaddr*) &addr6, + connect_6) == 0); + } ASSERT(uv_run(loop, UV_RUN_DEFAULT) == 0); diff --git a/deps/uv/test/test-fs-copyfile.c b/deps/uv/test/test-fs-copyfile.c index 4b1fdc5e798280..6cd43b450290f7 100644 --- a/deps/uv/test/test-fs-copyfile.c +++ b/deps/uv/test/test-fs-copyfile.c @@ -168,6 +168,22 @@ TEST_IMPL(fs_copyfile) { r = uv_fs_copyfile(loop, &req, fixture, dst, -1, fail_cb); ASSERT(r == UV_EINVAL); uv_run(loop, UV_RUN_DEFAULT); + + /* Copies file using UV_FS_COPYFILE_FICLONE. */ + unlink(dst); + r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_FICLONE, NULL); + ASSERT(r == 0); + handle_result(&req); + + /* Copies file using UV_FS_COPYFILE_FICLONE_FORCE. */ + unlink(dst); + r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_FICLONE_FORCE, + NULL); + ASSERT(r == 0 || r == UV_ENOSYS || r == UV_ENOTSUP || r == UV_ENOTTY); + + if (r == 0) + handle_result(&req); + unlink(dst); /* Cleanup */ return 0; } diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index 39d73300dc2b61..5ddccffd0a98e9 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -129,7 +129,7 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename, ++fs_event_cb_called; ASSERT(handle == &fs_event); ASSERT(status == 0); - ASSERT(events == UV_RENAME); + ASSERT(events == UV_CHANGE); #if defined(__APPLE__) || defined(_WIN32) || defined(__linux__) ASSERT(strcmp(filename, "file1") == 0); #else @@ -477,6 +477,42 @@ TEST_IMPL(fs_event_watch_dir_recursive) { #endif } +#ifdef _WIN32 +TEST_IMPL(fs_event_watch_dir_short_path) { + uv_loop_t* loop; + int r; + + /* Setup */ + loop = uv_default_loop(); + remove("watch_dir/file1"); + remove("watch_dir/"); + create_dir("watch_dir"); + create_file("watch_dir/file1"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0); + ASSERT(r == 0); + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + r = uv_timer_start(&timer, timer_cb_file, 100, 0); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(fs_event_cb_called == 1); + ASSERT(timer_cb_called == 1); + ASSERT(close_cb_called == 1); + + /* Cleanup */ + remove("watch_dir/file1"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + TEST_IMPL(fs_event_watch_file) { #if defined(NO_FS_EVENTS) diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 3318b86649de50..0075a02be663ce 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -1367,6 +1367,28 @@ TEST_IMPL(fs_chmod) { check_permission("test_file", 0600); +#ifdef _WIN32 + /* Test clearing read-only flag from files with Archive flag cleared */ + /* Make the file read-only and clear archive flag */ + r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY); + ASSERT(r != 0); + check_permission("test_file", 0400); + + r = uv_fs_open(NULL, &req, "test_file", 0, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_fchmod(NULL, &req, file, 0600, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + check_permission("test_file", 0600); + /* Restore Archive flag for rest of the tests */ + r = SetFileAttributes("test_file", FILE_ATTRIBUTE_ARCHIVE); + ASSERT(r != 0); +#endif #ifndef _WIN32 /* async chmod */ { @@ -1474,6 +1496,64 @@ TEST_IMPL(fs_unlink_readonly) { return 0; } +#ifdef _WIN32 +TEST_IMPL(fs_unlink_archive_readonly) { + int r; + uv_fs_t req; + uv_file file; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, + &req, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(req.result == sizeof(test_buf)); + uv_fs_req_cleanup(&req); + + close(file); + + /* Make the file read-only and clear archive flag */ + r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY); + ASSERT(r != 0); + uv_fs_req_cleanup(&req); + + check_permission("test_file", 0400); + + /* Try to unlink the file */ + r = uv_fs_unlink(NULL, &req, "test_file", NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* + * Run the loop just to check we don't have make any extraneous uv_ref() + * calls. This should drop out immediately. + */ + uv_run(loop, UV_RUN_DEFAULT); + + /* Cleanup. */ + uv_fs_chmod(NULL, &req, "test_file", 0600, NULL); + uv_fs_req_cleanup(&req); + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif TEST_IMPL(fs_chown) { int r; diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index ff0a31d16bb940..b89930d709e6ec 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -95,6 +95,7 @@ TEST_DECLARE (tcp_bind_error_fault) TEST_DECLARE (tcp_bind_error_inval) TEST_DECLARE (tcp_bind_localhost_ok) TEST_DECLARE (tcp_bind_invalid_flags) +TEST_DECLARE (tcp_bind_writable_flags) TEST_DECLARE (tcp_listen_without_bind) TEST_DECLARE (tcp_connect_error_fault) TEST_DECLARE (tcp_connect_timeout) @@ -283,6 +284,9 @@ TEST_DECLARE (fs_access) TEST_DECLARE (fs_chmod) TEST_DECLARE (fs_copyfile) TEST_DECLARE (fs_unlink_readonly) +#ifdef _WIN32 +TEST_DECLARE (fs_unlink_archive_readonly) +#endif TEST_DECLARE (fs_chown) TEST_DECLARE (fs_link) TEST_DECLARE (fs_readlink) @@ -300,6 +304,9 @@ TEST_DECLARE (fs_stat_missing_path) TEST_DECLARE (fs_read_file_eof) TEST_DECLARE (fs_event_watch_dir) TEST_DECLARE (fs_event_watch_dir_recursive) +#ifdef _WIN32 +TEST_DECLARE (fs_event_watch_dir_short_path) +#endif TEST_DECLARE (fs_event_watch_file) TEST_DECLARE (fs_event_watch_file_exact_path) TEST_DECLARE (fs_event_watch_file_twice) @@ -535,6 +542,7 @@ TASK_LIST_START TEST_ENTRY (tcp_bind_error_inval) TEST_ENTRY (tcp_bind_localhost_ok) TEST_ENTRY (tcp_bind_invalid_flags) + TEST_ENTRY (tcp_bind_writable_flags) TEST_ENTRY (tcp_listen_without_bind) TEST_ENTRY (tcp_connect_error_fault) TEST_ENTRY (tcp_connect_timeout) @@ -810,6 +818,9 @@ TASK_LIST_START TEST_ENTRY (fs_chmod) TEST_ENTRY (fs_copyfile) TEST_ENTRY (fs_unlink_readonly) +#ifdef _WIN32 + TEST_ENTRY (fs_unlink_archive_readonly) +#endif TEST_ENTRY (fs_chown) TEST_ENTRY (fs_utime) TEST_ENTRY (fs_futime) @@ -826,6 +837,9 @@ TASK_LIST_START TEST_ENTRY (fs_file_open_append) TEST_ENTRY (fs_event_watch_dir) TEST_ENTRY (fs_event_watch_dir_recursive) +#ifdef _WIN32 + TEST_ENTRY (fs_event_watch_dir_short_path) +#endif TEST_ENTRY (fs_event_watch_file) TEST_ENTRY (fs_event_watch_file_exact_path) TEST_ENTRY (fs_event_watch_file_twice) diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c index e828addbb48225..0d1b1d7ec9540c 100644 --- a/deps/uv/test/test-poll.c +++ b/deps/uv/test/test-poll.c @@ -134,7 +134,10 @@ static void close_socket(uv_os_sock_t sock) { #else r = close(sock); #endif - ASSERT(r == 0); + /* On FreeBSD close() can fail with ECONNRESET if the socket was shutdown by + * the peer before all pending data was delivered. + */ + ASSERT(r == 0 || errno == ECONNRESET); } diff --git a/deps/uv/test/test-tcp-bind-error.c b/deps/uv/test/test-tcp-bind-error.c index 10ed68e10ec26e..1456d081ae6374 100644 --- a/deps/uv/test/test-tcp-bind-error.c +++ b/deps/uv/test/test-tcp-bind-error.c @@ -214,3 +214,45 @@ TEST_IMPL(tcp_listen_without_bind) { MAKE_VALGRIND_HAPPY(); return 0; } + + +TEST_IMPL(tcp_bind_writable_flags) { + struct sockaddr_in addr; + uv_tcp_t server; + uv_buf_t buf; + uv_write_t write_req; + uv_shutdown_t shutdown_req; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + r = uv_listen((uv_stream_t*)&server, 128, NULL); + ASSERT(r == 0); + + ASSERT(0 == uv_is_writable((uv_stream_t*) &server)); + ASSERT(0 == uv_is_readable((uv_stream_t*) &server)); + + buf = uv_buf_init("PING", 4); + r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL); + ASSERT(r == UV_EPIPE); + r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL); +#ifdef _WIN32 + ASSERT(r == UV_EPIPE); +#else + ASSERT(r == UV_ENOTCONN); +#endif + r = uv_read_start((uv_stream_t*) &server, NULL, NULL); + ASSERT(r == UV_ENOTCONN); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-tcp-oob.c b/deps/uv/test/test-tcp-oob.c index 4f1397a82ffed7..ca2361f9bb776d 100644 --- a/deps/uv/test/test-tcp-oob.c +++ b/deps/uv/test/test-tcp-oob.c @@ -61,7 +61,7 @@ static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { #endif uv_os_fd_t fd; - ASSERT(nread > 0); + ASSERT(nread >= 0); ASSERT(0 == uv_fileno((uv_handle_t*)handle, &fd)); ASSERT(0 == uv_idle_start(&idle, idle_cb)); diff --git a/deps/uv/test/test-tcp-write-queue-order.c b/deps/uv/test/test-tcp-write-queue-order.c index 5119be6d330932..1ff9c517cec1c6 100644 --- a/deps/uv/test/test-tcp-write-queue-order.c +++ b/deps/uv/test/test-tcp-write-queue-order.c @@ -90,7 +90,7 @@ static void connection_cb(uv_stream_t* tcp, int status) { ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); - ASSERT(0 == uv_timer_start(&timer, timer_cb, 1, 0)); + ASSERT(0 == uv_timer_start(&timer, timer_cb, 1000, 0)); connection_cb_called++; } diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index a5046b87ea5b3c..e41f9ff5dce421 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -2,12 +2,12 @@ 'variables': { 'conditions': [ ['OS=="win"', { + 'shared_unix_defines': [ ], + }, { 'shared_unix_defines': [ '_LARGEFILE_SOURCE', '_FILE_OFFSET_BITS=64', ], - }, { - 'shared_unix_defines': [ ], }], ['OS in "mac ios"', { 'shared_mac_defines': [ '_DARWIN_USE_64_BIT_INODE=1' ], @@ -300,9 +300,6 @@ 'src/unix/no-fsevents.c', 'src/unix/no-proctitle.c', ], - 'defines': [ - '_PASE=1' - ], }, { 'sources': [ 'src/unix/aix.c'