diff options
Diffstat (limited to 'third-party/libuv/src')
75 files changed, 0 insertions, 36026 deletions
diff --git a/third-party/libuv/src/fs-poll.c b/third-party/libuv/src/fs-poll.c deleted file mode 100644 index 7fdaaeb17a..0000000000 --- a/third-party/libuv/src/fs-poll.c +++ /dev/null @@ -1,223 +0,0 @@ -/* 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 - * 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 "uv-common.h" - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -struct poll_ctx { - uv_fs_poll_t* parent_handle; /* NULL if parent has been stopped or closed */ - int busy_polling; - unsigned int interval; - uint64_t start_time; - uv_loop_t* loop; - uv_fs_poll_cb poll_cb; - uv_timer_t timer_handle; - uv_fs_t fs_req; /* TODO(bnoordhuis) mark fs_req internal */ - uv_stat_t statbuf; - char path[1]; /* variable length */ -}; - -static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b); -static void poll_cb(uv_fs_t* req); -static void timer_cb(uv_timer_t* timer, int status); -static void timer_close_cb(uv_handle_t* handle); - -static uv_stat_t zero_statbuf; - - -int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_POLL); - return 0; -} - - -int uv_fs_poll_start(uv_fs_poll_t* handle, - uv_fs_poll_cb cb, - const char* path, - unsigned int interval) { - struct poll_ctx* ctx; - uv_loop_t* loop; - size_t len; - - if (uv__is_active(handle)) - return 0; - - loop = handle->loop; - len = strlen(path); - ctx = calloc(1, sizeof(*ctx) + len); - - if (ctx == NULL) - return UV_ENOMEM; - - ctx->loop = loop; - ctx->poll_cb = cb; - ctx->interval = interval ? interval : 1; - ctx->start_time = uv_now(loop); - ctx->parent_handle = handle; - memcpy(ctx->path, path, len + 1); - - if (uv_timer_init(loop, &ctx->timer_handle)) - abort(); - - ctx->timer_handle.flags |= UV__HANDLE_INTERNAL; - uv__handle_unref(&ctx->timer_handle); - - if (uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb)) - abort(); - - handle->poll_ctx = ctx; - uv__handle_start(handle); - - return 0; -} - - -int uv_fs_poll_stop(uv_fs_poll_t* handle) { - struct poll_ctx* ctx; - - if (!uv__is_active(handle)) - return 0; - - ctx = handle->poll_ctx; - assert(ctx != NULL); - assert(ctx->parent_handle != NULL); - ctx->parent_handle = NULL; - handle->poll_ctx = NULL; - - /* Close the timer if it's active. If it's inactive, there's a stat request - * in progress and poll_cb will take care of the cleanup. - */ - if (uv__is_active(&ctx->timer_handle)) - uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb); - - uv__handle_stop(handle); - - return 0; -} - - -void uv__fs_poll_close(uv_fs_poll_t* handle) { - uv_fs_poll_stop(handle); -} - - -static void timer_cb(uv_timer_t* timer, int status) { - struct poll_ctx* ctx; - - ctx = container_of(timer, struct poll_ctx, timer_handle); - assert(ctx->parent_handle != NULL); - assert(ctx->parent_handle->poll_ctx == ctx); - ctx->start_time = uv_now(ctx->loop); - - if (uv_fs_stat(ctx->loop, &ctx->fs_req, ctx->path, poll_cb)) - abort(); -} - - -static void poll_cb(uv_fs_t* req) { - uv_stat_t* statbuf; - struct poll_ctx* ctx; - uint64_t interval; - - ctx = container_of(req, struct poll_ctx, fs_req); - - if (ctx->parent_handle == NULL) { /* handle has been stopped or closed */ - uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb); - uv_fs_req_cleanup(req); - return; - } - - if (req->result != 0) { - if (ctx->busy_polling != req->result) { - ctx->poll_cb(ctx->parent_handle, - req->result, - &ctx->statbuf, - &zero_statbuf); - ctx->busy_polling = req->result; - } - goto out; - } - - statbuf = &req->statbuf; - - if (ctx->busy_polling != 0) - if (ctx->busy_polling < 0 || !statbuf_eq(&ctx->statbuf, statbuf)) - ctx->poll_cb(ctx->parent_handle, 0, &ctx->statbuf, statbuf); - - ctx->statbuf = *statbuf; - ctx->busy_polling = 1; - -out: - uv_fs_req_cleanup(req); - - if (ctx->parent_handle == NULL) { /* handle has been stopped by callback */ - uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb); - return; - } - - /* Reschedule timer, subtract the delay from doing the stat(). */ - interval = ctx->interval; - interval -= (uv_now(ctx->loop) - ctx->start_time) % interval; - - if (uv_timer_start(&ctx->timer_handle, timer_cb, interval, 0)) - abort(); -} - - -static void timer_close_cb(uv_handle_t* handle) { - free(container_of(handle, struct poll_ctx, timer_handle)); -} - - -static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b) { - return a->st_ctim.tv_nsec == b->st_ctim.tv_nsec - && a->st_mtim.tv_nsec == b->st_mtim.tv_nsec - && a->st_birthtim.tv_nsec == b->st_birthtim.tv_nsec - && a->st_ctim.tv_sec == b->st_ctim.tv_sec - && a->st_mtim.tv_sec == b->st_mtim.tv_sec - && a->st_birthtim.tv_sec == b->st_birthtim.tv_sec - && a->st_size == b->st_size - && a->st_mode == b->st_mode - && a->st_uid == b->st_uid - && a->st_gid == b->st_gid - && a->st_ino == b->st_ino - && a->st_dev == b->st_dev - && a->st_flags == b->st_flags - && a->st_gen == b->st_gen; -} - - -#if defined(_WIN32) - -#include "win/internal.h" -#include "win/handle-inl.h" - -void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle) { - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); -} - -#endif /* _WIN32 */ diff --git a/third-party/libuv/src/inet.c b/third-party/libuv/src/inet.c deleted file mode 100644 index a30c0d1512..0000000000 --- a/third-party/libuv/src/inet.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdio.h> -#include <string.h> - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include <stdint.h> -#endif - -#include "uv.h" -#include "uv-common.h" - - -static int inet_ntop4(const unsigned char *src, char *dst, size_t size); -static int inet_ntop6(const unsigned char *src, char *dst, size_t size); -static int inet_pton4(const char *src, unsigned char *dst); -static int inet_pton6(const char *src, unsigned char *dst); - - -int uv_inet_ntop(int af, const void* src, char* dst, size_t size) { - switch (af) { - case AF_INET: - return (inet_ntop4(src, dst, size)); - case AF_INET6: - return (inet_ntop6(src, dst, size)); - default: - return UV_EAFNOSUPPORT; - } - /* NOTREACHED */ -} - - -static int inet_ntop4(const unsigned char *src, char *dst, size_t size) { - static const char fmt[] = "%u.%u.%u.%u"; - char tmp[sizeof "255.255.255.255"]; - int l; - -#ifndef _WIN32 - l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); -#else - l = _snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); -#endif - if (l <= 0 || (size_t) l >= size) { - return UV_ENOSPC; - } - strncpy(dst, tmp, size); - dst[size - 1] = '\0'; - return 0; -} - - -static int inet_ntop6(const unsigned char *src, char *dst, size_t size) { - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; - struct { int base, len; } best, cur; - unsigned int words[sizeof(struct in6_addr) / sizeof(uint16_t)]; - int i; - - /* - * Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < (int) sizeof(struct in6_addr); i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - best.base = -1; - best.len = 0; - cur.base = -1; - cur.len = 0; - for (i = 0; i < (int) ARRAY_SIZE(words); i++) { - if (words[i] == 0) { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - } - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - } - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* - * Format the result. - */ - tp = tmp; - for (i = 0; i < (int) ARRAY_SIZE(words); i++) { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) { - if (i == best.base) - *tp++ = ':'; - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) - *tp++ = ':'; - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && (best.len == 6 || - (best.len == 7 && words[7] != 0x0001) || - (best.len == 5 && words[5] == 0xffff))) { - int err = inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)); - if (err) - return err; - tp += strlen(tp); - break; - } - tp += sprintf(tp, "%x", words[i]); - } - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words)) - *tp++ = ':'; - *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) { - return UV_ENOSPC; - } - strcpy(dst, tmp); - return 0; -} - - -int uv_inet_pton(int af, const char* src, void* dst) { - switch (af) { - case AF_INET: - return (inet_pton4(src, dst)); - case AF_INET6: - return (inet_pton6(src, dst)); - default: - return UV_EAFNOSUPPORT; - } - /* NOTREACHED */ -} - - -static int inet_pton4(const char *src, unsigned char *dst) { - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - unsigned char tmp[sizeof(struct in_addr)], *tp; - - saw_digit = 0; - octets = 0; - *(tp = tmp) = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr(digits, ch)) != NULL) { - unsigned int nw = *tp * 10 + (pch - digits); - - if (saw_digit && *tp == 0) - return UV_EINVAL; - if (nw > 255) - return UV_EINVAL; - *tp = nw; - if (!saw_digit) { - if (++octets > 4) - return UV_EINVAL; - saw_digit = 1; - } - } else if (ch == '.' && saw_digit) { - if (octets == 4) - return UV_EINVAL; - *++tp = 0; - saw_digit = 0; - } else - return UV_EINVAL; - } - if (octets < 4) - return UV_EINVAL; - memcpy(dst, tmp, sizeof(struct in_addr)); - return 0; -} - - -static int inet_pton6(const char *src, unsigned char *dst) { - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[sizeof(struct in6_addr)], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, seen_xdigits; - unsigned int val; - - memset((tp = tmp), '\0', sizeof tmp); - endp = tp + sizeof tmp; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') - return UV_EINVAL; - curtok = src; - seen_xdigits = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if (pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if (++seen_xdigits > 4) - return UV_EINVAL; - continue; - } - if (ch == ':') { - curtok = src; - if (!seen_xdigits) { - if (colonp) - return UV_EINVAL; - colonp = tp; - continue; - } else if (*src == '\0') { - return UV_EINVAL; - } - if (tp + sizeof(uint16_t) > endp) - return UV_EINVAL; - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - seen_xdigits = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + sizeof(struct in_addr)) <= endp)) { - int err = inet_pton4(curtok, tp); - if (err == 0) { - tp += sizeof(struct in_addr); - seen_xdigits = 0; - break; /*%< '\\0' was seen by inet_pton4(). */ - } - } - return UV_EINVAL; - } - if (seen_xdigits) { - if (tp + sizeof(uint16_t) > endp) - return UV_EINVAL; - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - } - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const int n = tp - colonp; - int i; - - if (tp == endp) - return UV_EINVAL; - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if (tp != endp) - return UV_EINVAL; - memcpy(dst, tmp, sizeof tmp); - return 0; -} diff --git a/third-party/libuv/src/queue.h b/third-party/libuv/src/queue.h deleted file mode 100644 index fe02b454ea..0000000000 --- a/third-party/libuv/src/queue.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef QUEUE_H_ -#define QUEUE_H_ - -typedef void *QUEUE[2]; - -/* Private macros. */ -#define QUEUE_NEXT(q) (*(QUEUE **) &((*(q))[0])) -#define QUEUE_PREV(q) (*(QUEUE **) &((*(q))[1])) -#define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q))) -#define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q))) - -/* Public macros. */ -#define QUEUE_DATA(ptr, type, field) \ - ((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field))) - -#define QUEUE_FOREACH(q, h) \ - for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q)) - -#define QUEUE_EMPTY(q) \ - ((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q)) - -#define QUEUE_HEAD(q) \ - (QUEUE_NEXT(q)) - -#define QUEUE_INIT(q) \ - do { \ - QUEUE_NEXT(q) = (q); \ - QUEUE_PREV(q) = (q); \ - } \ - while (0) - -#define QUEUE_ADD(h, n) \ - do { \ - QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n); \ - QUEUE_NEXT_PREV(n) = QUEUE_PREV(h); \ - QUEUE_PREV(h) = QUEUE_PREV(n); \ - QUEUE_PREV_NEXT(h) = (h); \ - } \ - while (0) - -#define QUEUE_SPLIT(h, q, n) \ - do { \ - QUEUE_PREV(n) = QUEUE_PREV(h); \ - QUEUE_PREV_NEXT(n) = (n); \ - QUEUE_NEXT(n) = (q); \ - QUEUE_PREV(h) = QUEUE_PREV(q); \ - QUEUE_PREV_NEXT(h) = (h); \ - QUEUE_PREV(q) = (n); \ - } \ - while (0) - -#define QUEUE_INSERT_HEAD(h, q) \ - do { \ - QUEUE_NEXT(q) = QUEUE_NEXT(h); \ - QUEUE_PREV(q) = (h); \ - QUEUE_NEXT_PREV(q) = (q); \ - QUEUE_NEXT(h) = (q); \ - } \ - while (0) - -#define QUEUE_INSERT_TAIL(h, q) \ - do { \ - QUEUE_NEXT(q) = (h); \ - QUEUE_PREV(q) = QUEUE_PREV(h); \ - QUEUE_PREV_NEXT(q) = (q); \ - QUEUE_PREV(h) = (q); \ - } \ - while (0) - -#define QUEUE_REMOVE(q) \ - do { \ - QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q); \ - QUEUE_NEXT_PREV(q) = QUEUE_PREV(q); \ - } \ - while (0) - -#endif /* QUEUE_H_ */ diff --git a/third-party/libuv/src/unix/aix.c b/third-party/libuv/src/unix/aix.c deleted file mode 100644 index 2521681305..0000000000 --- a/third-party/libuv/src/unix/aix.c +++ /dev/null @@ -1,399 +0,0 @@ -/* 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 - * 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 <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <net/if.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <sys/time.h> -#include <unistd.h> -#include <fcntl.h> -#include <utmp.h> - -#include <sys/protosw.h> -#include <libperfstat.h> -#include <sys/proc.h> -#include <sys/procfs.h> - -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. - */ -int uv_exepath(char* buffer, size_t* size) { - ssize_t res; - char pp[64], cwdl[PATH_MAX]; - struct psinfo ps; - int fd; - - if (buffer == NULL) - return (-1); - - if (size == NULL) - return (-1); - - (void) snprintf(pp, sizeof(pp), "/proc/%lu/cwd", (unsigned long) getpid()); - - res = readlink(pp, cwdl, sizeof(cwdl) - 1); - if (res < 0) - return res; - - cwdl[res] = '\0'; - - (void) snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid()); - fd = open(pp, O_RDONLY); - if (fd < 0) - return fd; - - res = read(fd, &ps, sizeof(ps)); - uv__close(fd); - if (res < 0) - return res; - - (void) snprintf(buffer, *size, "%s%s", cwdl, ps.pr_fname); - *size = strlen(buffer); - return 0; -} - - -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); - if (result == -1) { - return 0; - } - return mem_total.real_free * 4096; -} - - -uint64_t uv_get_total_memory(void) { - perfstat_memory_total_t mem_total; - int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1); - if (result == -1) { - return 0; - } - return mem_total.real_total * 4096; -} - - -void uv_loadavg(double avg[3]) { - perfstat_cpu_total_t ps_total; - int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1); - if (result == -1) { - avg[0] = 0.; avg[1] = 0.; avg[2] = 0.; - return; - } - avg[0] = ps_total.loadavg[0] / (double)(1 << SBITS); - avg[1] = ps_total.loadavg[1] / (double)(1 << SBITS); - avg[2] = ps_total.loadavg[2] / (double)(1 << SBITS); -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - return -ENOSYS; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* filename, - unsigned int flags) { - return -ENOSYS; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - return -ENOSYS; -} - - -void uv__fs_event_close(uv_fs_event_t* handle) { - UNREACHABLE(); -} - - -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (size > 0) { - buffer[0] = '\0'; - } - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - char pp[64]; - psinfo_t psinfo; - int err; - int fd; - - (void) snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid()); - - fd = open(pp, O_RDONLY); - if (fd == -1) - return -errno; - - /* FIXME(bnoordhuis) Handle EINTR. */ - err = -EINVAL; - if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) { - *rss = (size_t)psinfo.pr_rssize * 1024; - err = 0; - } - uv__close(fd); - - return err; -} - - -int uv_uptime(double* uptime) { - struct utmp *utmp_buf; - size_t entries = 0; - time_t boot_time; - - utmpname(UTMP_FILE); - - setutent(); - - while ((utmp_buf = getutent()) != NULL) { - if (utmp_buf->ut_user[0] && utmp_buf->ut_type == USER_PROCESS) - ++entries; - if (utmp_buf->ut_type == BOOT_TIME) - boot_time = utmp_buf->ut_time; - } - - endutent(); - - if (boot_time == 0) - return -ENOSYS; - - *uptime = time(NULL) - boot_time; - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - uv_cpu_info_t* cpu_info; - perfstat_cpu_total_t ps_total; - perfstat_cpu_t* ps_cpus; - perfstat_id_t cpu_id; - int result, ncpus, idx = 0; - - result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1); - if (result == -1) { - return -ENOSYS; - } - - ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); - if (result == -1) { - return -ENOSYS; - } - - ps_cpus = (perfstat_cpu_t*) malloc(ncpus * sizeof(perfstat_cpu_t)); - if (!ps_cpus) { - return -ENOMEM; - } - - strcpy(cpu_id.name, FIRST_CPU); - result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus); - if (result == -1) { - free(ps_cpus); - return -ENOSYS; - } - - *cpu_infos = (uv_cpu_info_t*) malloc(ncpus * sizeof(uv_cpu_info_t)); - if (!*cpu_infos) { - free(ps_cpus); - return -ENOMEM; - } - - *count = ncpus; - - cpu_info = *cpu_infos; - while (idx < ncpus) { - cpu_info->speed = (int)(ps_total.processorHZ / 1000000); - cpu_info->model = strdup(ps_total.description); - cpu_info->cpu_times.user = ps_cpus[idx].user; - cpu_info->cpu_times.sys = ps_cpus[idx].sys; - cpu_info->cpu_times.idle = ps_cpus[idx].idle; - cpu_info->cpu_times.irq = ps_cpus[idx].wait; - cpu_info->cpu_times.nice = 0; - cpu_info++; - idx++; - } - - free(ps_cpus); - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; ++i) { - free(cpu_infos[i].model); - } - - free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { - uv_interface_address_t* address; - int sockfd, size = 1; - struct ifconf ifc; - struct ifreq *ifr, *p, flg; - - *count = 0; - - if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) { - return -ENOSYS; - } - - if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) { - uv__close(sockfd); - return -ENOSYS; - } - - ifc.ifc_req = (struct ifreq*)malloc(size); - ifc.ifc_len = size; - if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { - uv__close(sockfd); - return -ENOSYS; - } - -#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 -ENOSYS; - } - - if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) - continue; - - (*count)++; - } - - /* Alloc the return interface structs */ - *addresses = (uv_interface_address_t*) - 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; - - 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 = strdup(p->ifr_name); - - if (p->ifr_addr.sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr); - } - - /* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */ - - 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) { - free(addresses[i].name); - } - - free(addresses); -} diff --git a/third-party/libuv/src/unix/async.c b/third-party/libuv/src/unix/async.c deleted file mode 100644 index 3c23e1d7fd..0000000000 --- a/third-party/libuv/src/unix/async.c +++ /dev/null @@ -1,290 +0,0 @@ -/* 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 - * 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. - */ - -/* This file contains both the uv__async internal infrastructure and the - * user-facing uv_async_t functions. - */ - -#include "uv.h" -#include "internal.h" - -#include <errno.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents); -static int uv__async_make_pending(int* pending); -static int uv__async_eventfd(void); - - -int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { - int err; - - err = uv__async_start(loop, &loop->async_watcher, uv__async_event); - if (err) - return err; - - uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC); - handle->async_cb = async_cb; - handle->pending = 0; - - QUEUE_INSERT_TAIL(&loop->async_handles, &handle->queue); - uv__handle_start(handle); - - return 0; -} - - -int uv_async_send(uv_async_t* handle) { - if (uv__async_make_pending(&handle->pending) == 0) - uv__async_send(&handle->loop->async_watcher); - - return 0; -} - - -void uv__async_close(uv_async_t* handle) { - QUEUE_REMOVE(&handle->queue); - uv__handle_stop(handle); -} - - -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents) { - QUEUE* q; - uv_async_t* h; - - QUEUE_FOREACH(q, &loop->async_handles) { - h = QUEUE_DATA(q, uv_async_t, queue); - - if (h->pending == 0) - continue; - h->pending = 0; - - if (h->async_cb == NULL) - continue; - h->async_cb(h, 0); - } -} - - -static int uv__async_make_pending(int* pending) { - /* Do a cheap read first. */ - if (ACCESS_ONCE(int, *pending) != 0) - return 1; - - /* Micro-optimization: use atomic memory operations to detect if we've been - * preempted by another thread and don't have to make an expensive syscall. - * This speeds up the heavily contended case by about 1-2% and has little - * if any impact on the non-contended case. - * - * Use XCHG instead of the CMPXCHG that __sync_val_compare_and_swap() emits - * on x86, it's about 4x faster. It probably makes zero difference in the - * grand scheme of things but I'm OCD enough not to let this one pass. - */ -#if defined(__i386__) || defined(__x86_64__) - { - unsigned int val = 1; - __asm__ __volatile__ ("xchgl %0, %1" - : "+r" (val) - : "m" (*pending)); - return val != 0; - } -#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0) - return __sync_val_compare_and_swap(pending, 0, 1) != 0; -#else - ACCESS_ONCE(int, *pending) = 1; - return 0; -#endif -} - - -static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - struct uv__async* wa; - char buf[1024]; - unsigned n; - ssize_t r; - - n = 0; - for (;;) { - r = read(w->fd, buf, sizeof(buf)); - - if (r > 0) - n += r; - - if (r == sizeof(buf)) - continue; - - if (r != -1) - break; - - if (errno == EAGAIN || errno == EWOULDBLOCK) - break; - - if (errno == EINTR) - continue; - - abort(); - } - - wa = container_of(w, struct uv__async, io_watcher); - -#if defined(__linux__) - if (wa->wfd == -1) { - uint64_t val; - assert(n == sizeof(val)); - memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */ - wa->cb(loop, wa, val); - return; - } -#endif - - wa->cb(loop, wa, n); -} - - -void uv__async_send(struct uv__async* wa) { - const void* buf; - ssize_t len; - int fd; - int r; - - buf = ""; - len = 1; - fd = wa->wfd; - -#if defined(__linux__) - if (fd == -1) { - static const uint64_t val = 1; - buf = &val; - len = sizeof(val); - fd = wa->io_watcher.fd; /* eventfd */ - } -#endif - - do - r = write(fd, buf, len); - while (r == -1 && errno == EINTR); - - if (r == len) - return; - - if (r == -1) - if (errno == EAGAIN || errno == EWOULDBLOCK) - return; - - abort(); -} - - -void uv__async_init(struct uv__async* wa) { - wa->io_watcher.fd = -1; - wa->wfd = -1; -} - - -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) { - int pipefd[2]; - int err; - - if (wa->io_watcher.fd != -1) - return 0; - - err = uv__async_eventfd(); - if (err >= 0) { - pipefd[0] = err; - pipefd[1] = -1; - } - else if (err == -ENOSYS) - err = uv__make_pipe(pipefd, UV__F_NONBLOCK); - - if (err < 0) - return err; - - uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]); - uv__io_start(loop, &wa->io_watcher, UV__POLLIN); - wa->wfd = pipefd[1]; - wa->cb = cb; - - return 0; -} - - -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) { - if (wa->io_watcher.fd == -1) - return; - - uv__io_stop(loop, &wa->io_watcher, UV__POLLIN); - uv__close(wa->io_watcher.fd); - wa->io_watcher.fd = -1; - - if (wa->wfd != -1) { - uv__close(wa->wfd); - wa->wfd = -1; - } -} - - -static int uv__async_eventfd() { -#if defined(__linux__) - static int no_eventfd2; - static int no_eventfd; - int fd; - - if (no_eventfd2) - goto skip_eventfd2; - - fd = uv__eventfd2(0, UV__EFD_CLOEXEC | UV__EFD_NONBLOCK); - if (fd != -1) - return fd; - - if (errno != ENOSYS) - return -errno; - - no_eventfd2 = 1; - -skip_eventfd2: - - if (no_eventfd) - goto skip_eventfd; - - fd = uv__eventfd(0); - if (fd != -1) { - uv__cloexec(fd, 1); - uv__nonblock(fd, 1); - return fd; - } - - if (errno != ENOSYS) - return -errno; - - no_eventfd = 1; - -skip_eventfd: - -#endif - - return -ENOSYS; -} diff --git a/third-party/libuv/src/unix/atomic-ops.h b/third-party/libuv/src/unix/atomic-ops.h deleted file mode 100644 index 7e4e64beda..0000000000 --- a/third-party/libuv/src/unix/atomic-ops.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef UV_ATOMIC_OPS_H_ -#define UV_ATOMIC_OPS_H_ - -#include "internal.h" /* UV_UNUSED */ - -UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)); -UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)); -UV_UNUSED(static void cpu_relax(void)); - -/* Prefer hand-rolled assembly over the gcc builtins because the latter also - * issue full memory barriers. - */ -UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) { -#if defined(__i386__) || defined(__x86_64__) - int out; - __asm__ __volatile__ ("lock; cmpxchg %2, %1;" - : "=a" (out), "+m" (*(volatile int*) ptr) - : "r" (newval), "0" (oldval) - : "memory"); - return out; -#else - return __sync_val_compare_and_swap(ptr, oldval, newval); -#endif -} - -UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) { -#if defined(__i386__) || defined(__x86_64__) - long out; - __asm__ __volatile__ ("lock; cmpxchg %2, %1;" - : "=a" (out), "+m" (*(volatile long*) ptr) - : "r" (newval), "0" (oldval) - : "memory"); - return out; -#else - return __sync_val_compare_and_swap(ptr, oldval, newval); -#endif -} - -UV_UNUSED(static void cpu_relax(void)) { -#if defined(__i386__) || defined(__x86_64__) - __asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */ -#endif -} - -#endif /* UV_ATOMIC_OPS_H_ */ diff --git a/third-party/libuv/src/unix/core.c b/third-party/libuv/src/unix/core.c deleted file mode 100644 index df2a5f8042..0000000000 --- a/third-party/libuv/src/unix/core.c +++ /dev/null @@ -1,787 +0,0 @@ -/* 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 - * 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 <stddef.h> /* NULL */ -#include <stdio.h> /* printf */ -#include <stdlib.h> -#include <string.h> /* strerror */ -#include <errno.h> -#include <assert.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <limits.h> /* INT_MAX, PATH_MAX */ -#include <sys/uio.h> /* writev */ - -#ifdef __linux__ -# include <sys/ioctl.h> -#endif - -#ifdef __sun -# include <sys/types.h> -# include <sys/wait.h> -#endif - -#ifdef __APPLE__ -# include <mach-o/dyld.h> /* _NSGetExecutablePath */ -# include <sys/filio.h> -# include <sys/ioctl.h> -#endif - -#ifdef __FreeBSD__ -# include <sys/sysctl.h> -# include <sys/filio.h> -# include <sys/ioctl.h> -# include <sys/wait.h> -#endif - -static void uv__run_pending(uv_loop_t* loop); - -/* Verify that uv_buf_t is ABI-compatible with struct iovec. */ -STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec)); -STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->base) == - sizeof(((struct iovec*) 0)->iov_base)); -STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->len) == - sizeof(((struct iovec*) 0)->iov_len)); -STATIC_ASSERT(offsetof(uv_buf_t, base) == offsetof(struct iovec, iov_base)); -STATIC_ASSERT(offsetof(uv_buf_t, len) == offsetof(struct iovec, iov_len)); - - -uint64_t uv_hrtime(void) { - return uv__hrtime(UV_CLOCK_PRECISE); -} - - -void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - - handle->flags |= UV_CLOSING; - handle->close_cb = close_cb; - - switch (handle->type) { - case UV_NAMED_PIPE: - uv__pipe_close((uv_pipe_t*)handle); - break; - - case UV_TTY: - uv__stream_close((uv_stream_t*)handle); - break; - - case UV_TCP: - uv__tcp_close((uv_tcp_t*)handle); - break; - - case UV_UDP: - uv__udp_close((uv_udp_t*)handle); - break; - - case UV_PREPARE: - uv__prepare_close((uv_prepare_t*)handle); - break; - - case UV_CHECK: - uv__check_close((uv_check_t*)handle); - break; - - case UV_IDLE: - uv__idle_close((uv_idle_t*)handle); - break; - - case UV_ASYNC: - uv__async_close((uv_async_t*)handle); - break; - - case UV_TIMER: - uv__timer_close((uv_timer_t*)handle); - break; - - case UV_PROCESS: - uv__process_close((uv_process_t*)handle); - break; - - case UV_FS_EVENT: - uv__fs_event_close((uv_fs_event_t*)handle); - break; - - case UV_POLL: - uv__poll_close((uv_poll_t*)handle); - break; - - case UV_FS_POLL: - uv__fs_poll_close((uv_fs_poll_t*)handle); - break; - - case UV_SIGNAL: - uv__signal_close((uv_signal_t*) handle); - /* Signal handles may not be closed immediately. The signal code will */ - /* itself close uv__make_close_pending whenever appropriate. */ - return; - - default: - assert(0); - } - - uv__make_close_pending(handle); -} - - -void uv__make_close_pending(uv_handle_t* handle) { - assert(handle->flags & UV_CLOSING); - assert(!(handle->flags & UV_CLOSED)); - handle->next_closing = handle->loop->closing_handles; - handle->loop->closing_handles = handle; -} - - -static void uv__finish_close(uv_handle_t* handle) { - /* Note: while the handle is in the UV_CLOSING state now, it's still possible - * for it to be active in the sense that uv__is_active() returns true. - * A good example is when the user calls uv_shutdown(), immediately followed - * by uv_close(). The handle is considered active at this point because the - * completion of the shutdown req is still pending. - */ - assert(handle->flags & UV_CLOSING); - assert(!(handle->flags & UV_CLOSED)); - handle->flags |= UV_CLOSED; - - switch (handle->type) { - case UV_PREPARE: - case UV_CHECK: - case UV_IDLE: - case UV_ASYNC: - case UV_TIMER: - case UV_PROCESS: - case UV_FS_EVENT: - case UV_FS_POLL: - case UV_POLL: - case UV_SIGNAL: - break; - - case UV_NAMED_PIPE: - case UV_TCP: - case UV_TTY: - uv__stream_destroy((uv_stream_t*)handle); - break; - - case UV_UDP: - uv__udp_finish_close((uv_udp_t*)handle); - break; - - default: - assert(0); - break; - } - - uv__handle_unref(handle); - QUEUE_REMOVE(&handle->handle_queue); - - if (handle->close_cb) { - handle->close_cb(handle); - } -} - - -static void uv__run_closing_handles(uv_loop_t* loop) { - uv_handle_t* p; - uv_handle_t* q; - - p = loop->closing_handles; - loop->closing_handles = NULL; - - while (p) { - q = p->next_closing; - uv__finish_close(p); - p = q; - } -} - - -int uv_is_closing(const uv_handle_t* handle) { - return uv__is_closing(handle); -} - - -int uv_backend_fd(const uv_loop_t* loop) { - return loop->backend_fd; -} - - -int uv_backend_timeout(const uv_loop_t* loop) { - if (loop->stop_flag != 0) - return 0; - - if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop)) - return 0; - - if (!QUEUE_EMPTY(&loop->idle_handles)) - return 0; - - if (loop->closing_handles) - return 0; - - return uv__next_timeout(loop); -} - - -static int uv__loop_alive(const uv_loop_t* loop) { - return uv__has_active_handles(loop) || - uv__has_active_reqs(loop) || - loop->closing_handles != NULL; -} - - -int uv_loop_alive(const uv_loop_t* loop) { - return uv__loop_alive(loop); -} - - -int uv_run(uv_loop_t* loop, uv_run_mode mode) { - int timeout; - int r; - - r = uv__loop_alive(loop); - if (!r) - uv__update_time(loop); - - while (r != 0 && loop->stop_flag == 0) { - UV_TICK_START(loop, mode); - - uv__update_time(loop); - uv__run_timers(loop); - uv__run_idle(loop); - uv__run_prepare(loop); - uv__run_pending(loop); - - timeout = 0; - if ((mode & UV_RUN_NOWAIT) == 0) - timeout = uv_backend_timeout(loop); - - uv__io_poll(loop, timeout); - uv__run_check(loop); - uv__run_closing_handles(loop); - - if (mode == UV_RUN_ONCE) { - /* UV_RUN_ONCE implies forward progess: at least one callback must have - * been invoked when it returns. uv__io_poll() can return without doing - * I/O (meaning: no callbacks) when its timeout expires - which means we - * have pending timers that satisfy the forward progress constraint. - * - * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from - * the check. - */ - uv__update_time(loop); - uv__run_timers(loop); - } - - r = uv__loop_alive(loop); - UV_TICK_STOP(loop, mode); - - if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT)) - break; - } - - /* The if statement lets gcc compile it to a conditional store. Avoids - * dirtying a cache line. - */ - if (loop->stop_flag != 0) - loop->stop_flag = 0; - - return r; -} - - -void uv_update_time(uv_loop_t* loop) { - uv__update_time(loop); -} - - -int uv_is_active(const uv_handle_t* handle) { - return uv__is_active(handle); -} - - -/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */ -int uv__socket(int domain, int type, int protocol) { - int sockfd; - int err; - -#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) - sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol); - if (sockfd != -1) - return sockfd; - - if (errno != EINVAL) - return -errno; -#endif - - sockfd = socket(domain, type, protocol); - if (sockfd == -1) - return -errno; - - err = uv__nonblock(sockfd, 1); - if (err == 0) - err = uv__cloexec(sockfd, 1); - - if (err) { - uv__close(sockfd); - return err; - } - -#if defined(SO_NOSIGPIPE) - { - int on = 1; - setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)); - } -#endif - - return sockfd; -} - - -int uv__accept(int sockfd) { - int peerfd; - int err; - - assert(sockfd >= 0); - - while (1) { -#if defined(__linux__) - static int no_accept4; - - if (no_accept4) - goto skip; - - peerfd = uv__accept4(sockfd, - NULL, - NULL, - UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC); - if (peerfd != -1) - return peerfd; - - if (errno == EINTR) - continue; - - if (errno != ENOSYS) - return -errno; - - no_accept4 = 1; -skip: -#endif - - peerfd = accept(sockfd, NULL, NULL); - if (peerfd == -1) { - if (errno == EINTR) - continue; - return -errno; - } - - err = uv__cloexec(peerfd, 1); - if (err == 0) - err = uv__nonblock(peerfd, 1); - - if (err) { - uv__close(peerfd); - return err; - } - - return peerfd; - } -} - - -int uv__close(int fd) { - int saved_errno; - int rc; - - assert(fd > -1); /* Catch uninitialized io_watcher.fd bugs. */ - assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */ - - saved_errno = errno; - rc = close(fd); - if (rc == -1) { - rc = -errno; - if (rc == -EINTR) - rc = -EINPROGRESS; /* For platform/libc consistency. */ - errno = saved_errno; - } - - return rc; -} - - -#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) - -int uv__nonblock(int fd, int set) { - int r; - - do - r = ioctl(fd, FIONBIO, &set); - while (r == -1 && errno == EINTR); - - if (r) - return -errno; - - return 0; -} - - -int uv__cloexec(int fd, int set) { - int r; - - do - r = ioctl(fd, set ? FIOCLEX : FIONCLEX); - while (r == -1 && errno == EINTR); - - if (r) - return -errno; - - return 0; -} - -#else /* !(defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) */ - -int uv__nonblock(int fd, int set) { - int flags; - int r; - - do - r = fcntl(fd, F_GETFL); - while (r == -1 && errno == EINTR); - - if (r == -1) - return -errno; - - /* Bail out now if already set/clear. */ - if (!!(r & O_NONBLOCK) == !!set) - return 0; - - if (set) - flags = r | O_NONBLOCK; - else - flags = r & ~O_NONBLOCK; - - do - r = fcntl(fd, F_SETFL, flags); - while (r == -1 && errno == EINTR); - - if (r) - return -errno; - - return 0; -} - - -int uv__cloexec(int fd, int set) { - int flags; - int r; - - do - r = fcntl(fd, F_GETFD); - while (r == -1 && errno == EINTR); - - if (r == -1) - return -errno; - - /* Bail out now if already set/clear. */ - if (!!(r & FD_CLOEXEC) == !!set) - return 0; - - if (set) - flags = r | FD_CLOEXEC; - else - flags = r & ~FD_CLOEXEC; - - do - r = fcntl(fd, F_SETFD, flags); - while (r == -1 && errno == EINTR); - - if (r) - return -errno; - - return 0; -} - -#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) */ - - -/* This function is not execve-safe, there is a race window - * between the call to dup() and fcntl(FD_CLOEXEC). - */ -int uv__dup(int fd) { - int err; - - fd = dup(fd); - - if (fd == -1) - return -errno; - - err = uv__cloexec(fd, 1); - if (err) { - uv__close(fd); - return err; - } - - return fd; -} - - -ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) { - struct cmsghdr* cmsg; - ssize_t rc; - int* pfd; - int* end; -#if defined(__linux__) - static int no_msg_cmsg_cloexec; - if (no_msg_cmsg_cloexec == 0) { - rc = recvmsg(fd, msg, flags | 0x40000000); /* MSG_CMSG_CLOEXEC */ - if (rc != -1) - return rc; - if (errno != EINVAL) - return -errno; - rc = recvmsg(fd, msg, flags); - if (rc == -1) - return -errno; - no_msg_cmsg_cloexec = 1; - } else { - rc = recvmsg(fd, msg, flags); - } -#else - rc = recvmsg(fd, msg, flags); -#endif - if (rc == -1) - return -errno; - if (msg->msg_controllen == 0) - return rc; - for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) - if (cmsg->cmsg_type == SCM_RIGHTS) - for (pfd = (int*) CMSG_DATA(cmsg), - end = (int*) ((char*) cmsg + cmsg->cmsg_len); - pfd < end; - pfd += 1) - uv__cloexec(*pfd, 1); - return rc; -} - - -int uv_cwd(char* buffer, size_t size) { - if (buffer == NULL) - return -EINVAL; - - if (size == 0) - return -EINVAL; - - if (getcwd(buffer, size) == NULL) - return -errno; - - return 0; -} - - -int uv_chdir(const char* dir) { - if (chdir(dir)) - return -errno; - - return 0; -} - - -void uv_disable_stdio_inheritance(void) { - int fd; - - /* Set the CLOEXEC flag on all open descriptors. Unconditionally try the - * first 16 file descriptors. After that, bail out after the first error. - */ - for (fd = 0; ; fd++) - if (uv__cloexec(fd, 1) && fd > 15) - break; -} - - -static void uv__run_pending(uv_loop_t* loop) { - QUEUE* q; - uv__io_t* w; - - while (!QUEUE_EMPTY(&loop->pending_queue)) { - q = QUEUE_HEAD(&loop->pending_queue); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - w = QUEUE_DATA(q, uv__io_t, pending_queue); - w->cb(loop, w, UV__POLLOUT); - } -} - - -static unsigned int next_power_of_two(unsigned int val) { - val -= 1; - val |= val >> 1; - val |= val >> 2; - val |= val >> 4; - val |= val >> 8; - val |= val >> 16; - val += 1; - return val; -} - -static void maybe_resize(uv_loop_t* loop, unsigned int len) { - uv__io_t** watchers; - void* fake_watcher_list; - void* fake_watcher_count; - unsigned int nwatchers; - unsigned int i; - - if (len <= loop->nwatchers) - return; - - /* Preserve fake watcher list and count at the end of the watchers */ - if (loop->watchers != NULL) { - fake_watcher_list = loop->watchers[loop->nwatchers]; - fake_watcher_count = loop->watchers[loop->nwatchers + 1]; - } else { - fake_watcher_list = NULL; - fake_watcher_count = NULL; - } - - nwatchers = next_power_of_two(len + 2) - 2; - watchers = realloc(loop->watchers, - (nwatchers + 2) * sizeof(loop->watchers[0])); - - if (watchers == NULL) - abort(); - for (i = loop->nwatchers; i < nwatchers; i++) - watchers[i] = NULL; - watchers[nwatchers] = fake_watcher_list; - watchers[nwatchers + 1] = fake_watcher_count; - - loop->watchers = watchers; - loop->nwatchers = nwatchers; -} - - -void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) { - assert(cb != NULL); - assert(fd >= -1); - QUEUE_INIT(&w->pending_queue); - QUEUE_INIT(&w->watcher_queue); - w->cb = cb; - w->fd = fd; - w->events = 0; - w->pevents = 0; - -#if defined(UV_HAVE_KQUEUE) - w->rcount = 0; - w->wcount = 0; -#endif /* defined(UV_HAVE_KQUEUE) */ -} - - -void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT))); - assert(0 != events); - assert(w->fd >= 0); - assert(w->fd < INT_MAX); - - w->pevents |= events; - maybe_resize(loop, w->fd + 1); - -#if !defined(__sun) - /* The event ports backend needs to rearm all file descriptors on each and - * every tick of the event loop but the other backends allow us to - * short-circuit here if the event mask is unchanged. - */ - if (w->events == w->pevents) { - if (w->events == 0 && !QUEUE_EMPTY(&w->watcher_queue)) { - QUEUE_REMOVE(&w->watcher_queue); - QUEUE_INIT(&w->watcher_queue); - } - return; - } -#endif - - if (QUEUE_EMPTY(&w->watcher_queue)) - QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); - - if (loop->watchers[w->fd] == NULL) { - loop->watchers[w->fd] = w; - loop->nfds++; - } -} - - -void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT))); - assert(0 != events); - - if (w->fd == -1) - return; - - assert(w->fd >= 0); - - /* Happens when uv__io_stop() is called on a handle that was never started. */ - if ((unsigned) w->fd >= loop->nwatchers) - return; - - w->pevents &= ~events; - - if (w->pevents == 0) { - QUEUE_REMOVE(&w->watcher_queue); - QUEUE_INIT(&w->watcher_queue); - - if (loop->watchers[w->fd] != NULL) { - assert(loop->watchers[w->fd] == w); - assert(loop->nfds > 0); - loop->watchers[w->fd] = NULL; - loop->nfds--; - w->events = 0; - } - } - else if (QUEUE_EMPTY(&w->watcher_queue)) - QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); -} - - -void uv__io_close(uv_loop_t* loop, uv__io_t* w) { - uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT); - QUEUE_REMOVE(&w->pending_queue); - - /* Remove stale events for this file descriptor */ - uv__platform_invalidate_fd(loop, w->fd); -} - - -void uv__io_feed(uv_loop_t* loop, uv__io_t* w) { - if (QUEUE_EMPTY(&w->pending_queue)) - QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue); -} - - -int uv__io_active(const uv__io_t* w, unsigned int events) { - assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT))); - assert(0 != events); - return 0 != (w->pevents & events); -} diff --git a/third-party/libuv/src/unix/darwin-proctitle.c b/third-party/libuv/src/unix/darwin-proctitle.c deleted file mode 100644 index 8cd358bcf0..0000000000 --- a/third-party/libuv/src/unix/darwin-proctitle.c +++ /dev/null @@ -1,203 +0,0 @@ -/* 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 - * 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 <dlfcn.h> -#include <errno.h> -#include <stdlib.h> - -#include <TargetConditionals.h> - -#if !TARGET_OS_IPHONE -# include <CoreFoundation/CoreFoundation.h> -# include <ApplicationServices/ApplicationServices.h> -#endif - - -static int uv__pthread_setname_np(const char* name) { - int (*dynamic_pthread_setname_np)(const char* name); - char namebuf[64]; /* MAXTHREADNAMESIZE */ - int err; - - /* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */ - dynamic_pthread_setname_np = dlsym(RTLD_DEFAULT, "pthread_setname_np"); - if (dynamic_pthread_setname_np == NULL) - return -ENOSYS; - - strncpy(namebuf, name, sizeof(namebuf) - 1); - namebuf[sizeof(namebuf) - 1] = '\0'; - - err = dynamic_pthread_setname_np(namebuf); - if (err) - return -err; - - return 0; -} - - -int uv__set_process_title(const char* title) { -#if TARGET_OS_IPHONE - return uv__pthread_setname_np(title); -#else - CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, - const char*, - CFStringEncoding); - CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef); - void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef); - void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef); - CFTypeRef (*pLSGetCurrentApplicationASN)(void); - OSStatus (*pLSSetApplicationInformationItem)(int, - CFTypeRef, - CFStringRef, - CFStringRef, - CFDictionaryRef*); - void* application_services_handle; - void* core_foundation_handle; - CFBundleRef launch_services_bundle; - CFStringRef* display_name_key; - CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef); - CFBundleRef (*pCFBundleGetMainBundle)(void); - CFBundleRef hi_services_bundle; - OSStatus (*pSetApplicationIsDaemon)(int); - CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef); - void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t, - void*); - CFTypeRef asn; - int err; - - err = -ENOENT; - application_services_handle = dlopen("/System/Library/Frameworks/" - "ApplicationServices.framework/" - "Versions/A/ApplicationServices", - RTLD_LAZY | RTLD_LOCAL); - core_foundation_handle = dlopen("/System/Library/Frameworks/" - "CoreFoundation.framework/" - "Versions/A/CoreFoundation", - RTLD_LAZY | RTLD_LOCAL); - - if (application_services_handle == NULL || core_foundation_handle == NULL) - goto out; - - pCFStringCreateWithCString = - dlsym(core_foundation_handle, "CFStringCreateWithCString"); - pCFBundleGetBundleWithIdentifier = - dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier"); - pCFBundleGetDataPointerForName = - dlsym(core_foundation_handle, "CFBundleGetDataPointerForName"); - pCFBundleGetFunctionPointerForName = - dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName"); - - if (pCFStringCreateWithCString == NULL || - pCFBundleGetBundleWithIdentifier == NULL || - pCFBundleGetDataPointerForName == NULL || - pCFBundleGetFunctionPointerForName == NULL) { - goto out; - } - -#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) - - launch_services_bundle = - pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices")); - - if (launch_services_bundle == NULL) - goto out; - - pLSGetCurrentApplicationASN = - pCFBundleGetFunctionPointerForName(launch_services_bundle, - S("_LSGetCurrentApplicationASN")); - - if (pLSGetCurrentApplicationASN == NULL) - goto out; - - pLSSetApplicationInformationItem = - pCFBundleGetFunctionPointerForName(launch_services_bundle, - S("_LSSetApplicationInformationItem")); - - if (pLSSetApplicationInformationItem == NULL) - goto out; - - display_name_key = pCFBundleGetDataPointerForName(launch_services_bundle, - S("_kLSDisplayNameKey")); - - if (display_name_key == NULL || *display_name_key == NULL) - goto out; - - pCFBundleGetInfoDictionary = dlsym(core_foundation_handle, - "CFBundleGetInfoDictionary"); - pCFBundleGetMainBundle = dlsym(core_foundation_handle, - "CFBundleGetMainBundle"); - if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL) - goto out; - - /* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */ - hi_services_bundle = - pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices")); - err = -ENOENT; - if (hi_services_bundle == NULL) - goto out; - - pSetApplicationIsDaemon = pCFBundleGetFunctionPointerForName( - hi_services_bundle, - S("SetApplicationIsDaemon")); - pLSApplicationCheckIn = pCFBundleGetFunctionPointerForName( - launch_services_bundle, - S("_LSApplicationCheckIn")); - pLSSetApplicationLaunchServicesServerConnectionStatus = - pCFBundleGetFunctionPointerForName( - launch_services_bundle, - S("_LSSetApplicationLaunchServicesServerConnectionStatus")); - if (pSetApplicationIsDaemon == NULL || - pLSApplicationCheckIn == NULL || - pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) { - goto out; - } - - if (pSetApplicationIsDaemon(1) != noErr) - goto out; - - pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL); - - /* Check into process manager?! */ - pLSApplicationCheckIn(-2, - pCFBundleGetInfoDictionary(pCFBundleGetMainBundle())); - - asn = pLSGetCurrentApplicationASN(); - - err = -EINVAL; - if (pLSSetApplicationInformationItem(-2, /* Magic value. */ - asn, - *display_name_key, - S(title), - NULL) != noErr) { - goto out; - } - - uv__pthread_setname_np(title); /* Don't care if it fails. */ - err = 0; - -out: - if (core_foundation_handle != NULL) - dlclose(core_foundation_handle); - - if (application_services_handle != NULL) - dlclose(application_services_handle); - - return err; -#endif /* !TARGET_OS_IPHONE */ -} diff --git a/third-party/libuv/src/unix/darwin.c b/third-party/libuv/src/unix/darwin.c deleted file mode 100644 index bc282e7912..0000000000 --- a/third-party/libuv/src/unix/darwin.c +++ /dev/null @@ -1,324 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <stdint.h> -#include <errno.h> - -#include <ifaddrs.h> -#include <net/if.h> -#include <net/if_dl.h> - -#include <mach/mach.h> -#include <mach/mach_time.h> -#include <mach-o/dyld.h> /* _NSGetExecutablePath */ -#include <sys/resource.h> -#include <sys/sysctl.h> -#include <unistd.h> /* sysconf */ - - -int uv__platform_loop_init(uv_loop_t* loop, int default_loop) { - loop->cf_state = NULL; - - if (uv__kqueue_init(loop)) - return -errno; - - return 0; -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { - uv__fsevents_loop_delete(loop); -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - mach_timebase_info_data_t info; - - if (mach_timebase_info(&info) != KERN_SUCCESS) - abort(); - - return mach_absolute_time() * info.numer / info.denom; -} - - -int uv_exepath(char* buffer, size_t* size) { - uint32_t usize; - int result; - char* path; - char* fullpath; - - if (buffer == NULL || size == NULL) - return -EINVAL; - - usize = *size; - result = _NSGetExecutablePath(buffer, &usize); - if (result) return result; - - path = malloc(2 * PATH_MAX); - fullpath = realpath(buffer, path); - if (fullpath == NULL) { - SAVE_ERRNO(free(path)); - return -errno; - } - - strncpy(buffer, fullpath, *size); - free(fullpath); - *size = strlen(buffer); - return 0; -} - - -uint64_t uv_get_free_memory(void) { - vm_statistics_data_t info; - mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t); - - if (host_statistics(mach_host_self(), HOST_VM_INFO, - (host_info_t)&info, &count) != KERN_SUCCESS) { - return -EINVAL; /* FIXME(bnoordhuis) Translate error. */ - } - - return (uint64_t) info.free_count * sysconf(_SC_PAGESIZE); -} - - -uint64_t uv_get_total_memory(void) { - uint64_t info; - int which[] = {CTL_HW, HW_MEMSIZE}; - size_t size = sizeof(info); - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info; -} - - -void uv_loadavg(double avg[3]) { - struct loadavg info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_LOADAVG}; - - if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return; - - avg[0] = (double) info.ldavg[0] / info.fscale; - avg[1] = (double) info.ldavg[1] / info.fscale; - avg[2] = (double) info.ldavg[2] / info.fscale; -} - - -int uv_resident_set_memory(size_t* rss) { - mach_msg_type_number_t count; - task_basic_info_data_t info; - kern_return_t err; - - count = TASK_BASIC_INFO_COUNT; - err = task_info(mach_task_self(), - TASK_BASIC_INFO, - (task_info_t) &info, - &count); - (void) &err; - /* task_info(TASK_BASIC_INFO) cannot really fail. Anything other than - * KERN_SUCCESS implies a libuv bug. - */ - assert(err == KERN_SUCCESS); - *rss = info.resident_size; - - return 0; -} - - -int uv_uptime(double* uptime) { - time_t now; - struct timeval info; - size_t size = sizeof(info); - static int which[] = {CTL_KERN, KERN_BOOTTIME}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - now = time(NULL); - *uptime = now - info.tv_sec; - - return 0; -} - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), - multiplier = ((uint64_t)1000L / ticks); - char model[512]; - uint64_t cpuspeed; - size_t size; - unsigned int i; - natural_t numcpus; - mach_msg_type_number_t msg_type; - processor_cpu_load_info_data_t *info; - uv_cpu_info_t* cpu_info; - - size = sizeof(model); - if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) && - sysctlbyname("hw.model", &model, &size, NULL, 0)) { - return -errno; - } - - size = sizeof(cpuspeed); - if (sysctlbyname("hw.cpufrequency", &cpuspeed, &size, NULL, 0)) - return -errno; - - if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus, - (processor_info_array_t*)&info, - &msg_type) != KERN_SUCCESS) { - return -EINVAL; /* FIXME(bnoordhuis) Translate error. */ - } - - *cpu_infos = malloc(numcpus * sizeof(**cpu_infos)); - if (!(*cpu_infos)) - return -ENOMEM; /* FIXME(bnoordhuis) Deallocate info? */ - - *count = numcpus; - - for (i = 0; i < numcpus; i++) { - cpu_info = &(*cpu_infos)[i]; - - cpu_info->cpu_times.user = (uint64_t)(info[i].cpu_ticks[0]) * multiplier; - cpu_info->cpu_times.nice = (uint64_t)(info[i].cpu_ticks[3]) * multiplier; - cpu_info->cpu_times.sys = (uint64_t)(info[i].cpu_ticks[1]) * multiplier; - cpu_info->cpu_times.idle = (uint64_t)(info[i].cpu_ticks[2]) * multiplier; - cpu_info->cpu_times.irq = 0; - - cpu_info->model = strdup(model); - cpu_info->speed = cpuspeed/1000000; - } - vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); - - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - free(cpu_infos[i].model); - } - - free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = malloc(*count * sizeof(**addresses)); - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Mac OS X getifaddrs returns information related to Mac Addresses for - * various devices, such as firewire, etc. These are not relevant here. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - free(addresses[i].name); - } - - free(addresses); -} diff --git a/third-party/libuv/src/unix/dl.c b/third-party/libuv/src/unix/dl.c deleted file mode 100644 index cbffe4aa26..0000000000 --- a/third-party/libuv/src/unix/dl.c +++ /dev/null @@ -1,83 +0,0 @@ -/* 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 - * 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 <dlfcn.h> -#include <errno.h> -#include <string.h> -#include <locale.h> - -static int uv__dlerror(uv_lib_t* lib); - - -int uv_dlopen(const char* filename, uv_lib_t* lib) { - dlerror(); /* Reset error status. */ - lib->errmsg = NULL; - lib->handle = dlopen(filename, RTLD_LAZY); - return lib->handle ? 0 : uv__dlerror(lib); -} - - -void uv_dlclose(uv_lib_t* lib) { - if (lib->errmsg) { - free(lib->errmsg); - lib->errmsg = NULL; - } - - if (lib->handle) { - /* Ignore errors. No good way to signal them without leaking memory. */ - dlclose(lib->handle); - lib->handle = NULL; - } -} - - -int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { - dlerror(); /* Reset error status. */ - *ptr = dlsym(lib->handle, name); - return uv__dlerror(lib); -} - - -const char* uv_dlerror(uv_lib_t* lib) { - return lib->errmsg ? lib->errmsg : "no error"; -} - - -static int uv__dlerror(uv_lib_t* lib) { - const char* errmsg; - - if (lib->errmsg) - free(lib->errmsg); - - errmsg = dlerror(); - - if (errmsg) { - lib->errmsg = strdup(errmsg); - return -1; - } - else { - lib->errmsg = NULL; - return 0; - } -} diff --git a/third-party/libuv/src/unix/freebsd.c b/third-party/libuv/src/unix/freebsd.c deleted file mode 100644 index dcae244bb1..0000000000 --- a/third-party/libuv/src/unix/freebsd.c +++ /dev/null @@ -1,425 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <string.h> -#include <errno.h> - -#include <ifaddrs.h> -#include <net/if.h> -#include <net/if_dl.h> - -#include <kvm.h> -#include <paths.h> -#include <sys/user.h> -#include <sys/types.h> -#include <sys/resource.h> -#include <sys/sysctl.h> -#include <vm/vm_param.h> /* VM_LOADAVG */ -#include <time.h> -#include <stdlib.h> -#include <unistd.h> /* sysconf */ -#include <fcntl.h> - -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - -#ifndef CPUSTATES -# define CPUSTATES 5U -#endif -#ifndef CP_USER -# define CP_USER 0 -# define CP_NICE 1 -# define CP_SYS 2 -# define CP_IDLE 3 -# define CP_INTR 4 -#endif - -static char *process_title; - - -int uv__platform_loop_init(uv_loop_t* loop, int default_loop) { - return uv__kqueue_init(loop); -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - -int uv_exepath(char* buffer, size_t* size) { - int mib[4]; - size_t cb; - - if (buffer == NULL || size == NULL) - return -EINVAL; - -#ifdef __DragonFly__ - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_ARGS; - mib[3] = getpid(); -#else - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = -1; -#endif - - cb = *size; - if (sysctl(mib, 4, buffer, &cb, NULL, 0)) - return -errno; - *size = strlen(buffer); - - return 0; -} - - -uint64_t uv_get_free_memory(void) { - int freecount; - size_t size = sizeof(freecount); - - if (sysctlbyname("vm.stats.vm.v_free_count", &freecount, &size, NULL, 0)) - return -errno; - - return (uint64_t) freecount * sysconf(_SC_PAGESIZE); - -} - - -uint64_t uv_get_total_memory(void) { - unsigned long info; - int which[] = {CTL_HW, HW_PHYSMEM}; - - size_t size = sizeof(info); - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info; -} - - -void uv_loadavg(double avg[3]) { - struct loadavg info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_LOADAVG}; - - if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return; - - avg[0] = (double) info.ldavg[0] / info.fscale; - avg[1] = (double) info.ldavg[1] / info.fscale; - avg[2] = (double) info.ldavg[2] / info.fscale; -} - - -char** uv_setup_args(int argc, char** argv) { - process_title = argc ? strdup(argv[0]) : NULL; - return argv; -} - - -int uv_set_process_title(const char* title) { - int oid[4]; - - if (process_title) free(process_title); - process_title = strdup(title); - - oid[0] = CTL_KERN; - oid[1] = KERN_PROC; - oid[2] = KERN_PROC_ARGS; - oid[3] = getpid(); - - sysctl(oid, - ARRAY_SIZE(oid), - NULL, - NULL, - process_title, - strlen(process_title) + 1); - - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (process_title) { - strncpy(buffer, process_title, size); - } else { - if (size > 0) { - buffer[0] = '\0'; - } - } - - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - kvm_t *kd = NULL; - struct kinfo_proc *kinfo = NULL; - pid_t pid; - int nprocs; - size_t page_size = getpagesize(); - - pid = getpid(); - - kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); - if (kd == NULL) goto error; - - kinfo = kvm_getprocs(kd, KERN_PROC_PID, pid, &nprocs); - if (kinfo == NULL) goto error; - -#ifdef __DragonFly__ - *rss = kinfo->kp_vm_rssize * page_size; -#else - *rss = kinfo->ki_rssize * page_size; -#endif - - kvm_close(kd); - - return 0; - -error: - if (kd) kvm_close(kd); - return -EPERM; -} - - -int uv_uptime(double* uptime) { - time_t now; - struct timeval info; - size_t size = sizeof(info); - static int which[] = {CTL_KERN, KERN_BOOTTIME}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - now = time(NULL); - - *uptime = (double)(now - info.tv_sec); - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), - multiplier = ((uint64_t)1000L / ticks), cpuspeed, maxcpus, - cur = 0; - uv_cpu_info_t* cpu_info; - const char* maxcpus_key; - const char* cptimes_key; - char model[512]; - long* cp_times; - int numcpus; - size_t size; - int i; - -#if defined(__DragonFly__) - /* This is not quite correct but DragonFlyBSD doesn't seem to have anything - * comparable to kern.smp.maxcpus or kern.cp_times (kern.cp_time is a total, - * not per CPU). At least this stops uv_cpu_info() from failing completely. - */ - maxcpus_key = "hw.ncpu"; - cptimes_key = "kern.cp_time"; -#else - maxcpus_key = "kern.smp.maxcpus"; - cptimes_key = "kern.cp_times"; -#endif - - size = sizeof(model); - if (sysctlbyname("hw.model", &model, &size, NULL, 0)) - return -errno; - - size = sizeof(numcpus); - if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) - return -errno; - - *cpu_infos = malloc(numcpus * sizeof(**cpu_infos)); - if (!(*cpu_infos)) - return -ENOMEM; - - *count = numcpus; - - size = sizeof(cpuspeed); - if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) { - SAVE_ERRNO(free(*cpu_infos)); - return -errno; - } - - /* kern.cp_times on FreeBSD i386 gives an array up to maxcpus instead of - * ncpu. - */ - size = sizeof(maxcpus); - if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) { - SAVE_ERRNO(free(*cpu_infos)); - return -errno; - } - - size = maxcpus * CPUSTATES * sizeof(long); - - cp_times = malloc(size); - if (cp_times == NULL) { - free(*cpu_infos); - return -ENOMEM; - } - - if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) { - SAVE_ERRNO(free(cp_times)); - SAVE_ERRNO(free(*cpu_infos)); - return -errno; - } - - for (i = 0; i < numcpus; i++) { - cpu_info = &(*cpu_infos)[i]; - - cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier; - cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier; - cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier; - cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier; - cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier; - - cpu_info->model = strdup(model); - cpu_info->speed = cpuspeed; - - cur+=CPUSTATES; - } - - free(cp_times); - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - free(cpu_infos[i].model); - } - - free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = malloc(*count * sizeof(**addresses)); - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On FreeBSD getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - free(addresses[i].name); - } - - free(addresses); -} diff --git a/third-party/libuv/src/unix/fs.c b/third-party/libuv/src/unix/fs.c deleted file mode 100644 index 1aa6539cb4..0000000000 --- a/third-party/libuv/src/unix/fs.c +++ /dev/null @@ -1,971 +0,0 @@ -/* 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 - * 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. - */ - -/* Caveat emptor: this file deviates from the libuv convention of returning - * negated errno codes. Most uv_fs_*() functions map directly to the system - * call of the same name. For more complex wrappers, it's easier to just - * return -1 with errno set. The dispatcher in uv__fs_work() takes care of - * getting the errno to the right place (req->result or as the return value.) - */ - -#include "uv.h" -#include "internal.h" - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <pthread.h> -#include <dirent.h> -#include <unistd.h> -#include <fcntl.h> -#include <utime.h> -#include <poll.h> - -#if defined(__linux__) || defined(__sun) -# include <sys/sendfile.h> -#elif defined(__APPLE__) || defined(__FreeBSD__) -# include <sys/socket.h> -# include <sys/uio.h> -#endif - -#define INIT(type) \ - do { \ - uv__req_init((loop), (req), UV_FS); \ - (req)->fs_type = UV_FS_ ## type; \ - (req)->result = 0; \ - (req)->ptr = NULL; \ - (req)->loop = loop; \ - (req)->path = NULL; \ - (req)->new_path = NULL; \ - (req)->cb = (cb); \ - } \ - while (0) - -#define PATH \ - do { \ - (req)->path = strdup(path); \ - if ((req)->path == NULL) \ - return -ENOMEM; \ - } \ - while (0) - -#define PATH2 \ - do { \ - size_t path_len; \ - size_t new_path_len; \ - path_len = strlen((path)) + 1; \ - new_path_len = strlen((new_path)) + 1; \ - (req)->path = malloc(path_len + new_path_len); \ - if ((req)->path == NULL) \ - return -ENOMEM; \ - (req)->new_path = (req)->path + path_len; \ - memcpy((void*) (req)->path, (path), path_len); \ - memcpy((void*) (req)->new_path, (new_path), new_path_len); \ - } \ - while (0) - -#define POST \ - do { \ - if ((cb) != NULL) { \ - uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \ - return 0; \ - } \ - else { \ - uv__fs_work(&(req)->work_req); \ - uv__fs_done(&(req)->work_req, 0); \ - return (req)->result; \ - } \ - } \ - while (0) - - -static ssize_t uv__fs_fdatasync(uv_fs_t* req) { -#if defined(__linux__) || defined(__sun) || defined(__NetBSD__) - return fdatasync(req->file); -#elif defined(__APPLE__) && defined(F_FULLFSYNC) - return fcntl(req->file, F_FULLFSYNC); -#else - return fsync(req->file); -#endif -} - - -static ssize_t uv__fs_futime(uv_fs_t* req) { -#if defined(__linux__) - /* utimesat() has nanosecond resolution but we stick to microseconds - * for the sake of consistency with other platforms. - */ - static int no_utimesat; - struct timespec ts[2]; - struct timeval tv[2]; - char path[sizeof("/proc/self/fd/") + 3 * sizeof(int)]; - int r; - - if (no_utimesat) - goto skip; - - ts[0].tv_sec = req->atime; - ts[0].tv_nsec = (unsigned long)(req->atime * 1000000) % 1000000 * 1000; - ts[1].tv_sec = req->mtime; - ts[1].tv_nsec = (unsigned long)(req->mtime * 1000000) % 1000000 * 1000; - - r = uv__utimesat(req->file, NULL, ts, 0); - if (r == 0) - return r; - - if (errno != ENOSYS) - return r; - - no_utimesat = 1; - -skip: - - tv[0].tv_sec = req->atime; - tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000; - tv[1].tv_sec = req->mtime; - tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000; - snprintf(path, sizeof(path), "/proc/self/fd/%d", (int) req->file); - - r = utimes(path, tv); - if (r == 0) - return r; - - switch (errno) { - case ENOENT: - if (fcntl(req->file, F_GETFL) == -1 && errno == EBADF) - break; - /* Fall through. */ - - case EACCES: - case ENOTDIR: - errno = ENOSYS; - break; - } - - return r; - -#elif defined(__APPLE__) \ - || defined(__DragonFly__) \ - || defined(__FreeBSD__) \ - || defined(__NetBSD__) \ - || defined(__OpenBSD__) \ - || defined(__sun) - struct timeval tv[2]; - tv[0].tv_sec = req->atime; - tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000; - tv[1].tv_sec = req->mtime; - tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000; -# if defined(__sun) - return futimesat(req->file, NULL, tv); -# else - return futimes(req->file, tv); -# endif -#else - errno = ENOSYS; - return -1; -#endif -} - - -static ssize_t uv__fs_read(uv_fs_t* req) { - if (req->off < 0) - return read(req->file, req->buf, req->len); - else - return pread(req->file, req->buf, req->len, req->off); -} - - -static int uv__fs_readdir_filter(const struct dirent* dent) { - return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0; -} - - -/* This should have been called uv__fs_scandir(). */ -static ssize_t uv__fs_readdir(uv_fs_t* req) { - struct dirent **dents; - int saved_errno; - size_t off; - size_t len; - char *buf; - int i; - int n; - - dents = NULL; - n = scandir(req->path, &dents, uv__fs_readdir_filter, alphasort); - - if (n == 0) - goto out; /* osx still needs to deallocate some memory */ - else if (n == -1) - return n; - - len = 0; - - for (i = 0; i < n; i++) - len += strlen(dents[i]->d_name) + 1; - - buf = malloc(len); - - if (buf == NULL) { - errno = ENOMEM; - n = -1; - goto out; - } - - off = 0; - - for (i = 0; i < n; i++) { - len = strlen(dents[i]->d_name) + 1; - memcpy(buf + off, dents[i]->d_name, len); - off += len; - } - - req->ptr = buf; - -out: - saved_errno = errno; - if (dents != NULL) { - for (i = 0; i < n; i++) - free(dents[i]); - free(dents); - } - errno = saved_errno; - - return n; -} - - -static ssize_t uv__fs_readlink(uv_fs_t* req) { - ssize_t len; - char* buf; - - len = pathconf(req->path, _PC_PATH_MAX); - - if (len == -1) { -#if defined(PATH_MAX) - len = PATH_MAX; -#else - len = 4096; -#endif - } - - buf = malloc(len + 1); - - if (buf == NULL) { - errno = ENOMEM; - return -1; - } - - len = readlink(req->path, buf, len); - - if (len == -1) { - free(buf); - return -1; - } - - buf[len] = '\0'; - req->ptr = buf; - - return 0; -} - - -static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) { - struct pollfd pfd; - int use_pread; - off_t offset; - ssize_t nsent; - ssize_t nread; - ssize_t nwritten; - size_t buflen; - size_t len; - ssize_t n; - int in_fd; - int out_fd; - char buf[8192]; - - len = req->len; - in_fd = req->flags; - out_fd = req->file; - offset = req->off; - use_pread = 1; - - /* Here are the rules regarding errors: - * - * 1. Read errors are reported only if nsent==0, otherwise we return nsent. - * The user needs to know that some data has already been sent, to stop - * them from sending it twice. - * - * 2. Write errors are always reported. Write errors are bad because they - * mean data loss: we've read data but now we can't write it out. - * - * We try to use pread() and fall back to regular read() if the source fd - * doesn't support positional reads, for example when it's a pipe fd. - * - * If we get EAGAIN when writing to the target fd, we poll() on it until - * it becomes writable again. - * - * FIXME: If we get a write error when use_pread==1, it should be safe to - * return the number of sent bytes instead of an error because pread() - * is, in theory, idempotent. However, special files in /dev or /proc - * may support pread() but not necessarily return the same data on - * successive reads. - * - * FIXME: There is no way now to signal that we managed to send *some* data - * before a write error. - */ - for (nsent = 0; (size_t) nsent < len; ) { - buflen = len - nsent; - - if (buflen > sizeof(buf)) - buflen = sizeof(buf); - - do - if (use_pread) - nread = pread(in_fd, buf, buflen, offset); - else - nread = read(in_fd, buf, buflen); - while (nread == -1 && errno == EINTR); - - if (nread == 0) - goto out; - - if (nread == -1) { - if (use_pread && nsent == 0 && (errno == EIO || errno == ESPIPE)) { - use_pread = 0; - continue; - } - - if (nsent == 0) - nsent = -1; - - goto out; - } - - for (nwritten = 0; nwritten < nread; ) { - do - n = write(out_fd, buf + nwritten, nread - nwritten); - while (n == -1 && errno == EINTR); - - if (n != -1) { - nwritten += n; - continue; - } - - if (errno != EAGAIN && errno != EWOULDBLOCK) { - nsent = -1; - goto out; - } - - pfd.fd = out_fd; - pfd.events = POLLOUT; - pfd.revents = 0; - - do - n = poll(&pfd, 1, -1); - while (n == -1 && errno == EINTR); - - if (n == -1 || (pfd.revents & ~POLLOUT) != 0) { - errno = EIO; - nsent = -1; - goto out; - } - } - - offset += nread; - nsent += nread; - } - -out: - if (nsent != -1) - req->off = offset; - - return nsent; -} - - -static ssize_t uv__fs_sendfile(uv_fs_t* req) { - int in_fd; - int out_fd; - - in_fd = req->flags; - out_fd = req->file; - -#if defined(__linux__) || defined(__sun) - { - off_t off; - ssize_t r; - - off = req->off; - r = sendfile(out_fd, in_fd, &off, req->len); - - /* sendfile() on SunOS returns EINVAL if the target fd is not a socket but - * it still writes out data. Fortunately, we can detect it by checking if - * the offset has been updated. - */ - if (r != -1 || off > req->off) { - r = off - req->off; - req->off = off; - return r; - } - - if (errno == EINVAL || - errno == EIO || - errno == ENOTSOCK || - errno == EXDEV) { - errno = 0; - return uv__fs_sendfile_emul(req); - } - - return -1; - } -#elif defined(__FreeBSD__) || defined(__APPLE__) - { - off_t len; - ssize_t r; - - /* sendfile() on FreeBSD and Darwin returns EAGAIN if the target fd is in - * non-blocking mode and not all data could be written. If a non-zero - * number of bytes have been sent, we don't consider it an error. - */ - -#if defined(__FreeBSD__) - len = 0; - r = sendfile(in_fd, out_fd, req->off, req->len, NULL, &len, 0); -#else - /* The darwin sendfile takes len as an input for the length to send, - * so make sure to initialize it with the caller's value. */ - len = req->len; - r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0); -#endif - - if (r != -1 || len != 0) { - req->off += len; - return (ssize_t) len; - } - - if (errno == EINVAL || - errno == EIO || - errno == ENOTSOCK || - errno == EXDEV) { - errno = 0; - return uv__fs_sendfile_emul(req); - } - - return -1; - } -#else - /* Squelch compiler warnings. */ - (void) &in_fd; - (void) &out_fd; - - return uv__fs_sendfile_emul(req); -#endif -} - - -static ssize_t uv__fs_utime(uv_fs_t* req) { - struct utimbuf buf; - buf.actime = req->atime; - buf.modtime = req->mtime; - return utime(req->path, &buf); /* TODO use utimes() where available */ -} - - -static ssize_t uv__fs_write(uv_fs_t* req) { - ssize_t r; - - /* Serialize writes on OS X, concurrent write() and pwrite() calls result in - * data loss. We can't use a per-file descriptor lock, the descriptor may be - * a dup(). - */ -#if defined(__APPLE__) - static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_lock(&lock); -#endif - - if (req->off < 0) - r = write(req->file, req->buf, req->len); - else - r = pwrite(req->file, req->buf, req->len, req->off); - -#if defined(__APPLE__) - pthread_mutex_unlock(&lock); -#endif - - return r; -} - -static void uv__to_stat(struct stat* src, uv_stat_t* dst) { - dst->st_dev = src->st_dev; - dst->st_mode = src->st_mode; - dst->st_nlink = src->st_nlink; - dst->st_uid = src->st_uid; - dst->st_gid = src->st_gid; - dst->st_rdev = src->st_rdev; - dst->st_ino = src->st_ino; - dst->st_size = src->st_size; - dst->st_blksize = src->st_blksize; - dst->st_blocks = src->st_blocks; - -#if defined(__APPLE__) - dst->st_atim.tv_sec = src->st_atimespec.tv_sec; - dst->st_atim.tv_nsec = src->st_atimespec.tv_nsec; - dst->st_mtim.tv_sec = src->st_mtimespec.tv_sec; - dst->st_mtim.tv_nsec = src->st_mtimespec.tv_nsec; - dst->st_ctim.tv_sec = src->st_ctimespec.tv_sec; - dst->st_ctim.tv_nsec = src->st_ctimespec.tv_nsec; - dst->st_birthtim.tv_sec = src->st_birthtimespec.tv_sec; - dst->st_birthtim.tv_nsec = src->st_birthtimespec.tv_nsec; - dst->st_flags = src->st_flags; - dst->st_gen = src->st_gen; -#elif defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(_XOPEN_SOURCE) - dst->st_atim.tv_sec = src->st_atim.tv_sec; - dst->st_atim.tv_nsec = src->st_atim.tv_nsec; - dst->st_mtim.tv_sec = src->st_mtim.tv_sec; - dst->st_mtim.tv_nsec = src->st_mtim.tv_nsec; - dst->st_ctim.tv_sec = src->st_ctim.tv_sec; - dst->st_ctim.tv_nsec = src->st_ctim.tv_nsec; -# if defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__OpenBSD__) || \ - defined(__NetBSD__) - dst->st_birthtim.tv_sec = src->st_birthtim.tv_sec; - dst->st_birthtim.tv_nsec = src->st_birthtim.tv_nsec; - dst->st_flags = src->st_flags; - dst->st_gen = src->st_gen; -# else - dst->st_birthtim.tv_sec = src->st_ctim.tv_sec; - dst->st_birthtim.tv_nsec = src->st_ctim.tv_nsec; - dst->st_flags = 0; - dst->st_gen = 0; -# endif -#else - dst->st_atim.tv_sec = src->st_atime; - dst->st_atim.tv_nsec = 0; - dst->st_mtim.tv_sec = src->st_mtime; - dst->st_mtim.tv_nsec = 0; - dst->st_ctim.tv_sec = src->st_ctime; - dst->st_ctim.tv_nsec = 0; - dst->st_birthtim.tv_sec = src->st_ctime; - dst->st_birthtim.tv_nsec = 0; - dst->st_flags = 0; - dst->st_gen = 0; -#endif -} - - -static int uv__fs_stat(const char *path, uv_stat_t *buf) { - struct stat pbuf; - int ret; - ret = stat(path, &pbuf); - uv__to_stat(&pbuf, buf); - return ret; -} - - -static int uv__fs_lstat(const char *path, uv_stat_t *buf) { - struct stat pbuf; - int ret; - ret = lstat(path, &pbuf); - uv__to_stat(&pbuf, buf); - return ret; -} - - -static int uv__fs_fstat(int fd, uv_stat_t *buf) { - struct stat pbuf; - int ret; - ret = fstat(fd, &pbuf); - uv__to_stat(&pbuf, buf); - return ret; -} - - -static void uv__fs_work(struct uv__work* w) { - int retry_on_eintr; - uv_fs_t* req; - ssize_t r; - - req = container_of(w, uv_fs_t, work_req); - retry_on_eintr = !(req->fs_type == UV_FS_CLOSE); - - do { - errno = 0; - -#define X(type, action) \ - case UV_FS_ ## type: \ - r = action; \ - break; - - switch (req->fs_type) { - X(CHMOD, chmod(req->path, req->mode)); - X(CHOWN, chown(req->path, req->uid, req->gid)); - X(CLOSE, close(req->file)); - X(FCHMOD, fchmod(req->file, req->mode)); - X(FCHOWN, fchown(req->file, req->uid, req->gid)); - X(FDATASYNC, uv__fs_fdatasync(req)); - X(FSTAT, uv__fs_fstat(req->file, &req->statbuf)); - X(FSYNC, fsync(req->file)); - X(FTRUNCATE, ftruncate(req->file, req->off)); - X(FUTIME, uv__fs_futime(req)); - X(LSTAT, uv__fs_lstat(req->path, &req->statbuf)); - X(LINK, link(req->path, req->new_path)); - X(MKDIR, mkdir(req->path, req->mode)); - X(OPEN, open(req->path, req->flags, req->mode)); - X(READ, uv__fs_read(req)); - X(READDIR, uv__fs_readdir(req)); - X(READLINK, uv__fs_readlink(req)); - X(RENAME, rename(req->path, req->new_path)); - X(RMDIR, rmdir(req->path)); - X(SENDFILE, uv__fs_sendfile(req)); - X(STAT, uv__fs_stat(req->path, &req->statbuf)); - X(SYMLINK, symlink(req->path, req->new_path)); - X(UNLINK, unlink(req->path)); - X(UTIME, uv__fs_utime(req)); - X(WRITE, uv__fs_write(req)); - default: abort(); - } - -#undef X - } - while (r == -1 && errno == EINTR && retry_on_eintr); - - if (r == -1) - req->result = -errno; - else - req->result = r; - - if (r == 0 && (req->fs_type == UV_FS_STAT || - req->fs_type == UV_FS_FSTAT || - req->fs_type == UV_FS_LSTAT)) { - req->ptr = &req->statbuf; - } -} - - -static void uv__fs_done(struct uv__work* w, int status) { - uv_fs_t* req; - - req = container_of(w, uv_fs_t, work_req); - uv__req_unregister(req->loop, req); - - if (status == -ECANCELED) { - assert(req->result == 0); - req->result = -ECANCELED; - } - - if (req->cb != NULL) - req->cb(req); -} - - -int uv_fs_chmod(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int mode, - uv_fs_cb cb) { - INIT(CHMOD); - PATH; - req->mode = mode; - POST; -} - - -int uv_fs_chown(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_uid_t uid, - uv_gid_t gid, - uv_fs_cb cb) { - INIT(CHOWN); - PATH; - req->uid = uid; - req->gid = gid; - POST; -} - - -int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { - INIT(CLOSE); - req->file = file; - POST; -} - - -int uv_fs_fchmod(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - int mode, - uv_fs_cb cb) { - INIT(FCHMOD); - req->file = file; - req->mode = mode; - POST; -} - - -int uv_fs_fchown(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - uv_uid_t uid, - uv_gid_t gid, - uv_fs_cb cb) { - INIT(FCHOWN); - req->file = file; - req->uid = uid; - req->gid = gid; - POST; -} - - -int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { - INIT(FDATASYNC); - req->file = file; - POST; -} - - -int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { - INIT(FSTAT); - req->file = file; - POST; -} - - -int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { - INIT(FSYNC); - req->file = file; - POST; -} - - -int uv_fs_ftruncate(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - int64_t off, - uv_fs_cb cb) { - INIT(FTRUNCATE); - req->file = file; - req->off = off; - POST; -} - - -int uv_fs_futime(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - double atime, - double mtime, - uv_fs_cb cb) { - INIT(FUTIME); - req->file = file; - req->atime = atime; - req->mtime = mtime; - POST; -} - - -int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - INIT(LSTAT); - PATH; - POST; -} - - -int uv_fs_link(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - const char* new_path, - uv_fs_cb cb) { - INIT(LINK); - PATH2; - POST; -} - - -int uv_fs_mkdir(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int mode, - uv_fs_cb cb) { - INIT(MKDIR); - PATH; - req->mode = mode; - POST; -} - - -int uv_fs_open(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int flags, - int mode, - uv_fs_cb cb) { - INIT(OPEN); - PATH; - req->flags = flags; - req->mode = mode; - POST; -} - - -int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, - uv_file file, - void* buf, - size_t len, - int64_t off, - uv_fs_cb cb) { - INIT(READ); - req->file = file; - req->buf = buf; - req->len = len; - req->off = off; - POST; -} - - -int uv_fs_readdir(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int flags, - uv_fs_cb cb) { - INIT(READDIR); - PATH; - req->flags = flags; - POST; -} - - -int uv_fs_readlink(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - uv_fs_cb cb) { - INIT(READLINK); - PATH; - POST; -} - - -int uv_fs_rename(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - const char* new_path, - uv_fs_cb cb) { - INIT(RENAME); - PATH2; - POST; -} - - -int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - INIT(RMDIR); - PATH; - POST; -} - - -int uv_fs_sendfile(uv_loop_t* loop, - uv_fs_t* req, - uv_file out_fd, - uv_file in_fd, - int64_t off, - size_t len, - uv_fs_cb cb) { - INIT(SENDFILE); - req->flags = in_fd; /* hack */ - req->file = out_fd; - req->off = off; - req->len = len; - POST; -} - - -int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - INIT(STAT); - PATH; - POST; -} - - -int uv_fs_symlink(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - const char* new_path, - int flags, - uv_fs_cb cb) { - INIT(SYMLINK); - PATH2; - req->flags = flags; - POST; -} - - -int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - INIT(UNLINK); - PATH; - POST; -} - - -int uv_fs_utime(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - double atime, - double mtime, - uv_fs_cb cb) { - INIT(UTIME); - PATH; - req->atime = atime; - req->mtime = mtime; - POST; -} - - -int uv_fs_write(uv_loop_t* loop, - uv_fs_t* req, - uv_file file, - const void* buf, - size_t len, - int64_t off, - uv_fs_cb cb) { - INIT(WRITE); - req->file = file; - req->buf = (void*) buf; - req->len = len; - req->off = off; - POST; -} - - -void uv_fs_req_cleanup(uv_fs_t* req) { - free((void*) req->path); - req->path = NULL; - req->new_path = NULL; - - if (req->ptr != &req->statbuf) - free(req->ptr); - req->ptr = NULL; -} diff --git a/third-party/libuv/src/unix/fsevents.c b/third-party/libuv/src/unix/fsevents.c deleted file mode 100644 index 7faa1562a6..0000000000 --- a/third-party/libuv/src/unix/fsevents.c +++ /dev/null @@ -1,899 +0,0 @@ -/* 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 - * 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" - -#if TARGET_OS_IPHONE - -/* iOS (currently) doesn't provide the FSEvents-API (nor CoreServices) */ - -int uv__fsevents_init(uv_fs_event_t* handle) { - return 0; -} - - -int uv__fsevents_close(uv_fs_event_t* handle) { - return 0; -} - - -void uv__fsevents_loop_delete(uv_loop_t* loop) { -} - -#else /* TARGET_OS_IPHONE */ - -#include <dlfcn.h> -#include <assert.h> -#include <stdlib.h> -#include <pthread.h> - -#include <CoreFoundation/CFRunLoop.h> -#include <CoreServices/CoreServices.h> - -/* These are macros to avoid "initializer element is not constant" errors - * with old versions of gcc. - */ -#define kFSEventsModified (kFSEventStreamEventFlagItemFinderInfoMod | \ - kFSEventStreamEventFlagItemModified | \ - kFSEventStreamEventFlagItemInodeMetaMod | \ - kFSEventStreamEventFlagItemChangeOwner | \ - kFSEventStreamEventFlagItemXattrMod) - -#define kFSEventsRenamed (kFSEventStreamEventFlagItemCreated | \ - kFSEventStreamEventFlagItemRemoved | \ - kFSEventStreamEventFlagItemRenamed) - -#define kFSEventsSystem (kFSEventStreamEventFlagUserDropped | \ - kFSEventStreamEventFlagKernelDropped | \ - kFSEventStreamEventFlagEventIdsWrapped | \ - kFSEventStreamEventFlagHistoryDone | \ - kFSEventStreamEventFlagMount | \ - kFSEventStreamEventFlagUnmount | \ - kFSEventStreamEventFlagRootChanged) - -typedef struct uv__fsevents_event_s uv__fsevents_event_t; -typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t; -typedef struct uv__cf_loop_state_s uv__cf_loop_state_t; - -struct uv__cf_loop_signal_s { - QUEUE member; - uv_fs_event_t* handle; -}; - -struct uv__fsevents_event_s { - QUEUE member; - int events; - char path[1]; -}; - -struct uv__cf_loop_state_s { - CFRunLoopRef loop; - CFRunLoopSourceRef signal_source; - int fsevent_need_reschedule; - FSEventStreamRef fsevent_stream; - uv_sem_t fsevent_sem; - uv_mutex_t fsevent_mutex; - void* fsevent_handles[2]; - unsigned int fsevent_handle_count; -}; - -/* Forward declarations */ -static void uv__cf_loop_cb(void* arg); -static void* uv__cf_loop_runner(void* arg); -static int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle); - -/* Lazy-loaded by uv__fsevents_global_init(). */ -static CFArrayRef (*pCFArrayCreate)(CFAllocatorRef, - const void**, - CFIndex, - const CFArrayCallBacks*); -static void (*pCFRelease)(CFTypeRef); -static void (*pCFRunLoopAddSource)(CFRunLoopRef, - CFRunLoopSourceRef, - CFStringRef); -static CFRunLoopRef (*pCFRunLoopGetCurrent)(void); -static void (*pCFRunLoopRemoveSource)(CFRunLoopRef, - CFRunLoopSourceRef, - CFStringRef); -static void (*pCFRunLoopRun)(void); -static CFRunLoopSourceRef (*pCFRunLoopSourceCreate)(CFAllocatorRef, - CFIndex, - CFRunLoopSourceContext*); -static void (*pCFRunLoopSourceSignal)(CFRunLoopSourceRef); -static void (*pCFRunLoopStop)(CFRunLoopRef); -static void (*pCFRunLoopWakeUp)(CFRunLoopRef); -static CFStringRef (*pCFStringCreateWithFileSystemRepresentation)( - CFAllocatorRef, - const char*); -static CFStringEncoding (*pCFStringGetSystemEncoding)(void); -static CFStringRef (*pkCFRunLoopDefaultMode); -static FSEventStreamRef (*pFSEventStreamCreate)(CFAllocatorRef, - FSEventStreamCallback, - FSEventStreamContext*, - CFArrayRef, - FSEventStreamEventId, - CFTimeInterval, - FSEventStreamCreateFlags); -static void (*pFSEventStreamFlushSync)(FSEventStreamRef); -static void (*pFSEventStreamInvalidate)(FSEventStreamRef); -static void (*pFSEventStreamRelease)(FSEventStreamRef); -static void (*pFSEventStreamScheduleWithRunLoop)(FSEventStreamRef, - CFRunLoopRef, - CFStringRef); -static Boolean (*pFSEventStreamStart)(FSEventStreamRef); -static void (*pFSEventStreamStop)(FSEventStreamRef); - -#define UV__FSEVENTS_PROCESS(handle, block) \ - do { \ - QUEUE events; \ - QUEUE* q; \ - uv__fsevents_event_t* event; \ - int err; \ - uv_mutex_lock(&(handle)->cf_mutex); \ - /* Split-off all events and empty original queue */ \ - QUEUE_INIT(&events); \ - if (!QUEUE_EMPTY(&(handle)->cf_events)) { \ - q = QUEUE_HEAD(&(handle)->cf_events); \ - QUEUE_SPLIT(&(handle)->cf_events, q, &events); \ - } \ - /* Get error (if any) and zero original one */ \ - err = (handle)->cf_error; \ - (handle)->cf_error = 0; \ - uv_mutex_unlock(&(handle)->cf_mutex); \ - /* Loop through events, deallocating each after processing */ \ - while (!QUEUE_EMPTY(&events)) { \ - q = QUEUE_HEAD(&events); \ - event = QUEUE_DATA(q, uv__fsevents_event_t, member); \ - QUEUE_REMOVE(q); \ - /* NOTE: Checking uv__is_active() is required here, because handle \ - * callback may close handle and invoking it after it will lead to \ - * incorrect behaviour */ \ - if (!uv__is_closing((handle)) && uv__is_active((handle))) \ - block \ - /* Free allocated data */ \ - free(event); \ - } \ - if (err != 0 && !uv__is_closing((handle)) && uv__is_active((handle))) \ - (handle)->cb((handle), NULL, 0, err); \ - } while (0) - - -/* Runs in UV loop's thread, when there're events to report to handle */ -static void uv__fsevents_cb(uv_async_t* cb, int status) { - uv_fs_event_t* handle; - - handle = cb->data; - - UV__FSEVENTS_PROCESS(handle, { - handle->cb(handle, event->path[0] ? event->path : NULL, event->events, 0); - }); -} - - -/* Runs in CF thread, pushed event into handle's event list */ -static void uv__fsevents_push_event(uv_fs_event_t* handle, - QUEUE* events, - int err) { - assert(events != NULL || err != 0); - uv_mutex_lock(&handle->cf_mutex); - - /* Concatenate two queues */ - if (events != NULL) - QUEUE_ADD(&handle->cf_events, events); - - /* Propagate error */ - if (err != 0) - handle->cf_error = err; - uv_mutex_unlock(&handle->cf_mutex); - - uv_async_send(handle->cf_cb); -} - - -/* Runs in CF thread, when there're events in FSEventStream */ -static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef, - void* info, - size_t numEvents, - void* eventPaths, - const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIds[]) { - size_t i; - int len; - char** paths; - char* path; - char* pos; - uv_fs_event_t* handle; - QUEUE* q; - uv_loop_t* loop; - uv__cf_loop_state_t* state; - uv__fsevents_event_t* event; - QUEUE head; - - loop = info; - state = loop->cf_state; - assert(state != NULL); - paths = eventPaths; - - /* For each handle */ - uv_mutex_lock(&state->fsevent_mutex); - QUEUE_FOREACH(q, &state->fsevent_handles) { - handle = QUEUE_DATA(q, uv_fs_event_t, cf_member); - QUEUE_INIT(&head); - - /* Process and filter out events */ - for (i = 0; i < numEvents; i++) { - /* Ignore system events */ - if (eventFlags[i] & kFSEventsSystem) - continue; - - path = paths[i]; - len = strlen(path); - - /* Filter out paths that are outside handle's request */ - if (strncmp(path, handle->realpath, handle->realpath_len) != 0) - continue; - - if (handle->realpath_len > 1 || *handle->realpath != '/') { - path += handle->realpath_len; - len -= handle->realpath_len; - - /* Skip forward slash */ - if (*path != '\0') { - path++; - len--; - } - } - -#ifdef MAC_OS_X_VERSION_10_7 - /* Ignore events with path equal to directory itself */ - if (len == 0) - continue; -#endif /* MAC_OS_X_VERSION_10_7 */ - - /* Do not emit events from subdirectories (without option set) */ - if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != 0) { - pos = strchr(path + 1, '/'); - if (pos != NULL) - continue; - } - -#ifndef MAC_OS_X_VERSION_10_7 - path = ""; - len = 0; -#endif /* MAC_OS_X_VERSION_10_7 */ - - event = malloc(sizeof(*event) + len); - if (event == NULL) - break; - - memset(event, 0, sizeof(*event)); - memcpy(event->path, path, len + 1); - - if ((eventFlags[i] & kFSEventsModified) != 0 && - (eventFlags[i] & kFSEventsRenamed) == 0) - event->events = UV_CHANGE; - else - event->events = UV_RENAME; - - QUEUE_INSERT_TAIL(&head, &event->member); - } - - if (!QUEUE_EMPTY(&head)) - uv__fsevents_push_event(handle, &head, 0); - } - uv_mutex_unlock(&state->fsevent_mutex); -} - - -/* Runs in CF thread */ -static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) { - uv__cf_loop_state_t* state; - FSEventStreamContext ctx; - FSEventStreamRef ref; - CFAbsoluteTime latency; - FSEventStreamCreateFlags flags; - - /* Initialize context */ - ctx.version = 0; - ctx.info = loop; - ctx.retain = NULL; - ctx.release = NULL; - ctx.copyDescription = NULL; - - latency = 0.05; - - /* Explanation of selected flags: - * 1. NoDefer - without this flag, events that are happening continuously - * (i.e. each event is happening after time interval less than `latency`, - * counted from previous event), will be deferred and passed to callback - * once they'll either fill whole OS buffer, or when this continuous stream - * will stop (i.e. there'll be delay between events, bigger than - * `latency`). - * Specifying this flag will invoke callback after `latency` time passed - * since event. - * 2. FileEvents - fire callback for file changes too (by default it is firing - * it only for directory changes). - */ - flags = kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents; - - /* - * NOTE: It might sound like a good idea to remember last seen StreamEventId, - * but in reality one dir might have last StreamEventId less than, the other, - * that is being watched now. Which will cause FSEventStream API to report - * changes to files from the past. - */ - ref = pFSEventStreamCreate(NULL, - &uv__fsevents_event_cb, - &ctx, - paths, - kFSEventStreamEventIdSinceNow, - latency, - flags); - assert(ref != NULL); - - state = loop->cf_state; - pFSEventStreamScheduleWithRunLoop(ref, - state->loop, - *pkCFRunLoopDefaultMode); - if (!pFSEventStreamStart(ref)) { - pFSEventStreamInvalidate(ref); - pFSEventStreamRelease(ref); - return -EMFILE; - } - - state->fsevent_stream = ref; - return 0; -} - - -/* Runs in CF thread */ -static void uv__fsevents_destroy_stream(uv_loop_t* loop) { - uv__cf_loop_state_t* state; - - state = loop->cf_state; - - if (state->fsevent_stream == NULL) - return; - - /* Flush all accumulated events */ - pFSEventStreamFlushSync(state->fsevent_stream); - - /* Stop emitting events */ - pFSEventStreamStop(state->fsevent_stream); - - /* Release stream */ - pFSEventStreamInvalidate(state->fsevent_stream); - pFSEventStreamRelease(state->fsevent_stream); - state->fsevent_stream = NULL; -} - - -/* Runs in CF thread, when there're new fsevent handles to add to stream */ -static void uv__fsevents_reschedule(uv_fs_event_t* handle) { - uv__cf_loop_state_t* state; - QUEUE* q; - uv_fs_event_t* curr; - CFArrayRef cf_paths; - CFStringRef* paths; - unsigned int i; - int err; - unsigned int path_count; - - state = handle->loop->cf_state; - paths = NULL; - cf_paths = NULL; - err = 0; - /* NOTE: `i` is used in deallocation loop below */ - i = 0; - - /* Optimization to prevent O(n^2) time spent when starting to watch - * many files simultaneously - */ - uv_mutex_lock(&state->fsevent_mutex); - if (state->fsevent_need_reschedule == 0) { - uv_mutex_unlock(&state->fsevent_mutex); - goto final; - } - state->fsevent_need_reschedule = 0; - uv_mutex_unlock(&state->fsevent_mutex); - - /* Destroy previous FSEventStream */ - uv__fsevents_destroy_stream(handle->loop); - - /* Any failure below will be a memory failure */ - err = -ENOMEM; - - /* Create list of all watched paths */ - uv_mutex_lock(&state->fsevent_mutex); - path_count = state->fsevent_handle_count; - if (path_count != 0) { - paths = malloc(sizeof(*paths) * path_count); - if (paths == NULL) { - uv_mutex_unlock(&state->fsevent_mutex); - goto final; - } - - q = &state->fsevent_handles; - for (; i < path_count; i++) { - q = QUEUE_NEXT(q); - assert(q != &state->fsevent_handles); - curr = QUEUE_DATA(q, uv_fs_event_t, cf_member); - - assert(curr->realpath != NULL); - paths[i] = - pCFStringCreateWithFileSystemRepresentation(NULL, curr->realpath); - if (paths[i] == NULL) { - uv_mutex_unlock(&state->fsevent_mutex); - goto final; - } - } - } - uv_mutex_unlock(&state->fsevent_mutex); - err = 0; - - if (path_count != 0) { - /* Create new FSEventStream */ - cf_paths = pCFArrayCreate(NULL, (const void**) paths, path_count, NULL); - if (cf_paths == NULL) { - err = -ENOMEM; - goto final; - } - err = uv__fsevents_create_stream(handle->loop, cf_paths); - } - -final: - /* Deallocate all paths in case of failure */ - if (err != 0) { - if (cf_paths == NULL) { - while (i != 0) - pCFRelease(paths[--i]); - free(paths); - } else { - /* CFArray takes ownership of both strings and original C-array */ - pCFRelease(cf_paths); - } - - /* Broadcast error to all handles */ - uv_mutex_lock(&state->fsevent_mutex); - QUEUE_FOREACH(q, &state->fsevent_handles) { - curr = QUEUE_DATA(q, uv_fs_event_t, cf_member); - uv__fsevents_push_event(curr, NULL, err); - } - uv_mutex_unlock(&state->fsevent_mutex); - } - - /* - * Main thread will block until the removal of handle from the list, - * we must tell it when we're ready. - * - * NOTE: This is coupled with `uv_sem_wait()` in `uv__fsevents_close` - */ - if (!uv__is_active(handle)) - uv_sem_post(&state->fsevent_sem); -} - - -static int uv__fsevents_global_init(void) { - static pthread_mutex_t global_init_mutex = PTHREAD_MUTEX_INITIALIZER; - static void* core_foundation_handle; - static void* core_services_handle; - int err; - - err = 0; - pthread_mutex_lock(&global_init_mutex); - if (core_foundation_handle != NULL) - goto out; - - /* The libraries are never unloaded because we currently don't have a good - * mechanism for keeping a reference count. It's unlikely to be an issue - * but if it ever becomes one, we can turn the dynamic library handles into - * per-event loop properties and have the dynamic linker keep track for us. - */ - err = -ENOSYS; - core_foundation_handle = dlopen("/System/Library/Frameworks/" - "CoreFoundation.framework/" - "Versions/A/CoreFoundation", - RTLD_LAZY | RTLD_LOCAL); - if (core_foundation_handle == NULL) - goto out; - - core_services_handle = dlopen("/System/Library/Frameworks/" - "CoreServices.framework/" - "Versions/A/CoreServices", - RTLD_LAZY | RTLD_LOCAL); - if (core_services_handle == NULL) - goto out; - - err = -ENOENT; -#define V(handle, symbol) \ - do { \ - p ## symbol = dlsym((handle), #symbol); \ - if (p ## symbol == NULL) \ - goto out; \ - } \ - while (0) - V(core_foundation_handle, CFArrayCreate); - V(core_foundation_handle, CFRelease); - V(core_foundation_handle, CFRunLoopAddSource); - V(core_foundation_handle, CFRunLoopGetCurrent); - V(core_foundation_handle, CFRunLoopRemoveSource); - V(core_foundation_handle, CFRunLoopRun); - V(core_foundation_handle, CFRunLoopSourceCreate); - V(core_foundation_handle, CFRunLoopSourceSignal); - V(core_foundation_handle, CFRunLoopStop); - V(core_foundation_handle, CFRunLoopWakeUp); - V(core_foundation_handle, CFStringCreateWithFileSystemRepresentation); - V(core_foundation_handle, CFStringGetSystemEncoding); - V(core_foundation_handle, kCFRunLoopDefaultMode); - V(core_services_handle, FSEventStreamCreate); - V(core_services_handle, FSEventStreamFlushSync); - V(core_services_handle, FSEventStreamInvalidate); - V(core_services_handle, FSEventStreamRelease); - V(core_services_handle, FSEventStreamScheduleWithRunLoop); - V(core_services_handle, FSEventStreamStart); - V(core_services_handle, FSEventStreamStop); -#undef V - err = 0; - -out: - if (err && core_services_handle != NULL) { - dlclose(core_services_handle); - core_services_handle = NULL; - } - - if (err && core_foundation_handle != NULL) { - dlclose(core_foundation_handle); - core_foundation_handle = NULL; - } - - pthread_mutex_unlock(&global_init_mutex); - return err; -} - - -/* Runs in UV loop */ -static int uv__fsevents_loop_init(uv_loop_t* loop) { - CFRunLoopSourceContext ctx; - uv__cf_loop_state_t* state; - pthread_attr_t attr_storage; - pthread_attr_t* attr; - int err; - - if (loop->cf_state != NULL) - return 0; - - err = uv__fsevents_global_init(); - if (err) - return err; - - state = calloc(1, sizeof(*state)); - if (state == NULL) - return -ENOMEM; - - err = uv_mutex_init(&loop->cf_mutex); - if (err) - goto fail_mutex_init; - - err = uv_sem_init(&loop->cf_sem, 0); - if (err) - goto fail_sem_init; - - QUEUE_INIT(&loop->cf_signals); - - err = uv_sem_init(&state->fsevent_sem, 0); - if (err) - goto fail_fsevent_sem_init; - - err = uv_mutex_init(&state->fsevent_mutex); - if (err) - goto fail_fsevent_mutex_init; - - QUEUE_INIT(&state->fsevent_handles); - state->fsevent_need_reschedule = 0; - state->fsevent_handle_count = 0; - - memset(&ctx, 0, sizeof(ctx)); - ctx.info = loop; - ctx.perform = uv__cf_loop_cb; - state->signal_source = pCFRunLoopSourceCreate(NULL, 0, &ctx); - if (state->signal_source == NULL) { - err = -ENOMEM; - goto fail_signal_source_create; - } - - /* In the unlikely event that pthread_attr_init() fails, create the thread - * with the default stack size. We'll use a little more address space but - * that in itself is not a fatal error. - */ - attr = &attr_storage; - if (pthread_attr_init(attr)) - attr = NULL; - - if (attr != NULL) - if (pthread_attr_setstacksize(attr, 4 * PTHREAD_STACK_MIN)) - abort(); - - loop->cf_state = state; - - /* uv_thread_t is an alias for pthread_t. */ - err = -pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop); - - if (attr != NULL) - pthread_attr_destroy(attr); - - if (err) - goto fail_thread_create; - - /* Synchronize threads */ - uv_sem_wait(&loop->cf_sem); - return 0; - -fail_thread_create: - loop->cf_state = NULL; - -fail_signal_source_create: - uv_mutex_destroy(&state->fsevent_mutex); - -fail_fsevent_mutex_init: - uv_sem_destroy(&state->fsevent_sem); - -fail_fsevent_sem_init: - uv_sem_destroy(&loop->cf_sem); - -fail_sem_init: - uv_mutex_destroy(&loop->cf_mutex); - -fail_mutex_init: - free(state); - return err; -} - - -/* Runs in UV loop */ -void uv__fsevents_loop_delete(uv_loop_t* loop) { - uv__cf_loop_signal_t* s; - uv__cf_loop_state_t* state; - QUEUE* q; - - if (loop->cf_state == NULL) - return; - - if (uv__cf_loop_signal(loop, NULL) != 0) - abort(); - - uv_thread_join(&loop->cf_thread); - uv_sem_destroy(&loop->cf_sem); - uv_mutex_destroy(&loop->cf_mutex); - - /* Free any remaining data */ - while (!QUEUE_EMPTY(&loop->cf_signals)) { - q = QUEUE_HEAD(&loop->cf_signals); - s = QUEUE_DATA(q, uv__cf_loop_signal_t, member); - QUEUE_REMOVE(q); - free(s); - } - - /* Destroy state */ - state = loop->cf_state; - uv_sem_destroy(&state->fsevent_sem); - uv_mutex_destroy(&state->fsevent_mutex); - pCFRelease(state->signal_source); - free(state); - loop->cf_state = NULL; -} - - -/* Runs in CF thread. This is the CF loop's body */ -static void* uv__cf_loop_runner(void* arg) { - uv_loop_t* loop; - uv__cf_loop_state_t* state; - - loop = arg; - state = loop->cf_state; - state->loop = pCFRunLoopGetCurrent(); - - pCFRunLoopAddSource(state->loop, - state->signal_source, - *pkCFRunLoopDefaultMode); - - uv_sem_post(&loop->cf_sem); - - pCFRunLoopRun(); - pCFRunLoopRemoveSource(state->loop, - state->signal_source, - *pkCFRunLoopDefaultMode); - - return NULL; -} - - -/* Runs in CF thread, executed after `uv__cf_loop_signal()` */ -static void uv__cf_loop_cb(void* arg) { - uv_loop_t* loop; - uv__cf_loop_state_t* state; - QUEUE* item; - QUEUE split_head; - uv__cf_loop_signal_t* s; - - loop = arg; - state = loop->cf_state; - QUEUE_INIT(&split_head); - - uv_mutex_lock(&loop->cf_mutex); - if (!QUEUE_EMPTY(&loop->cf_signals)) { - QUEUE* split_pos = QUEUE_HEAD(&loop->cf_signals); - QUEUE_SPLIT(&loop->cf_signals, split_pos, &split_head); - } - uv_mutex_unlock(&loop->cf_mutex); - - while (!QUEUE_EMPTY(&split_head)) { - item = QUEUE_HEAD(&split_head); - - s = QUEUE_DATA(item, uv__cf_loop_signal_t, member); - - /* This was a termination signal */ - if (s->handle == NULL) - pCFRunLoopStop(state->loop); - else - uv__fsevents_reschedule(s->handle); - - QUEUE_REMOVE(item); - free(s); - } -} - - -/* Runs in UV loop to notify CF thread */ -int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__cf_loop_signal_t* item; - uv__cf_loop_state_t* state; - - item = malloc(sizeof(*item)); - if (item == NULL) - return -ENOMEM; - - item->handle = handle; - - uv_mutex_lock(&loop->cf_mutex); - QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member); - uv_mutex_unlock(&loop->cf_mutex); - - state = loop->cf_state; - assert(state != NULL); - pCFRunLoopSourceSignal(state->signal_source); - pCFRunLoopWakeUp(state->loop); - - return 0; -} - - -/* Runs in UV loop to initialize handle */ -int uv__fsevents_init(uv_fs_event_t* handle) { - int err; - uv__cf_loop_state_t* state; - - err = uv__fsevents_loop_init(handle->loop); - if (err) - return err; - - /* Get absolute path to file */ - handle->realpath = realpath(handle->filename, NULL); - if (handle->realpath == NULL) - return -errno; - handle->realpath_len = strlen(handle->realpath); - - /* Initialize event queue */ - QUEUE_INIT(&handle->cf_events); - handle->cf_error = 0; - - /* - * Events will occur in other thread. - * Initialize callback for getting them back into event loop's thread - */ - handle->cf_cb = malloc(sizeof(*handle->cf_cb)); - if (handle->cf_cb == NULL) { - err = -ENOMEM; - goto fail_cf_cb_malloc; - } - - handle->cf_cb->data = handle; - uv_async_init(handle->loop, handle->cf_cb, uv__fsevents_cb); - handle->cf_cb->flags |= UV__HANDLE_INTERNAL; - uv_unref((uv_handle_t*) handle->cf_cb); - - err = uv_mutex_init(&handle->cf_mutex); - if (err) - goto fail_cf_mutex_init; - - /* Insert handle into the list */ - state = handle->loop->cf_state; - uv_mutex_lock(&state->fsevent_mutex); - QUEUE_INSERT_TAIL(&state->fsevent_handles, &handle->cf_member); - state->fsevent_handle_count++; - state->fsevent_need_reschedule = 1; - uv_mutex_unlock(&state->fsevent_mutex); - - /* Reschedule FSEventStream */ - assert(handle != NULL); - err = uv__cf_loop_signal(handle->loop, handle); - if (err) - goto fail_loop_signal; - - return 0; - -fail_loop_signal: - uv_mutex_destroy(&handle->cf_mutex); - -fail_cf_mutex_init: - free(handle->cf_cb); - handle->cf_cb = NULL; - -fail_cf_cb_malloc: - free(handle->realpath); - handle->realpath = NULL; - handle->realpath_len = 0; - - return err; -} - - -/* Runs in UV loop to de-initialize handle */ -int uv__fsevents_close(uv_fs_event_t* handle) { - int err; - uv__cf_loop_state_t* state; - - if (handle->cf_cb == NULL) - return -EINVAL; - - /* Remove handle from the list */ - state = handle->loop->cf_state; - uv_mutex_lock(&state->fsevent_mutex); - QUEUE_REMOVE(&handle->cf_member); - state->fsevent_handle_count--; - state->fsevent_need_reschedule = 1; - uv_mutex_unlock(&state->fsevent_mutex); - - /* Reschedule FSEventStream */ - assert(handle != NULL); - err = uv__cf_loop_signal(handle->loop, handle); - if (err) - return -err; - - /* Wait for deinitialization */ - uv_sem_wait(&state->fsevent_sem); - - uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free); - handle->cf_cb = NULL; - - /* Free data in queue */ - UV__FSEVENTS_PROCESS(handle, { - /* NOP */ - }); - - uv_mutex_destroy(&handle->cf_mutex); - free(handle->realpath); - handle->realpath = NULL; - handle->realpath_len = 0; - - return 0; -} - -#endif /* TARGET_OS_IPHONE */ diff --git a/third-party/libuv/src/unix/getaddrinfo.c b/third-party/libuv/src/unix/getaddrinfo.c deleted file mode 100644 index 1db00680d1..0000000000 --- a/third-party/libuv/src/unix/getaddrinfo.c +++ /dev/null @@ -1,135 +0,0 @@ -/* 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 - * 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 <errno.h> -#include <stddef.h> /* NULL */ -#include <stdlib.h> -#include <string.h> - - -static void uv__getaddrinfo_work(struct uv__work* w) { - uv_getaddrinfo_t* req; - int err; - - req = container_of(w, uv_getaddrinfo_t, work_req); - err = getaddrinfo(req->hostname, req->service, req->hints, &req->res); - req->retcode = uv__getaddrinfo_translate_error(err); -} - - -static void uv__getaddrinfo_done(struct uv__work* w, int status) { - uv_getaddrinfo_t* req; - struct addrinfo *res; - - req = container_of(w, uv_getaddrinfo_t, work_req); - uv__req_unregister(req->loop, req); - - res = req->res; - req->res = NULL; - - /* See initialization in uv_getaddrinfo(). */ - if (req->hints) - free(req->hints); - else if (req->service) - free(req->service); - else if (req->hostname) - free(req->hostname); - else - assert(0); - - req->hints = NULL; - req->service = NULL; - req->hostname = NULL; - - if (status == -ECANCELED) { - assert(req->retcode == 0); - req->retcode = UV_EAI_CANCELED; - } - - req->cb(req, req->retcode, res); -} - - -int uv_getaddrinfo(uv_loop_t* loop, - uv_getaddrinfo_t* req, - uv_getaddrinfo_cb cb, - const char* hostname, - const char* service, - const struct addrinfo* hints) { - size_t hostname_len; - size_t service_len; - size_t hints_len; - size_t len; - char* buf; - - if (req == NULL || cb == NULL || (hostname == NULL && service == NULL)) - return -EINVAL; - - hostname_len = hostname ? strlen(hostname) + 1 : 0; - service_len = service ? strlen(service) + 1 : 0; - hints_len = hints ? sizeof(*hints) : 0; - buf = malloc(hostname_len + service_len + hints_len); - - if (buf == NULL) - return -ENOMEM; - - uv__req_init(loop, req, UV_GETADDRINFO); - req->loop = loop; - req->cb = cb; - req->res = NULL; - req->hints = NULL; - req->service = NULL; - req->hostname = NULL; - req->retcode = 0; - - /* order matters, see uv_getaddrinfo_done() */ - len = 0; - - if (hints) { - req->hints = memcpy(buf + len, hints, sizeof(*hints)); - len += sizeof(*hints); - } - - if (service) { - req->service = memcpy(buf + len, service, service_len); - len += service_len; - } - - if (hostname) { - req->hostname = memcpy(buf + len, hostname, hostname_len); - len += hostname_len; - } - - uv__work_submit(loop, - &req->work_req, - uv__getaddrinfo_work, - uv__getaddrinfo_done); - - return 0; -} - - -void uv_freeaddrinfo(struct addrinfo* ai) { - if (ai) - freeaddrinfo(ai); -} diff --git a/third-party/libuv/src/unix/internal.h b/third-party/libuv/src/unix/internal.h deleted file mode 100644 index 0ea82b51a0..0000000000 --- a/third-party/libuv/src/unix/internal.h +++ /dev/null @@ -1,296 +0,0 @@ -/* 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 - * 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. - */ - -#ifndef UV_UNIX_INTERNAL_H_ -#define UV_UNIX_INTERNAL_H_ - -#include "uv-common.h" - -#include <assert.h> -#include <stdlib.h> /* abort */ -#include <string.h> /* strrchr */ - -#if defined(__STRICT_ANSI__) -# define inline __inline -#endif - -#if defined(__linux__) -# include "linux-syscalls.h" -#endif /* __linux__ */ - -#if defined(__sun) -# include <sys/port.h> -# include <port.h> -#endif /* __sun */ - -#if defined(__APPLE__) && !TARGET_OS_IPHONE -# include <CoreServices/CoreServices.h> -#endif - -#define STATIC_ASSERT(expr) \ - void uv__static_assert(int static_assert_failed[1 - 2 * !(expr)]) - -#define ACCESS_ONCE(type, var) \ - (*(volatile type*) &(var)) - -#define UNREACHABLE() \ - do { \ - assert(0 && "unreachable code"); \ - abort(); \ - } \ - while (0) - -#define SAVE_ERRNO(block) \ - do { \ - int _saved_errno = errno; \ - do { block; } while (0); \ - errno = _saved_errno; \ - } \ - while (0) - -/* The __clang__ and __INTEL_COMPILER checks are superfluous because they - * define __GNUC__. They are here to convey to you, dear reader, that these - * macros are enabled when compiling with clang or icc. - */ -#if defined(__clang__) || \ - defined(__GNUC__) || \ - defined(__INTEL_COMPILER) || \ - defined(__SUNPRO_C) -# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration -# define UV_UNUSED(declaration) __attribute__((unused)) declaration -#else -# define UV_DESTRUCTOR(declaration) declaration -# define UV_UNUSED(declaration) declaration -#endif - -#if defined(__linux__) -# define UV__POLLIN UV__EPOLLIN -# define UV__POLLOUT UV__EPOLLOUT -# define UV__POLLERR UV__EPOLLERR -# define UV__POLLHUP UV__EPOLLHUP -#endif - -#if defined(__sun) -# define UV__POLLIN POLLIN -# define UV__POLLOUT POLLOUT -# define UV__POLLERR POLLERR -# define UV__POLLHUP POLLHUP -#endif - -#ifndef UV__POLLIN -# define UV__POLLIN 1 -#endif - -#ifndef UV__POLLOUT -# define UV__POLLOUT 2 -#endif - -#ifndef UV__POLLERR -# define UV__POLLERR 4 -#endif - -#ifndef UV__POLLHUP -# define UV__POLLHUP 8 -#endif - -/* handle flags */ -enum { - UV_CLOSING = 0x01, /* uv_close() called but not finished. */ - UV_CLOSED = 0x02, /* close(2) finished. */ - UV_STREAM_READING = 0x04, /* uv_read_start() called. */ - UV_STREAM_SHUTTING = 0x08, /* uv_shutdown() called but not complete. */ - UV_STREAM_SHUT = 0x10, /* Write side closed. */ - UV_STREAM_READABLE = 0x20, /* The stream is readable */ - UV_STREAM_WRITABLE = 0x40, /* The stream is writable */ - UV_STREAM_BLOCKING = 0x80, /* Synchronous writes. */ - UV_STREAM_READ_PARTIAL = 0x100, /* read(2) read less than requested. */ - UV_STREAM_READ_EOF = 0x200, /* read(2) read EOF. */ - UV_TCP_NODELAY = 0x400, /* Disable Nagle. */ - UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */ - UV_TCP_SINGLE_ACCEPT = 0x1000 /* Only accept() when idle. */ -}; - -typedef enum { - UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */ - UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */ -} uv_clocktype_t; - -/* core */ -int uv__nonblock(int fd, int set); -int uv__close(int fd); -int uv__cloexec(int fd, int set); -int uv__socket(int domain, int type, int protocol); -int uv__dup(int fd); -ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags); -void uv__make_close_pending(uv_handle_t* handle); - -void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd); -void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events); -void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events); -void uv__io_close(uv_loop_t* loop, uv__io_t* w); -void uv__io_feed(uv_loop_t* loop, uv__io_t* w); -int uv__io_active(const uv__io_t* w, unsigned int events); -void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ - -/* async */ -void uv__async_send(struct uv__async* wa); -void uv__async_init(struct uv__async* wa); -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb); -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa); - -/* loop */ -void uv__run_idle(uv_loop_t* loop); -void uv__run_check(uv_loop_t* loop); -void uv__run_prepare(uv_loop_t* loop); - -/* stream */ -void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream, - uv_handle_type type); -int uv__stream_open(uv_stream_t*, int fd, int flags); -void uv__stream_destroy(uv_stream_t* stream); -#if defined(__APPLE__) -int uv__stream_try_select(uv_stream_t* stream, int* fd); -#endif /* defined(__APPLE__) */ -void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events); -int uv__accept(int sockfd); - -/* tcp */ -int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb); -int uv__tcp_nodelay(int fd, int on); -int uv__tcp_keepalive(int fd, int on, unsigned int delay); - -/* pipe */ -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); - -/* timer */ -void uv__run_timers(uv_loop_t* loop); -int uv__next_timeout(const uv_loop_t* loop); - -/* signal */ -void uv__signal_close(uv_signal_t* handle); -void uv__signal_global_once_init(void); -void uv__signal_loop_cleanup(uv_loop_t* loop); - -/* thread pool */ -void uv__work_submit(uv_loop_t* loop, - struct uv__work *w, - void (*work)(struct uv__work *w), - void (*done)(struct uv__work *w, int status)); -void uv__work_done(uv_async_t* handle, int status); - -/* platform specific */ -uint64_t uv__hrtime(uv_clocktype_t type); -int uv__kqueue_init(uv_loop_t* loop); -int uv__platform_loop_init(uv_loop_t* loop, int default_loop); -void uv__platform_loop_delete(uv_loop_t* loop); -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd); - -/* various */ -void uv__async_close(uv_async_t* handle); -void uv__check_close(uv_check_t* handle); -void uv__fs_event_close(uv_fs_event_t* handle); -void uv__idle_close(uv_idle_t* handle); -void uv__pipe_close(uv_pipe_t* handle); -void uv__poll_close(uv_poll_t* handle); -void uv__prepare_close(uv_prepare_t* handle); -void uv__process_close(uv_process_t* handle); -void uv__stream_close(uv_stream_t* handle); -void uv__tcp_close(uv_tcp_t* handle); -void uv__timer_close(uv_timer_t* handle); -void uv__udp_close(uv_udp_t* handle); -void uv__udp_finish_close(uv_udp_t* handle); - -#if defined(__APPLE__) -int uv___stream_fd(uv_stream_t* handle); -#define uv__stream_fd(handle) (uv___stream_fd((uv_stream_t*) (handle))) -#else -#define uv__stream_fd(handle) ((handle)->io_watcher.fd) -#endif /* defined(__APPLE__) */ - -#ifdef UV__O_NONBLOCK -# define UV__F_NONBLOCK UV__O_NONBLOCK -#else -# define UV__F_NONBLOCK 1 -#endif - -int uv__make_socketpair(int fds[2], int flags); -int uv__make_pipe(int fds[2], int flags); - -#if defined(__APPLE__) - -int uv__fsevents_init(uv_fs_event_t* handle); -int uv__fsevents_close(uv_fs_event_t* handle); -void uv__fsevents_loop_delete(uv_loop_t* loop); - -/* OSX < 10.7 has no file events, polyfill them */ -#ifndef MAC_OS_X_VERSION_10_7 - -static const int kFSEventStreamCreateFlagFileEvents = 0x00000010; -static const int kFSEventStreamEventFlagItemCreated = 0x00000100; -static const int kFSEventStreamEventFlagItemRemoved = 0x00000200; -static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400; -static const int kFSEventStreamEventFlagItemRenamed = 0x00000800; -static const int kFSEventStreamEventFlagItemModified = 0x00001000; -static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000; -static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000; -static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000; -static const int kFSEventStreamEventFlagItemIsFile = 0x00010000; -static const int kFSEventStreamEventFlagItemIsDir = 0x00020000; -static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000; - -#endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */ - -#endif /* defined(__APPLE__) */ - -UV_UNUSED(static void uv__req_init(uv_loop_t* loop, - uv_req_t* req, - uv_req_type type)) { - req->type = type; - uv__req_register(loop, req); -} -#define uv__req_init(loop, req, type) \ - uv__req_init((loop), (uv_req_t*)(req), (type)) - -UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { - /* Use a fast time source if available. We only need millisecond precision. - */ - loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000; -} - -UV_UNUSED(static char* uv__basename_r(const char* path)) { - char* s; - - s = strrchr(path, '/'); - if (s == NULL) - return (char*) path; - - return s + 1; -} - - -#ifdef HAVE_DTRACE -#include "uv-dtrace.h" -#else -#define UV_TICK_START(arg0, arg1) -#define UV_TICK_STOP(arg0, arg1) -#endif - -#endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/third-party/libuv/src/unix/kqueue.c b/third-party/libuv/src/unix/kqueue.c deleted file mode 100644 index f86f291fc0..0000000000 --- a/third-party/libuv/src/unix/kqueue.c +++ /dev/null @@ -1,403 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include <sys/sysctl.h> -#include <sys/types.h> -#include <sys/event.h> -#include <sys/time.h> -#include <unistd.h> -#include <fcntl.h> -#include <time.h> - -static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags); - - -int uv__kqueue_init(uv_loop_t* loop) { - loop->backend_fd = kqueue(); - if (loop->backend_fd == -1) - return -errno; - - uv__cloexec(loop->backend_fd, 1); - - return 0; -} - - -void uv__io_poll(uv_loop_t* loop, int timeout) { - struct kevent events[1024]; - struct kevent* ev; - struct timespec spec; - unsigned int nevents; - unsigned int revents; - QUEUE* q; - uint64_t base; - uint64_t diff; - uv__io_t* w; - int filter; - int fflags; - int count; - int nfds; - int fd; - int op; - int i; - - if (loop->nfds == 0) { - assert(QUEUE_EMPTY(&loop->watcher_queue)); - return; - } - - nevents = 0; - - while (!QUEUE_EMPTY(&loop->watcher_queue)) { - q = QUEUE_HEAD(&loop->watcher_queue); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - w = QUEUE_DATA(q, uv__io_t, watcher_queue); - assert(w->pevents != 0); - assert(w->fd >= 0); - assert(w->fd < (int) loop->nwatchers); - - if ((w->events & UV__POLLIN) == 0 && (w->pevents & UV__POLLIN) != 0) { - filter = EVFILT_READ; - fflags = 0; - op = EV_ADD; - - if (w->cb == uv__fs_event) { - filter = EVFILT_VNODE; - fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME - | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE; - op = EV_ADD | EV_ONESHOT; /* Stop the event from firing repeatedly. */ - } - - EV_SET(events + nevents, w->fd, filter, op, fflags, 0, 0); - - if (++nevents == ARRAY_SIZE(events)) { - if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) - abort(); - nevents = 0; - } - } - - if ((w->events & UV__POLLOUT) == 0 && (w->pevents & UV__POLLOUT) != 0) { - EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0); - - if (++nevents == ARRAY_SIZE(events)) { - if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) - abort(); - nevents = 0; - } - } - - w->events = w->pevents; - } - - assert(timeout >= -1); - base = loop->time; - count = 48; /* Benchmarks suggest this gives the best throughput. */ - - for (;; nevents = 0) { - if (timeout != -1) { - spec.tv_sec = timeout / 1000; - spec.tv_nsec = (timeout % 1000) * 1000000; - } - - nfds = kevent(loop->backend_fd, - events, - nevents, - events, - ARRAY_SIZE(events), - timeout == -1 ? NULL : &spec); - - /* Update loop->time unconditionally. It's tempting to skip the update when - * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the - * operating system didn't reschedule our process while in the syscall. - */ - SAVE_ERRNO(uv__update_time(loop)); - - if (nfds == 0) { - assert(timeout != -1); - return; - } - - if (nfds == -1) { - if (errno != EINTR) - abort(); - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - - /* Interrupted by a signal. Update timeout and poll again. */ - goto update_timeout; - } - - nevents = 0; - - assert(loop->watchers != NULL); - loop->watchers[loop->nwatchers] = (void*) events; - loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; - for (i = 0; i < nfds; i++) { - ev = events + i; - fd = ev->ident; - /* Skip invalidated events, see uv__platform_invalidate_fd */ - if (fd == -1) - continue; - w = loop->watchers[fd]; - - if (w == NULL) { - /* File descriptor that we've stopped watching, disarm it. */ - /* TODO batch up */ - struct kevent events[1]; - - EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); - if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) - if (errno != EBADF && errno != ENOENT) - abort(); - - continue; - } - - if (ev->filter == EVFILT_VNODE) { - assert(w->events == UV__POLLIN); - assert(w->pevents == UV__POLLIN); - w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */ - nevents++; - continue; - } - - revents = 0; - - if (ev->filter == EVFILT_READ) { - if (w->pevents & UV__POLLIN) { - revents |= UV__POLLIN; - w->rcount = ev->data; - } else { - /* TODO batch up */ - struct kevent events[1]; - EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); - if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) - if (errno != ENOENT) - abort(); - } - } - - if (ev->filter == EVFILT_WRITE) { - if (w->pevents & UV__POLLOUT) { - revents |= UV__POLLOUT; - w->wcount = ev->data; - } else { - /* TODO batch up */ - struct kevent events[1]; - EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); - if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) - if (errno != ENOENT) - abort(); - } - } - - if (ev->flags & EV_ERROR) - revents |= UV__POLLERR; - - if (revents == 0) - continue; - - w->cb(loop, w, revents); - nevents++; - } - loop->watchers[loop->nwatchers] = NULL; - loop->watchers[loop->nwatchers + 1] = NULL; - - if (nevents != 0) { - if (nfds == ARRAY_SIZE(events) && --count != 0) { - /* Poll for more events but don't block this time. */ - timeout = 0; - continue; - } - return; - } - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - -update_timeout: - assert(timeout > 0); - - diff = loop->time - base; - if (diff >= (uint64_t) timeout) - return; - - timeout -= diff; - } -} - - -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { - struct kevent* events; - uintptr_t i; - uintptr_t nfds; - - assert(loop->watchers != NULL); - - events = (struct kevent*) loop->watchers[loop->nwatchers]; - nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; - if (events == NULL) - return; - - /* Invalidate events with same file descriptor */ - for (i = 0; i < nfds; i++) - if ((int) events[i].ident == fd) - events[i].ident = -1; -} - - -static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) { - uv_fs_event_t* handle; - struct kevent ev; - int events; - const char* path; -#if defined(F_GETPATH) - /* MAXPATHLEN == PATH_MAX but the former is what XNU calls it internally. */ - char pathbuf[MAXPATHLEN]; -#endif - - handle = container_of(w, uv_fs_event_t, event_watcher); - - if (fflags & (NOTE_ATTRIB | NOTE_EXTEND)) - events = UV_CHANGE; - else - events = UV_RENAME; - - path = NULL; -#if defined(F_GETPATH) - /* Also works when the file has been unlinked from the file system. Passing - * in the path when the file has been deleted is arguably a little strange - * but it's consistent with what the inotify backend does. - */ - if (fcntl(handle->event_watcher.fd, F_GETPATH, pathbuf) == 0) - path = uv__basename_r(pathbuf); -#endif - handle->cb(handle, path, events, 0); - - if (handle->event_watcher.fd == -1) - return; - - /* Watcher operates in one-shot mode, re-arm it. */ - fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME - | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE; - - EV_SET(&ev, w->fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, fflags, 0, 0); - - if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL)) - abort(); -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); - return 0; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* filename, - unsigned int flags) { -#if defined(__APPLE__) - struct stat statbuf; -#endif /* defined(__APPLE__) */ - int fd; - - if (uv__is_active(handle)) - return -EINVAL; - - /* TODO open asynchronously - but how do we report back errors? */ - fd = open(filename, O_RDONLY); - if (fd == -1) - return -errno; - - uv__handle_start(handle); - uv__io_init(&handle->event_watcher, uv__fs_event, fd); - handle->filename = strdup(filename); - handle->cb = cb; - -#if defined(__APPLE__) - /* Nullify field to perform checks later */ - handle->cf_cb = NULL; - handle->realpath = NULL; - handle->realpath_len = 0; - handle->cf_flags = flags; - - if (fstat(fd, &statbuf)) - goto fallback; - /* FSEvents works only with directories */ - if (!(statbuf.st_mode & S_IFDIR)) - goto fallback; - - return uv__fsevents_init(handle); - -fallback: -#endif /* defined(__APPLE__) */ - - uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN); - - return 0; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - if (!uv__is_active(handle)) - return -EINVAL; - - uv__handle_stop(handle); - -#if defined(__APPLE__) - if (uv__fsevents_close(handle)) - uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN); -#else - uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN); -#endif /* defined(__APPLE__) */ - - free(handle->filename); - handle->filename = NULL; - - uv__close(handle->event_watcher.fd); - handle->event_watcher.fd = -1; - - return 0; -} - - -void uv__fs_event_close(uv_fs_event_t* handle) { - uv_fs_event_stop(handle); -} diff --git a/third-party/libuv/src/unix/linux-core.c b/third-party/libuv/src/unix/linux-core.c deleted file mode 100644 index f71dd2d6b9..0000000000 --- a/third-party/libuv/src/unix/linux-core.c +++ /dev/null @@ -1,816 +0,0 @@ -/* 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 - * 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 <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <errno.h> - -#include <net/if.h> -#include <sys/param.h> -#include <sys/prctl.h> -#include <sys/sysinfo.h> -#include <unistd.h> -#include <fcntl.h> -#include <time.h> - -#ifndef __ANDROID__ -#define HAVE_IFADDRS_H 1 -#endif - -#ifdef __UCLIBC__ -# if __UCLIBC_MAJOR__ < 0 || __UCLIBC_MINOR__ < 9 || __UCLIBC_SUBLEVEL__ < 32 -# undef HAVE_IFADDRS_H -# endif -#endif -#ifdef HAVE_IFADDRS_H -# include <ifaddrs.h> -# include <sys/socket.h> -# include <net/ethernet.h> -# include <linux/if_packet.h> -#endif - -/* Available from 2.6.32 onwards. */ -#ifndef CLOCK_MONOTONIC_COARSE -# define CLOCK_MONOTONIC_COARSE 6 -#endif - -/* This is rather annoying: CLOCK_BOOTTIME lives in <linux/time.h> but we can't - * include that file because it conflicts with <time.h>. We'll just have to - * define it ourselves. - */ -#ifndef CLOCK_BOOTTIME -# define CLOCK_BOOTTIME 7 -#endif - -static int read_models(unsigned int numcpus, uv_cpu_info_t* ci); -static int read_times(unsigned int numcpus, uv_cpu_info_t* ci); -static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci); -static unsigned long read_cpufreq(unsigned int cpunum); - - -int uv__platform_loop_init(uv_loop_t* loop, int default_loop) { - int fd; - - fd = uv__epoll_create1(UV__EPOLL_CLOEXEC); - - /* epoll_create1() can fail either because it's not implemented (old kernel) - * or because it doesn't understand the EPOLL_CLOEXEC flag. - */ - if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) { - fd = uv__epoll_create(256); - - if (fd != -1) - uv__cloexec(fd, 1); - } - - loop->backend_fd = fd; - loop->inotify_fd = -1; - loop->inotify_watchers = NULL; - - if (fd == -1) - return -errno; - - return 0; -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { - if (loop->inotify_fd == -1) return; - uv__io_stop(loop, &loop->inotify_read_watcher, UV__POLLIN); - uv__close(loop->inotify_fd); - loop->inotify_fd = -1; -} - - -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { - struct uv__epoll_event* events; - uintptr_t i; - uintptr_t nfds; - - assert(loop->watchers != NULL); - - events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers]; - nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; - if (events == NULL) - return; - - /* Invalidate events with same file descriptor */ - for (i = 0; i < nfds; i++) - if ((int) events[i].data == fd) - events[i].data = -1; -} - - -void uv__io_poll(uv_loop_t* loop, int timeout) { - struct uv__epoll_event events[1024]; - struct uv__epoll_event* pe; - struct uv__epoll_event e; - QUEUE* q; - uv__io_t* w; - uint64_t base; - uint64_t diff; - int nevents; - int count; - int nfds; - int fd; - int op; - int i; - - if (loop->nfds == 0) { - assert(QUEUE_EMPTY(&loop->watcher_queue)); - return; - } - - while (!QUEUE_EMPTY(&loop->watcher_queue)) { - q = QUEUE_HEAD(&loop->watcher_queue); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - w = QUEUE_DATA(q, uv__io_t, watcher_queue); - assert(w->pevents != 0); - assert(w->fd >= 0); - assert(w->fd < (int) loop->nwatchers); - - e.events = w->pevents; - e.data = w->fd; - - if (w->events == 0) - op = UV__EPOLL_CTL_ADD; - else - op = UV__EPOLL_CTL_MOD; - - /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching - * events, skip the syscall and squelch the events after epoll_wait(). - */ - if (uv__epoll_ctl(loop->backend_fd, op, w->fd, &e)) { - if (errno != EEXIST) - abort(); - - assert(op == UV__EPOLL_CTL_ADD); - - /* We've reactivated a file descriptor that's been watched before. */ - if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_MOD, w->fd, &e)) - abort(); - } - - w->events = w->pevents; - } - - assert(timeout >= -1); - base = loop->time; - count = 48; /* Benchmarks suggest this gives the best throughput. */ - - for (;;) { - nfds = uv__epoll_wait(loop->backend_fd, - events, - ARRAY_SIZE(events), - timeout); - - /* Update loop->time unconditionally. It's tempting to skip the update when - * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the - * operating system didn't reschedule our process while in the syscall. - */ - SAVE_ERRNO(uv__update_time(loop)); - - if (nfds == 0) { - assert(timeout != -1); - return; - } - - if (nfds == -1) { - if (errno != EINTR) - abort(); - - if (timeout == -1) - continue; - - if (timeout == 0) - return; - - /* Interrupted by a signal. Update timeout and poll again. */ - goto update_timeout; - } - - nevents = 0; - - assert(loop->watchers != NULL); - loop->watchers[loop->nwatchers] = (void*) events; - loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; - for (i = 0; i < nfds; i++) { - pe = events + i; - fd = pe->data; - - /* Skip invalidated events, see uv__platform_invalidate_fd */ - if (fd == -1) - continue; - - assert(fd >= 0); - assert((unsigned) fd < loop->nwatchers); - - w = loop->watchers[fd]; - - if (w == NULL) { - /* File descriptor that we've stopped watching, disarm it. - * - * Ignore all errors because we may be racing with another thread - * when the file descriptor is closed. - */ - uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, pe); - continue; - } - - /* Give users only events they're interested in. Prevents spurious - * callbacks when previous callback invocation in this loop has stopped - * the current watcher. Also, filters out events that users has not - * requested us to watch. - */ - pe->events &= w->pevents | UV__POLLERR | UV__POLLHUP; - - /* Work around an epoll quirk where it sometimes reports just the - * EPOLLERR or EPOLLHUP event. In order to force the event loop to - * move forward, we merge in the read/write events that the watcher - * is interested in; uv__read() and uv__write() will then deal with - * the error or hangup in the usual fashion. - * - * Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user - * reads the available data, calls uv_read_stop(), then sometime later - * calls uv_read_start() again. By then, libuv has forgotten about the - * hangup and the kernel won't report EPOLLIN again because there's - * nothing left to read. If anything, libuv is to blame here. The - * current hack is just a quick bandaid; to properly fix it, libuv - * needs to remember the error/hangup event. We should get that for - * free when we switch over to edge-triggered I/O. - */ - if (pe->events == UV__EPOLLERR || pe->events == UV__EPOLLHUP) - pe->events |= w->pevents & (UV__EPOLLIN | UV__EPOLLOUT); - - if (pe->events != 0) { - w->cb(loop, w, pe->events); - nevents++; - } - } - loop->watchers[loop->nwatchers] = NULL; - loop->watchers[loop->nwatchers + 1] = NULL; - - if (nevents != 0) { - if (nfds == ARRAY_SIZE(events) && --count != 0) { - /* Poll for more events but don't block this time. */ - timeout = 0; - continue; - } - return; - } - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - -update_timeout: - assert(timeout > 0); - - diff = loop->time - base; - if (diff >= (uint64_t) timeout) - return; - - timeout -= diff; - } -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - static clock_t fast_clock_id = -1; - struct timespec t; - clock_t clock_id; - - /* Prefer CLOCK_MONOTONIC_COARSE if available but only when it has - * millisecond granularity or better. CLOCK_MONOTONIC_COARSE is - * serviced entirely from the vDSO, whereas CLOCK_MONOTONIC may - * decide to make a costly system call. - */ - /* TODO(bnoordhuis) Use CLOCK_MONOTONIC_COARSE for UV_CLOCK_PRECISE - * when it has microsecond granularity or better (unlikely). - */ - if (type == UV_CLOCK_FAST && fast_clock_id == -1) { - if (clock_getres(CLOCK_MONOTONIC_COARSE, &t) == 0 && - t.tv_nsec <= 1 * 1000 * 1000) { - fast_clock_id = CLOCK_MONOTONIC_COARSE; - } else { - fast_clock_id = CLOCK_MONOTONIC; - } - } - - clock_id = CLOCK_MONOTONIC; - if (type == UV_CLOCK_FAST) - clock_id = fast_clock_id; - - if (clock_gettime(clock_id, &t)) - return 0; /* Not really possible. */ - - return t.tv_sec * (uint64_t) 1e9 + t.tv_nsec; -} - - -void uv_loadavg(double avg[3]) { - struct sysinfo info; - - if (sysinfo(&info) < 0) return; - - avg[0] = (double) info.loads[0] / 65536.0; - avg[1] = (double) info.loads[1] / 65536.0; - avg[2] = (double) info.loads[2] / 65536.0; -} - - -int uv_exepath(char* buffer, size_t* size) { - ssize_t n; - - if (buffer == NULL || size == NULL) - return -EINVAL; - - n = readlink("/proc/self/exe", buffer, *size - 1); - if (n == -1) - return -errno; - - buffer[n] = '\0'; - *size = n; - - return 0; -} - - -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); -} - - -int uv_resident_set_memory(size_t* rss) { - char buf[1024]; - const char* s; - ssize_t n; - long val; - int fd; - int i; - - do - fd = open("/proc/self/stat", O_RDONLY); - while (fd == -1 && errno == EINTR); - - if (fd == -1) - return -errno; - - do - n = read(fd, buf, sizeof(buf) - 1); - while (n == -1 && errno == EINTR); - - uv__close(fd); - if (n == -1) - return -errno; - buf[n] = '\0'; - - s = strchr(buf, ' '); - if (s == NULL) - goto err; - - s += 1; - if (*s != '(') - goto err; - - s = strchr(s, ')'); - if (s == NULL) - goto err; - - for (i = 1; i <= 22; i++) { - s = strchr(s + 1, ' '); - if (s == NULL) - goto err; - } - - errno = 0; - val = strtol(s, NULL, 10); - if (errno != 0) - goto err; - if (val < 0) - goto err; - - *rss = val * getpagesize(); - return 0; - -err: - return -EINVAL; -} - - -int uv_uptime(double* uptime) { - static volatile int no_clock_boottime; - struct timespec now; - int r; - - /* Try CLOCK_BOOTTIME first, fall back to CLOCK_MONOTONIC if not available - * (pre-2.6.39 kernels). CLOCK_MONOTONIC doesn't increase when the system - * is suspended. - */ - if (no_clock_boottime) { - retry: r = clock_gettime(CLOCK_MONOTONIC, &now); - } - else if ((r = clock_gettime(CLOCK_BOOTTIME, &now)) && errno == EINVAL) { - no_clock_boottime = 1; - goto retry; - } - - if (r) - return -errno; - - *uptime = now.tv_sec; - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int numcpus; - uv_cpu_info_t* ci; - int err; - - *cpu_infos = NULL; - *count = 0; - - numcpus = sysconf(_SC_NPROCESSORS_ONLN); - assert(numcpus != (unsigned int) -1); - assert(numcpus != 0); - - ci = calloc(numcpus, sizeof(*ci)); - if (ci == NULL) - return -ENOMEM; - - err = read_models(numcpus, ci); - if (err == 0) - err = read_times(numcpus, ci); - - if (err) { - uv_free_cpu_info(ci, numcpus); - return err; - } - - /* read_models() on x86 also reads the CPU speed from /proc/cpuinfo. - * We don't check for errors here. Worst case, the field is left zero. - */ - if (ci[0].speed == 0) - read_speeds(numcpus, ci); - - *cpu_infos = ci; - *count = numcpus; - - return 0; -} - - -static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) { - unsigned int num; - - for (num = 0; num < numcpus; num++) - ci[num].speed = read_cpufreq(num) / 1000; -} - - -/* Also reads the CPU frequency on x86. The other architectures only have - * a BogoMIPS field, which may not be very accurate. - * - * Note: Simply returns on error, uv_cpu_info() takes care of the cleanup. - */ -static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { - static const char model_marker[] = "model name\t: "; - static const char speed_marker[] = "cpu MHz\t\t: "; - const char* inferred_model; - unsigned int model_idx; - unsigned int speed_idx; - char buf[1024]; - char* model; - FILE* fp; - - /* Most are unused on non-ARM, non-MIPS and non-x86 architectures. */ - (void) &model_marker; - (void) &speed_marker; - (void) &speed_idx; - (void) &model; - (void) &buf; - (void) &fp; - - model_idx = 0; - speed_idx = 0; - -#if defined(__arm__) || \ - defined(__i386__) || \ - defined(__mips__) || \ - defined(__x86_64__) - fp = fopen("/proc/cpuinfo", "r"); - if (fp == NULL) - return -errno; - - while (fgets(buf, sizeof(buf), fp)) { - if (model_idx < numcpus) { - if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) { - model = buf + sizeof(model_marker) - 1; - model = strndup(model, strlen(model) - 1); /* Strip newline. */ - if (model == NULL) { - fclose(fp); - return -ENOMEM; - } - ci[model_idx++].model = model; - continue; - } - } -#if defined(__arm__) || defined(__mips__) - if (model_idx < numcpus) { -#if defined(__arm__) - /* Fallback for pre-3.8 kernels. */ - static const char model_marker[] = "Processor\t: "; -#else /* defined(__mips__) */ - static const char model_marker[] = "cpu model\t\t: "; -#endif - if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) { - model = buf + sizeof(model_marker) - 1; - model = strndup(model, strlen(model) - 1); /* Strip newline. */ - if (model == NULL) { - fclose(fp); - return -ENOMEM; - } - ci[model_idx++].model = model; - continue; - } - } -#else /* !__arm__ && !__mips__ */ - if (speed_idx < numcpus) { - if (strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0) { - ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1); - continue; - } - } -#endif /* __arm__ || __mips__ */ - } - - fclose(fp); -#endif /* __arm__ || __i386__ || __mips__ || __x86_64__ */ - - /* Now we want to make sure that all the models contain *something* because - * it's not safe to leave them as null. Copy the last entry unless there - * isn't one, in that case we simply put "unknown" into everything. - */ - inferred_model = "unknown"; - if (model_idx > 0) - inferred_model = ci[model_idx - 1].model; - - while (model_idx < numcpus) { - model = strndup(inferred_model, strlen(inferred_model)); - if (model == NULL) - return -ENOMEM; - ci[model_idx++].model = model; - } - - return 0; -} - - -static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) { - unsigned long clock_ticks; - struct uv_cpu_times_s ts; - unsigned long user; - unsigned long nice; - unsigned long sys; - unsigned long idle; - unsigned long dummy; - unsigned long irq; - unsigned int num; - unsigned int len; - char buf[1024]; - FILE* fp; - - clock_ticks = sysconf(_SC_CLK_TCK); - assert(clock_ticks != (unsigned long) -1); - assert(clock_ticks != 0); - - fp = fopen("/proc/stat", "r"); - if (fp == NULL) - return -errno; - - if (!fgets(buf, sizeof(buf), fp)) - abort(); - - num = 0; - - while (fgets(buf, sizeof(buf), fp)) { - if (num >= numcpus) - break; - - if (strncmp(buf, "cpu", 3)) - break; - - /* skip "cpu<num> " marker */ - { - unsigned int n; - int r = sscanf(buf, "cpu%u ", &n); - assert(r == 1); - (void) r; /* silence build warning */ - for (len = sizeof("cpu0"); n /= 10; len++); - } - - /* Line contains user, nice, system, idle, iowait, irq, softirq, steal, - * guest, guest_nice but we're only interested in the first four + irq. - * - * Don't use %*s to skip fields or %ll to read straight into the uint64_t - * fields, they're not allowed in C89 mode. - */ - if (6 != sscanf(buf + len, - "%lu %lu %lu %lu %lu %lu", - &user, - &nice, - &sys, - &idle, - &dummy, - &irq)) - abort(); - - ts.user = clock_ticks * user; - ts.nice = clock_ticks * nice; - ts.sys = clock_ticks * sys; - ts.idle = clock_ticks * idle; - ts.irq = clock_ticks * irq; - ci[num++].cpu_times = ts; - } - fclose(fp); - assert(num == numcpus); - - return 0; -} - - -static unsigned long read_cpufreq(unsigned int cpunum) { - unsigned long val; - char buf[1024]; - FILE* fp; - - snprintf(buf, - sizeof(buf), - "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", - cpunum); - - fp = fopen(buf, "r"); - if (fp == NULL) - return 0; - - if (fscanf(fp, "%lu", &val) != 1) - val = 0; - - fclose(fp); - - return val; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - free(cpu_infos[i].model); - } - - free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { -#ifndef HAVE_IFADDRS_H - return -ENOSYS; -#else - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_ll *sll; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { - continue; - } - - (*count)++; - } - - *addresses = malloc(*count * sizeof(**addresses)); - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Linux getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == PF_PACKET) - continue; - - address->name = strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_PACKET)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sll = (struct sockaddr_ll*)ent->ifa_addr; - memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -#endif -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - free(addresses[i].name); - } - - free(addresses); -} - - -void uv__set_process_title(const char* title) { -#if defined(PR_SET_NAME) - prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */ -#endif -} diff --git a/third-party/libuv/src/unix/linux-inotify.c b/third-party/libuv/src/unix/linux-inotify.c deleted file mode 100644 index 7641f383c4..0000000000 --- a/third-party/libuv/src/unix/linux-inotify.c +++ /dev/null @@ -1,257 +0,0 @@ -/* 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 - * 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 "tree.h" -#include "internal.h" - -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <errno.h> - -#include <sys/types.h> -#include <unistd.h> - -struct watcher_list { - RB_ENTRY(watcher_list) entry; - QUEUE watchers; - char* path; - int wd; -}; - -struct watcher_root { - struct watcher_list* rbh_root; -}; -#define CAST(p) ((struct watcher_root*)(p)) - - -static int compare_watchers(const struct watcher_list* a, - const struct watcher_list* b) { - if (a->wd < b->wd) return -1; - if (a->wd > b->wd) return 1; - return 0; -} - - -RB_GENERATE_STATIC(watcher_root, watcher_list, entry, compare_watchers) - - -static void uv__inotify_read(uv_loop_t* loop, - uv__io_t* w, - unsigned int revents); - - -static int new_inotify_fd(void) { - int err; - int fd; - - fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC); - if (fd != -1) - return fd; - - if (errno != ENOSYS) - return -errno; - - fd = uv__inotify_init(); - if (fd == -1) - return -errno; - - err = uv__cloexec(fd, 1); - if (err == 0) - err = uv__nonblock(fd, 1); - - if (err) { - uv__close(fd); - return err; - } - - return fd; -} - - -static int init_inotify(uv_loop_t* loop) { - int err; - - if (loop->inotify_fd != -1) - return 0; - - err = new_inotify_fd(); - if (err < 0) - return err; - - loop->inotify_fd = err; - uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd); - uv__io_start(loop, &loop->inotify_read_watcher, UV__POLLIN); - - return 0; -} - - -static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) { - struct watcher_list w; - w.wd = wd; - return RB_FIND(watcher_root, CAST(&loop->inotify_watchers), &w); -} - - -static void uv__inotify_read(uv_loop_t* loop, - uv__io_t* dummy, - unsigned int events) { - const struct uv__inotify_event* e; - struct watcher_list* w; - uv_fs_event_t* h; - QUEUE* q; - const char* path; - ssize_t size; - const char *p; - /* needs to be large enough for sizeof(inotify_event) + strlen(filename) */ - char buf[4096]; - - while (1) { - do - size = read(loop->inotify_fd, buf, sizeof(buf)); - while (size == -1 && errno == EINTR); - - if (size == -1) { - assert(errno == EAGAIN || errno == EWOULDBLOCK); - break; - } - - assert(size > 0); /* pre-2.6.21 thing, size=0 == read buffer too small */ - - /* Now we have one or more inotify_event structs. */ - for (p = buf; p < buf + size; p += sizeof(*e) + e->len) { - e = (const struct uv__inotify_event*)p; - - events = 0; - if (e->mask & (UV__IN_ATTRIB|UV__IN_MODIFY)) - events |= UV_CHANGE; - if (e->mask & ~(UV__IN_ATTRIB|UV__IN_MODIFY)) - events |= UV_RENAME; - - w = find_watcher(loop, e->wd); - if (w == NULL) - continue; /* Stale event, no watchers left. */ - - /* inotify does not return the filename when monitoring a single file - * for modifications. Repurpose the filename for API compatibility. - * I'm not convinced this is a good thing, maybe it should go. - */ - path = e->len ? (const char*) (e + 1) : uv__basename_r(w->path); - - QUEUE_FOREACH(q, &w->watchers) { - h = QUEUE_DATA(q, uv_fs_event_t, watchers); - h->cb(h, path, events, 0); - } - } - } -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); - return 0; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* path, - unsigned int flags) { - struct watcher_list* w; - int events; - int err; - int wd; - - if (uv__is_active(handle)) - return -EINVAL; - - err = init_inotify(handle->loop); - if (err) - return err; - - events = UV__IN_ATTRIB - | UV__IN_CREATE - | UV__IN_MODIFY - | UV__IN_DELETE - | UV__IN_DELETE_SELF - | UV__IN_MOVE_SELF - | UV__IN_MOVED_FROM - | UV__IN_MOVED_TO; - - wd = uv__inotify_add_watch(handle->loop->inotify_fd, path, events); - if (wd == -1) - return -errno; - - w = find_watcher(handle->loop, wd); - if (w) - goto no_insert; - - w = malloc(sizeof(*w) + strlen(path) + 1); - if (w == NULL) - return -ENOMEM; - - w->wd = wd; - w->path = strcpy((char*)(w + 1), path); - QUEUE_INIT(&w->watchers); - RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w); - -no_insert: - uv__handle_start(handle); - QUEUE_INSERT_TAIL(&w->watchers, &handle->watchers); - handle->filename = w->path; - handle->cb = cb; - handle->wd = wd; - - return 0; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - struct watcher_list* w; - - if (!uv__is_active(handle)) - return -EINVAL; - - w = find_watcher(handle->loop, handle->wd); - assert(w != NULL); - - handle->wd = -1; - handle->filename = NULL; - uv__handle_stop(handle); - QUEUE_REMOVE(&handle->watchers); - - if (QUEUE_EMPTY(&w->watchers)) { - /* No watchers left for this path. Clean up. */ - RB_REMOVE(watcher_root, CAST(&handle->loop->inotify_watchers), w); - uv__inotify_rm_watch(handle->loop->inotify_fd, w->wd); - free(w); - } - - return 0; -} - - -void uv__fs_event_close(uv_fs_event_t* handle) { - uv_fs_event_stop(handle); -} diff --git a/third-party/libuv/src/unix/linux-syscalls.c b/third-party/libuv/src/unix/linux-syscalls.c deleted file mode 100644 index 06cc5943cf..0000000000 --- a/third-party/libuv/src/unix/linux-syscalls.c +++ /dev/null @@ -1,388 +0,0 @@ -/* 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 - * 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 "linux-syscalls.h" -#include <unistd.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <errno.h> - -#if defined(__i386__) -# ifndef __NR_socketcall -# define __NR_socketcall 102 -# endif -#endif - -#if defined(__arm__) -# if defined(__thumb__) || defined(__ARM_EABI__) -# define UV_SYSCALL_BASE 0 -# else -# define UV_SYSCALL_BASE 0x900000 -# endif -#endif /* __arm__ */ - -#ifndef __NR_accept4 -# if defined(__x86_64__) -# define __NR_accept4 288 -# elif defined(__i386__) - /* Nothing. Handled through socketcall(). */ -# elif defined(__arm__) -# define __NR_accept4 (UV_SYSCALL_BASE + 366) -# endif -#endif /* __NR_accept4 */ - -#ifndef __NR_eventfd -# if defined(__x86_64__) -# define __NR_eventfd 284 -# elif defined(__i386__) -# define __NR_eventfd 323 -# elif defined(__arm__) -# define __NR_eventfd (UV_SYSCALL_BASE + 351) -# endif -#endif /* __NR_eventfd */ - -#ifndef __NR_eventfd2 -# if defined(__x86_64__) -# define __NR_eventfd2 290 -# elif defined(__i386__) -# define __NR_eventfd2 328 -# elif defined(__arm__) -# define __NR_eventfd2 (UV_SYSCALL_BASE + 356) -# endif -#endif /* __NR_eventfd2 */ - -#ifndef __NR_epoll_create -# if defined(__x86_64__) -# define __NR_epoll_create 213 -# elif defined(__i386__) -# define __NR_epoll_create 254 -# elif defined(__arm__) -# define __NR_epoll_create (UV_SYSCALL_BASE + 250) -# endif -#endif /* __NR_epoll_create */ - -#ifndef __NR_epoll_create1 -# if defined(__x86_64__) -# define __NR_epoll_create1 291 -# elif defined(__i386__) -# define __NR_epoll_create1 329 -# elif defined(__arm__) -# define __NR_epoll_create1 (UV_SYSCALL_BASE + 357) -# endif -#endif /* __NR_epoll_create1 */ - -#ifndef __NR_epoll_ctl -# if defined(__x86_64__) -# define __NR_epoll_ctl 233 /* used to be 214 */ -# elif defined(__i386__) -# define __NR_epoll_ctl 255 -# elif defined(__arm__) -# define __NR_epoll_ctl (UV_SYSCALL_BASE + 251) -# endif -#endif /* __NR_epoll_ctl */ - -#ifndef __NR_epoll_wait -# if defined(__x86_64__) -# define __NR_epoll_wait 232 /* used to be 215 */ -# elif defined(__i386__) -# define __NR_epoll_wait 256 -# elif defined(__arm__) -# define __NR_epoll_wait (UV_SYSCALL_BASE + 252) -# endif -#endif /* __NR_epoll_wait */ - -#ifndef __NR_epoll_pwait -# if defined(__x86_64__) -# define __NR_epoll_pwait 281 -# elif defined(__i386__) -# define __NR_epoll_pwait 319 -# elif defined(__arm__) -# define __NR_epoll_pwait (UV_SYSCALL_BASE + 346) -# endif -#endif /* __NR_epoll_pwait */ - -#ifndef __NR_inotify_init -# if defined(__x86_64__) -# define __NR_inotify_init 253 -# elif defined(__i386__) -# define __NR_inotify_init 291 -# elif defined(__arm__) -# define __NR_inotify_init (UV_SYSCALL_BASE + 316) -# endif -#endif /* __NR_inotify_init */ - -#ifndef __NR_inotify_init1 -# if defined(__x86_64__) -# define __NR_inotify_init1 294 -# elif defined(__i386__) -# define __NR_inotify_init1 332 -# elif defined(__arm__) -# define __NR_inotify_init1 (UV_SYSCALL_BASE + 360) -# endif -#endif /* __NR_inotify_init1 */ - -#ifndef __NR_inotify_add_watch -# if defined(__x86_64__) -# define __NR_inotify_add_watch 254 -# elif defined(__i386__) -# define __NR_inotify_add_watch 292 -# elif defined(__arm__) -# define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317) -# endif -#endif /* __NR_inotify_add_watch */ - -#ifndef __NR_inotify_rm_watch -# if defined(__x86_64__) -# define __NR_inotify_rm_watch 255 -# elif defined(__i386__) -# define __NR_inotify_rm_watch 293 -# elif defined(__arm__) -# define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318) -# endif -#endif /* __NR_inotify_rm_watch */ - -#ifndef __NR_pipe2 -# if defined(__x86_64__) -# define __NR_pipe2 293 -# elif defined(__i386__) -# define __NR_pipe2 331 -# elif defined(__arm__) -# define __NR_pipe2 (UV_SYSCALL_BASE + 359) -# endif -#endif /* __NR_pipe2 */ - -#ifndef __NR_recvmmsg -# if defined(__x86_64__) -# define __NR_recvmmsg 299 -# elif defined(__i386__) -# define __NR_recvmmsg 337 -# elif defined(__arm__) -# define __NR_recvmmsg (UV_SYSCALL_BASE + 365) -# endif -#endif /* __NR_recvmsg */ - -#ifndef __NR_sendmmsg -# if defined(__x86_64__) -# define __NR_sendmmsg 307 -# elif defined(__i386__) -# define __NR_sendmmsg 345 -# elif defined(__arm__) -# define __NR_sendmmsg (UV_SYSCALL_BASE + 374) -# endif -#endif /* __NR_sendmmsg */ - -#ifndef __NR_utimensat -# if defined(__x86_64__) -# define __NR_utimensat 280 -# elif defined(__i386__) -# define __NR_utimensat 320 -# elif defined(__arm__) -# define __NR_utimensat (UV_SYSCALL_BASE + 348) -# endif -#endif /* __NR_utimensat */ - - -int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) { -#if defined(__i386__) - unsigned long args[4]; - int r; - - args[0] = (unsigned long) fd; - args[1] = (unsigned long) addr; - args[2] = (unsigned long) addrlen; - args[3] = (unsigned long) flags; - - r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args); - - /* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does - * a bad flags argument. Try to distinguish between the two cases. - */ - if (r == -1) - if (errno == EINVAL) - if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0) - errno = ENOSYS; - - return r; -#elif defined(__NR_accept4) - return syscall(__NR_accept4, fd, addr, addrlen, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__eventfd(unsigned int count) { -#if defined(__NR_eventfd) - return syscall(__NR_eventfd, count); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__eventfd2(unsigned int count, int flags) { -#if defined(__NR_eventfd2) - return syscall(__NR_eventfd2, count, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_create(int size) { -#if defined(__NR_epoll_create) - return syscall(__NR_epoll_create, size); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_create1(int flags) { -#if defined(__NR_epoll_create1) - return syscall(__NR_epoll_create1, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event* events) { -#if defined(__NR_epoll_ctl) - return syscall(__NR_epoll_ctl, epfd, op, fd, events); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_wait(int epfd, - struct uv__epoll_event* events, - int nevents, - int timeout) { -#if defined(__NR_epoll_wait) - return syscall(__NR_epoll_wait, epfd, events, nevents, timeout); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__epoll_pwait(int epfd, - struct uv__epoll_event* events, - int nevents, - int timeout, - const sigset_t* sigmask) { -#if defined(__NR_epoll_pwait) - return syscall(__NR_epoll_pwait, - epfd, - events, - nevents, - timeout, - sigmask, - sizeof(*sigmask)); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__inotify_init(void) { -#if defined(__NR_inotify_init) - return syscall(__NR_inotify_init); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__inotify_init1(int flags) { -#if defined(__NR_inotify_init1) - return syscall(__NR_inotify_init1, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__inotify_add_watch(int fd, const char* path, uint32_t mask) { -#if defined(__NR_inotify_add_watch) - return syscall(__NR_inotify_add_watch, fd, path, mask); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__inotify_rm_watch(int fd, int32_t wd) { -#if defined(__NR_inotify_rm_watch) - return syscall(__NR_inotify_rm_watch, fd, wd); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__pipe2(int pipefd[2], int flags) { -#if defined(__NR_pipe2) - return syscall(__NR_pipe2, pipefd, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__sendmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags) { -#if defined(__NR_sendmmsg) - return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__recvmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags, - struct timespec* timeout) { -#if defined(__NR_recvmmsg) - return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout); -#else - return errno = ENOSYS, -1; -#endif -} - - -int uv__utimesat(int dirfd, - const char* path, - const struct timespec times[2], - int flags) -{ -#if defined(__NR_utimensat) - return syscall(__NR_utimensat, dirfd, path, times, flags); -#else - return errno = ENOSYS, -1; -#endif -} diff --git a/third-party/libuv/src/unix/linux-syscalls.h b/third-party/libuv/src/unix/linux-syscalls.h deleted file mode 100644 index 1ad9518548..0000000000 --- a/third-party/libuv/src/unix/linux-syscalls.h +++ /dev/null @@ -1,151 +0,0 @@ -/* 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 - * 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. - */ - -#ifndef UV_LINUX_SYSCALL_H_ -#define UV_LINUX_SYSCALL_H_ - -#undef _GNU_SOURCE -#define _GNU_SOURCE - -#include <stdint.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/socket.h> - -#if defined(__alpha__) -# define UV__O_CLOEXEC 0x200000 -#elif defined(__hppa__) -# define UV__O_CLOEXEC 0x200000 -#elif defined(__sparc__) -# define UV__O_CLOEXEC 0x400000 -#else -# define UV__O_CLOEXEC 0x80000 -#endif - -#if defined(__alpha__) -# define UV__O_NONBLOCK 0x4 -#elif defined(__hppa__) -# define UV__O_NONBLOCK 0x10004 -#elif defined(__mips__) -# define UV__O_NONBLOCK 0x80 -#elif defined(__sparc__) -# define UV__O_NONBLOCK 0x4000 -#else -# define UV__O_NONBLOCK 0x800 -#endif - -#define UV__EFD_CLOEXEC UV__O_CLOEXEC -#define UV__EFD_NONBLOCK UV__O_NONBLOCK - -#define UV__IN_CLOEXEC UV__O_CLOEXEC -#define UV__IN_NONBLOCK UV__O_NONBLOCK - -#define UV__SOCK_CLOEXEC UV__O_CLOEXEC -#define UV__SOCK_NONBLOCK UV__O_NONBLOCK - -/* epoll flags */ -#define UV__EPOLL_CLOEXEC UV__O_CLOEXEC -#define UV__EPOLL_CTL_ADD 1 -#define UV__EPOLL_CTL_DEL 2 -#define UV__EPOLL_CTL_MOD 3 - -#define UV__EPOLLIN 1 -#define UV__EPOLLOUT 4 -#define UV__EPOLLERR 8 -#define UV__EPOLLHUP 16 -#define UV__EPOLLONESHOT 0x40000000 -#define UV__EPOLLET 0x80000000 - -/* inotify flags */ -#define UV__IN_ACCESS 0x001 -#define UV__IN_MODIFY 0x002 -#define UV__IN_ATTRIB 0x004 -#define UV__IN_CLOSE_WRITE 0x008 -#define UV__IN_CLOSE_NOWRITE 0x010 -#define UV__IN_OPEN 0x020 -#define UV__IN_MOVED_FROM 0x040 -#define UV__IN_MOVED_TO 0x080 -#define UV__IN_CREATE 0x100 -#define UV__IN_DELETE 0x200 -#define UV__IN_DELETE_SELF 0x400 -#define UV__IN_MOVE_SELF 0x800 - -#if defined(__x86_64__) -struct uv__epoll_event { - uint32_t events; - uint64_t data; -} __attribute__((packed)); -#else -struct uv__epoll_event { - uint32_t events; - uint64_t data; -}; -#endif - -struct uv__inotify_event { - int32_t wd; - uint32_t mask; - uint32_t cookie; - uint32_t len; - /* char name[0]; */ -}; - -struct uv__mmsghdr { - struct msghdr msg_hdr; - unsigned int msg_len; -}; - -int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags); -int uv__eventfd(unsigned int count); -int uv__epoll_create(int size); -int uv__epoll_create1(int flags); -int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event *ev); -int uv__epoll_wait(int epfd, - struct uv__epoll_event* events, - int nevents, - int timeout); -int uv__epoll_pwait(int epfd, - struct uv__epoll_event* events, - int nevents, - int timeout, - const sigset_t* sigmask); -int uv__eventfd2(unsigned int count, int flags); -int uv__inotify_init(void); -int uv__inotify_init1(int flags); -int uv__inotify_add_watch(int fd, const char* path, uint32_t mask); -int uv__inotify_rm_watch(int fd, int32_t wd); -int uv__pipe2(int pipefd[2], int flags); -int uv__recvmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags, - struct timespec* timeout); -int uv__sendmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags); -int uv__utimesat(int dirfd, - const char* path, - const struct timespec times[2], - int flags); - -#endif /* UV_LINUX_SYSCALL_H_ */ diff --git a/third-party/libuv/src/unix/loop-watcher.c b/third-party/libuv/src/unix/loop-watcher.c deleted file mode 100644 index dc03c206d2..0000000000 --- a/third-party/libuv/src/unix/loop-watcher.c +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - * 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" - -#define UV_LOOP_WATCHER_DEFINE(name, type) \ - int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \ - uv__handle_init(loop, (uv_handle_t*)handle, UV_##type); \ - handle->name##_cb = NULL; \ - return 0; \ - } \ - \ - int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ - if (uv__is_active(handle)) return 0; \ - if (cb == NULL) return -EINVAL; \ - QUEUE_INSERT_HEAD(&handle->loop->name##_handles, &handle->queue); \ - handle->name##_cb = cb; \ - uv__handle_start(handle); \ - return 0; \ - } \ - \ - int uv_##name##_stop(uv_##name##_t* handle) { \ - if (!uv__is_active(handle)) return 0; \ - QUEUE_REMOVE(&handle->queue); \ - uv__handle_stop(handle); \ - return 0; \ - } \ - \ - void uv__run_##name(uv_loop_t* loop) { \ - uv_##name##_t* h; \ - QUEUE* q; \ - QUEUE_FOREACH(q, &loop->name##_handles) { \ - h = QUEUE_DATA(q, uv_##name##_t, queue); \ - h->name##_cb(h, 0); \ - } \ - } \ - \ - void uv__##name##_close(uv_##name##_t* handle) { \ - uv_##name##_stop(handle); \ - } - -UV_LOOP_WATCHER_DEFINE(prepare, PREPARE) -UV_LOOP_WATCHER_DEFINE(check, CHECK) -UV_LOOP_WATCHER_DEFINE(idle, IDLE) diff --git a/third-party/libuv/src/unix/loop.c b/third-party/libuv/src/unix/loop.c deleted file mode 100644 index 94a5c03819..0000000000 --- a/third-party/libuv/src/unix/loop.c +++ /dev/null @@ -1,163 +0,0 @@ -/* 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 - * 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 "tree.h" -#include "internal.h" -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -static int uv__loop_init(uv_loop_t* loop, int default_loop); -static void uv__loop_delete(uv_loop_t* loop); - -static uv_loop_t default_loop_struct; -static uv_loop_t* default_loop_ptr; - - -uv_loop_t* uv_default_loop(void) { - if (default_loop_ptr != NULL) - return default_loop_ptr; - - if (uv__loop_init(&default_loop_struct, /* default_loop? */ 1)) - return NULL; - - default_loop_ptr = &default_loop_struct; - return default_loop_ptr; -} - - -uv_loop_t* uv_loop_new(void) { - uv_loop_t* loop; - - loop = malloc(sizeof(*loop)); - if (loop == NULL) - return NULL; - - if (uv__loop_init(loop, /* default_loop? */ 0)) { - free(loop); - return NULL; - } - - return loop; -} - - -void uv_loop_delete(uv_loop_t* loop) { - uv__loop_delete(loop); -#ifndef NDEBUG - memset(loop, -1, sizeof(*loop)); -#endif - if (loop == default_loop_ptr) - default_loop_ptr = NULL; - else - free(loop); -} - - -static int uv__loop_init(uv_loop_t* loop, int default_loop) { - unsigned int i; - int err; - - uv__signal_global_once_init(); - - memset(loop, 0, sizeof(*loop)); - RB_INIT(&loop->timer_handles); - 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->nfds = 0; - loop->watchers = NULL; - loop->nwatchers = 0; - QUEUE_INIT(&loop->pending_queue); - QUEUE_INIT(&loop->watcher_queue); - - loop->closing_handles = NULL; - uv__update_time(loop); - uv__async_init(&loop->async_watcher); - loop->signal_pipefd[0] = -1; - loop->signal_pipefd[1] = -1; - loop->backend_fd = -1; - loop->emfile_fd = -1; - - loop->timer_counter = 0; - loop->stop_flag = 0; - - err = uv__platform_loop_init(loop, default_loop); - if (err) - return err; - - uv_signal_init(loop, &loop->child_watcher); - uv__handle_unref(&loop->child_watcher); - loop->child_watcher.flags |= UV__HANDLE_INTERNAL; - - for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) - QUEUE_INIT(loop->process_handles + i); - - if (uv_mutex_init(&loop->wq_mutex)) - abort(); - - if (uv_async_init(loop, &loop->wq_async, uv__work_done)) - abort(); - - uv__handle_unref(&loop->wq_async); - loop->wq_async.flags |= UV__HANDLE_INTERNAL; - - return 0; -} - - -static void uv__loop_delete(uv_loop_t* loop) { - uv__signal_loop_cleanup(loop); - uv__platform_loop_delete(loop); - uv__async_stop(loop, &loop->async_watcher); - - if (loop->emfile_fd != -1) { - uv__close(loop->emfile_fd); - loop->emfile_fd = -1; - } - - if (loop->backend_fd != -1) { - uv__close(loop->backend_fd); - loop->backend_fd = -1; - } - - uv_mutex_lock(&loop->wq_mutex); - assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!"); - assert(!uv__has_active_reqs(loop)); - uv_mutex_unlock(&loop->wq_mutex); - uv_mutex_destroy(&loop->wq_mutex); - -#if 0 - assert(QUEUE_EMPTY(&loop->pending_queue)); - assert(QUEUE_EMPTY(&loop->watcher_queue)); - assert(loop->nfds == 0); -#endif - - free(loop->watchers); - loop->watchers = NULL; - loop->nwatchers = 0; -} diff --git a/third-party/libuv/src/unix/netbsd.c b/third-party/libuv/src/unix/netbsd.c deleted file mode 100644 index 7423a71078..0000000000 --- a/third-party/libuv/src/unix/netbsd.c +++ /dev/null @@ -1,367 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <string.h> -#include <errno.h> - -#include <kvm.h> -#include <paths.h> -#include <ifaddrs.h> -#include <unistd.h> -#include <time.h> -#include <stdlib.h> -#include <fcntl.h> - -#include <net/if.h> -#include <net/if_dl.h> -#include <sys/resource.h> -#include <sys/types.h> -#include <sys/sysctl.h> - -#include <unistd.h> -#include <time.h> - -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - -static char *process_title; - - -int uv__platform_loop_init(uv_loop_t* loop, int default_loop) { - return uv__kqueue_init(loop); -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - -void uv_loadavg(double avg[3]) { - struct loadavg info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_LOADAVG}; - - if (sysctl(which, 2, &info, &size, NULL, 0) == -1) return; - - avg[0] = (double) info.ldavg[0] / info.fscale; - avg[1] = (double) info.ldavg[1] / info.fscale; - avg[2] = (double) info.ldavg[2] / info.fscale; -} - - -int uv_exepath(char* buffer, size_t* size) { - int mib[4]; - size_t cb; - pid_t mypid; - - if (buffer == NULL || size == NULL) - return -EINVAL; - - mypid = getpid(); - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = mypid; - mib[3] = KERN_PROC_ARGV; - - cb = *size; - if (sysctl(mib, 4, buffer, &cb, NULL, 0)) - return -errno; - *size = strlen(buffer); - - return 0; -} - - -uint64_t uv_get_free_memory(void) { - struct uvmexp info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_UVMEXP}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info.free * sysconf(_SC_PAGESIZE); -} - - -uint64_t uv_get_total_memory(void) { -#if defined(HW_PHYSMEM64) - uint64_t info; - int which[] = {CTL_HW, HW_PHYSMEM64}; -#else - unsigned int info; - int which[] = {CTL_HW, HW_PHYSMEM}; -#endif - size_t size = sizeof(info); - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info; -} - - -char** uv_setup_args(int argc, char** argv) { - process_title = argc ? strdup(argv[0]) : NULL; - return argv; -} - - -int uv_set_process_title(const char* title) { - if (process_title) free(process_title); - - process_title = strdup(title); - setproctitle("%s", title); - - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (process_title) { - strncpy(buffer, process_title, size); - } else { - if (size > 0) { - buffer[0] = '\0'; - } - } - - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - kvm_t *kd = NULL; - struct kinfo_proc2 *kinfo = NULL; - pid_t pid; - int nprocs; - int max_size = sizeof(struct kinfo_proc2); - int page_size; - - page_size = getpagesize(); - pid = getpid(); - - kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open"); - - if (kd == NULL) goto error; - - kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs); - if (kinfo == NULL) goto error; - - *rss = kinfo->p_vm_rssize * page_size; - - kvm_close(kd); - - return 0; - -error: - if (kd) kvm_close(kd); - return -EPERM; -} - - -int uv_uptime(double* uptime) { - time_t now; - struct timeval info; - size_t size = sizeof(info); - static int which[] = {CTL_KERN, KERN_BOOTTIME}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - now = time(NULL); - - *uptime = (double)(now - info.tv_sec); - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK); - unsigned int multiplier = ((uint64_t)1000L / ticks); - unsigned int cur = 0; - uv_cpu_info_t* cpu_info; - u_int64_t* cp_times; - char model[512]; - u_int64_t cpuspeed; - int numcpus; - size_t size; - int i; - - size = sizeof(model); - if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) && - sysctlbyname("hw.model", &model, &size, NULL, 0)) { - return -errno; - } - - size = sizeof(numcpus); - if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) - return -errno; - *count = numcpus; - - /* Only i386 and amd64 have machdep.tsc_freq */ - size = sizeof(cpuspeed); - if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0)) - cpuspeed = 0; - - size = numcpus * CPUSTATES * sizeof(*cp_times); - cp_times = malloc(size); - if (cp_times == NULL) - return -ENOMEM; - - if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0)) - return -errno; - - *cpu_infos = malloc(numcpus * sizeof(**cpu_infos)); - if (!(*cpu_infos)) { - free(cp_times); - free(*cpu_infos); - return -ENOMEM; - } - - for (i = 0; i < numcpus; i++) { - cpu_info = &(*cpu_infos)[i]; - cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier; - cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier; - cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier; - cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier; - cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier; - cpu_info->model = strdup(model); - cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6); - cur += CPUSTATES; - } - free(cp_times); - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - free(cpu_infos[i].model); - } - - free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { - int i; - - for (i = 0; i < count; i++) { - free(addresses[i].name); - } - - free(addresses); -} diff --git a/third-party/libuv/src/unix/openbsd.c b/third-party/libuv/src/unix/openbsd.c deleted file mode 100644 index f052d80c57..0000000000 --- a/third-party/libuv/src/unix/openbsd.c +++ /dev/null @@ -1,388 +0,0 @@ -/* 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 - * 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 <sys/types.h> -#include <sys/param.h> -#include <sys/resource.h> -#include <sys/sched.h> -#include <sys/time.h> -#include <sys/sysctl.h> - -#include <ifaddrs.h> -#include <net/if.h> -#include <net/if_dl.h> - -#include <errno.h> -#include <fcntl.h> -#include <kvm.h> -#include <paths.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - - -static char *process_title; - - -int uv__platform_loop_init(uv_loop_t* loop, int default_loop) { - return uv__kqueue_init(loop); -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - -void uv_loadavg(double avg[3]) { - struct loadavg info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_LOADAVG}; - - if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return; - - avg[0] = (double) info.ldavg[0] / info.fscale; - avg[1] = (double) info.ldavg[1] / info.fscale; - avg[2] = (double) info.ldavg[2] / info.fscale; -} - - -int uv_exepath(char* buffer, size_t* size) { - int mib[4]; - char **argsbuf = NULL; - char **argsbuf_tmp; - size_t argsbuf_size = 100U; - size_t exepath_size; - pid_t mypid; - int err; - - if (buffer == NULL || size == NULL) - return -EINVAL; - - mypid = getpid(); - for (;;) { - err = -ENOMEM; - argsbuf_tmp = realloc(argsbuf, argsbuf_size); - if (argsbuf_tmp == NULL) - goto out; - argsbuf = argsbuf_tmp; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = mypid; - mib[3] = KERN_PROC_ARGV; - if (sysctl(mib, 4, argsbuf, &argsbuf_size, NULL, 0) == 0) { - break; - } - if (errno != ENOMEM) { - err = -errno; - goto out; - } - argsbuf_size *= 2U; - } - if (argsbuf[0] == NULL) { - err = -EINVAL; /* FIXME(bnoordhuis) More appropriate error. */ - goto out; - } - exepath_size = strlen(argsbuf[0]); - if (exepath_size >= *size) { - err = -EINVAL; - goto out; - } - memcpy(buffer, argsbuf[0], exepath_size + 1U); - *size = exepath_size; - err = 0; - -out: - free(argsbuf); - - return err; -} - - -uint64_t uv_get_free_memory(void) { - struct uvmexp info; - size_t size = sizeof(info); - int which[] = {CTL_VM, VM_UVMEXP}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info.free * sysconf(_SC_PAGESIZE); -} - - -uint64_t uv_get_total_memory(void) { - uint64_t info; - int which[] = {CTL_HW, HW_PHYSMEM64}; - size_t size = sizeof(info); - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - return (uint64_t) info; -} - - -char** uv_setup_args(int argc, char** argv) { - process_title = argc ? strdup(argv[0]) : NULL; - return argv; -} - - -int uv_set_process_title(const char* title) { - if (process_title) free(process_title); - process_title = strdup(title); - setproctitle(title); - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (process_title) { - strncpy(buffer, process_title, size); - } else { - if (size > 0) { - buffer[0] = '\0'; - } - } - - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - kvm_t *kd = NULL; - struct kinfo_proc *kinfo = NULL; - pid_t pid; - int nprocs, max_size = sizeof(struct kinfo_proc); - size_t page_size = getpagesize(); - - pid = getpid(); - - kd = kvm_open(NULL, _PATH_MEM, NULL, O_RDONLY, "kvm_open"); - if (kd == NULL) goto error; - - kinfo = kvm_getprocs(kd, KERN_PROC_PID, pid, max_size, &nprocs); - if (kinfo == NULL) goto error; - - *rss = kinfo->p_vm_rssize * page_size; - - kvm_close(kd); - - return 0; - -error: - if (kd) kvm_close(kd); - return -EPERM; -} - - -int uv_uptime(double* uptime) { - time_t now; - struct timeval info; - size_t size = sizeof(info); - static int which[] = {CTL_KERN, KERN_BOOTTIME}; - - if (sysctl(which, 2, &info, &size, NULL, 0)) - return -errno; - - now = time(NULL); - - *uptime = (double)(now - info.tv_sec); - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), - multiplier = ((uint64_t)1000L / ticks), cpuspeed; - uint64_t info[CPUSTATES]; - char model[512]; - int numcpus = 1; - int which[] = {CTL_HW,HW_MODEL,0}; - size_t size; - int i; - uv_cpu_info_t* cpu_info; - - size = sizeof(model); - if (sysctl(which, 2, &model, &size, NULL, 0)) - return -errno; - - which[1] = HW_NCPU; - size = sizeof(numcpus); - if (sysctl(which, 2, &numcpus, &size, NULL, 0)) - return -errno; - - *cpu_infos = malloc(numcpus * sizeof(**cpu_infos)); - if (!(*cpu_infos)) - return -ENOMEM; - - *count = numcpus; - - which[1] = HW_CPUSPEED; - size = sizeof(cpuspeed); - if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) { - SAVE_ERRNO(free(*cpu_infos)); - return -errno; - } - - size = sizeof(info); - which[0] = CTL_KERN; - which[1] = KERN_CPTIME2; - for (i = 0; i < numcpus; i++) { - which[2] = i; - size = sizeof(info); - if (sysctl(which, 3, &info, &size, NULL, 0)) { - SAVE_ERRNO(free(*cpu_infos)); - return -errno; - } - - cpu_info = &(*cpu_infos)[i]; - - cpu_info->cpu_times.user = (uint64_t)(info[CP_USER]) * multiplier; - cpu_info->cpu_times.nice = (uint64_t)(info[CP_NICE]) * multiplier; - cpu_info->cpu_times.sys = (uint64_t)(info[CP_SYS]) * multiplier; - cpu_info->cpu_times.idle = (uint64_t)(info[CP_IDLE]) * multiplier; - cpu_info->cpu_times.irq = (uint64_t)(info[CP_INTR]) * multiplier; - - cpu_info->model = strdup(model); - cpu_info->speed = cpuspeed; - } - - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - free(cpu_infos[i].model); - } - - free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs) != 0) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - free(addresses[i].name); - } - - free(addresses); -} diff --git a/third-party/libuv/src/unix/pipe.c b/third-party/libuv/src/unix/pipe.c deleted file mode 100644 index fd4afb6370..0000000000 --- a/third-party/libuv/src/unix/pipe.c +++ /dev/null @@ -1,216 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <errno.h> -#include <string.h> -#include <sys/un.h> -#include <unistd.h> -#include <stdlib.h> - - -int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { - uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); - handle->shutdown_req = NULL; - handle->connect_req = NULL; - handle->pipe_fname = NULL; - handle->ipc = ipc; - return 0; -} - - -int uv_pipe_bind(uv_pipe_t* handle, const char* name) { - struct sockaddr_un saddr; - const char* pipe_fname; - int sockfd; - int bound; - int err; - - pipe_fname = NULL; - sockfd = -1; - bound = 0; - err = -EINVAL; - - /* Already bound? */ - if (uv__stream_fd(handle) >= 0) - return -EINVAL; - - /* Make a copy of the file name, it outlives this function's scope. */ - pipe_fname = strdup(name); - if (pipe_fname == NULL) { - err = -ENOMEM; - goto out; - } - - /* We've got a copy, don't touch the original any more. */ - name = NULL; - - err = uv__socket(AF_UNIX, SOCK_STREAM, 0); - if (err < 0) - goto out; - sockfd = err; - - memset(&saddr, 0, sizeof saddr); - strncpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path) - 1); - saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; - saddr.sun_family = AF_UNIX; - - if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) { - err = -errno; - /* Convert ENOENT to EACCES for compatibility with Windows. */ - if (err == -ENOENT) - err = -EACCES; - goto out; - } - bound = 1; - - /* Success. */ - handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */ - handle->io_watcher.fd = sockfd; - return 0; - -out: - if (bound) { - /* unlink() before uv__close() to avoid races. */ - assert(pipe_fname != NULL); - unlink(pipe_fname); - } - uv__close(sockfd); - free((void*)pipe_fname); - return err; -} - - -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { - if (uv__stream_fd(handle) == -1) - return -EINVAL; - - if (listen(uv__stream_fd(handle), backlog)) - return -errno; - - handle->connection_cb = cb; - handle->io_watcher.cb = uv__server_io; - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN); - return 0; -} - - -void uv__pipe_close(uv_pipe_t* handle) { - if (handle->pipe_fname) { - /* - * Unlink the file system entity before closing the file descriptor. - * Doing it the other way around introduces a race where our process - * unlinks a socket with the same name that's just been created by - * another thread or process. - */ - unlink(handle->pipe_fname); - free((void*)handle->pipe_fname); - handle->pipe_fname = NULL; - } - - uv__stream_close((uv_stream_t*)handle); -} - - -int uv_pipe_open(uv_pipe_t* handle, uv_file fd) { -#if defined(__APPLE__) - int err; - - err = uv__stream_try_select((uv_stream_t*) handle, &fd); - if (err) - return err; -#endif /* defined(__APPLE__) */ - - return uv__stream_open((uv_stream_t*)handle, - fd, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); -} - - -void uv_pipe_connect(uv_connect_t* req, - uv_pipe_t* handle, - const char* name, - uv_connect_cb cb) { - struct sockaddr_un saddr; - int new_sock; - int err; - int r; - - new_sock = (uv__stream_fd(handle) == -1); - err = -EINVAL; - - if (new_sock) { - err = uv__socket(AF_UNIX, SOCK_STREAM, 0); - if (err < 0) - goto out; - handle->io_watcher.fd = err; - } - - memset(&saddr, 0, sizeof saddr); - strncpy(saddr.sun_path, name, sizeof(saddr.sun_path) - 1); - saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; - saddr.sun_family = AF_UNIX; - - do { - r = connect(uv__stream_fd(handle), - (struct sockaddr*)&saddr, sizeof saddr); - } - while (r == -1 && errno == EINTR); - - if (r == -1 && errno != EINPROGRESS) { - err = -errno; - goto out; - } - - err = 0; - if (new_sock) { - err = uv__stream_open((uv_stream_t*)handle, - uv__stream_fd(handle), - UV_STREAM_READABLE | UV_STREAM_WRITABLE); - } - - if (err == 0) - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT); - -out: - handle->delayed_error = err; - handle->connect_req = req; - - uv__req_init(handle->loop, req, UV_CONNECT); - req->handle = (uv_stream_t*)handle; - req->cb = cb; - QUEUE_INIT(&req->queue); - - /* Force callback to run on next tick in case of error. */ - if (err) - uv__io_feed(handle->loop, &handle->io_watcher); - - /* Mimic the Windows pipe implementation, always - * return 0 and let the callback handle errors. - */ -} - - -void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { -} diff --git a/third-party/libuv/src/unix/poll.c b/third-party/libuv/src/unix/poll.c deleted file mode 100644 index a34a8d1e14..0000000000 --- a/third-party/libuv/src/unix/poll.c +++ /dev/null @@ -1,107 +0,0 @@ -/* 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 - * 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 <unistd.h> -#include <assert.h> -#include <errno.h> - - -static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - uv_poll_t* handle; - int pevents; - - handle = container_of(w, uv_poll_t, io_watcher); - - if (events & UV__POLLERR) { - uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT); - uv__handle_stop(handle); - handle->poll_cb(handle, -EBADF, 0); - return; - } - - pevents = 0; - if (events & UV__POLLIN) - pevents |= UV_READABLE; - if (events & UV__POLLOUT) - pevents |= UV_WRITABLE; - - handle->poll_cb(handle, 0, pevents); -} - - -int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); - uv__io_init(&handle->io_watcher, uv__poll_io, fd); - handle->poll_cb = NULL; - return 0; -} - - -int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, - uv_os_sock_t socket) { - return uv_poll_init(loop, handle, socket); -} - - -static void uv__poll_stop(uv_poll_t* handle) { - uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT); - uv__handle_stop(handle); -} - - -int uv_poll_stop(uv_poll_t* handle) { - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - uv__poll_stop(handle); - return 0; -} - - -int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) { - int events; - - assert((pevents & ~(UV_READABLE | UV_WRITABLE)) == 0); - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - - uv__poll_stop(handle); - - if (pevents == 0) - return 0; - - events = 0; - if (pevents & UV_READABLE) - events |= UV__POLLIN; - if (pevents & UV_WRITABLE) - events |= UV__POLLOUT; - - uv__io_start(handle->loop, &handle->io_watcher, events); - uv__handle_start(handle); - handle->poll_cb = poll_cb; - - return 0; -} - - -void uv__poll_close(uv_poll_t* handle) { - uv__poll_stop(handle); -} diff --git a/third-party/libuv/src/unix/process.c b/third-party/libuv/src/unix/process.c deleted file mode 100644 index 6f96b754d8..0000000000 --- a/third-party/libuv/src/unix/process.c +++ /dev/null @@ -1,517 +0,0 @@ -/* 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 - * 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 <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> - -#if defined(__APPLE__) && !TARGET_OS_IPHONE -# include <crt_externs.h> -# define environ (*_NSGetEnviron()) -#else -extern char **environ; -#endif - - -static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) { - assert(pid > 0); - return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles); -} - - -static void uv__chld(uv_signal_t* handle, int signum) { - uv_process_t* process; - uv_loop_t* loop; - int exit_status; - int term_signal; - unsigned int i; - int status; - pid_t pid; - QUEUE pending; - QUEUE* h; - QUEUE* q; - - assert(signum == SIGCHLD); - - QUEUE_INIT(&pending); - loop = handle->loop; - - for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) { - h = loop->process_handles + i; - q = QUEUE_HEAD(h); - - while (q != h) { - process = QUEUE_DATA(q, uv_process_t, queue); - q = QUEUE_NEXT(q); - - do - pid = waitpid(process->pid, &status, WNOHANG); - while (pid == -1 && errno == EINTR); - - if (pid == 0) - continue; - - if (pid == -1) { - if (errno != ECHILD) - abort(); - continue; - } - - process->status = status; - QUEUE_REMOVE(&process->queue); - QUEUE_INSERT_TAIL(&pending, &process->queue); - } - - while (!QUEUE_EMPTY(&pending)) { - q = QUEUE_HEAD(&pending); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - process = QUEUE_DATA(q, uv_process_t, queue); - uv__handle_stop(process); - - if (process->exit_cb == NULL) - continue; - - exit_status = 0; - if (WIFEXITED(process->status)) - exit_status = WEXITSTATUS(process->status); - - term_signal = 0; - if (WIFSIGNALED(process->status)) - term_signal = WTERMSIG(process->status); - - process->exit_cb(process, exit_status, term_signal); - } - } -} - - -int uv__make_socketpair(int fds[2], int flags) { -#if defined(__linux__) - static int no_cloexec; - - if (no_cloexec) - goto skip; - - if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0) - return 0; - - /* Retry on EINVAL, it means SOCK_CLOEXEC is not supported. - * Anything else is a genuine error. - */ - if (errno != EINVAL) - return -errno; - - no_cloexec = 1; - -skip: -#endif - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) - return -errno; - - uv__cloexec(fds[0], 1); - uv__cloexec(fds[1], 1); - - if (flags & UV__F_NONBLOCK) { - uv__nonblock(fds[0], 1); - uv__nonblock(fds[1], 1); - } - - return 0; -} - - -int uv__make_pipe(int fds[2], int flags) { -#if defined(__linux__) - static int no_pipe2; - - if (no_pipe2) - goto skip; - - if (uv__pipe2(fds, flags | UV__O_CLOEXEC) == 0) - return 0; - - if (errno != ENOSYS) - return -errno; - - no_pipe2 = 1; - -skip: -#endif - - if (pipe(fds)) - return -errno; - - uv__cloexec(fds[0], 1); - uv__cloexec(fds[1], 1); - - if (flags & UV__F_NONBLOCK) { - uv__nonblock(fds[0], 1); - uv__nonblock(fds[1], 1); - } - - return 0; -} - - -/* - * Used for initializing stdio streams like options.stdin_stream. Returns - * zero on success. See also the cleanup section in uv_spawn(). - */ -static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) { - int mask; - int fd; - - mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM; - - switch (container->flags & mask) { - case UV_IGNORE: - return 0; - - case UV_CREATE_PIPE: - assert(container->data.stream != NULL); - if (container->data.stream->type != UV_NAMED_PIPE) - return -EINVAL; - else - return uv__make_socketpair(fds, 0); - - case UV_INHERIT_FD: - case UV_INHERIT_STREAM: - if (container->flags & UV_INHERIT_FD) - fd = container->data.fd; - else - fd = uv__stream_fd(container->data.stream); - - if (fd == -1) - return -EINVAL; - - fds[1] = fd; - return 0; - - default: - assert(0 && "Unexpected flags"); - return -EINVAL; - } -} - - -static int uv__process_open_stream(uv_stdio_container_t* container, - int pipefds[2], - int writable) { - int flags; - - if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0) - return 0; - - if (uv__close(pipefds[1])) - if (errno != EINTR && errno != EINPROGRESS) - abort(); - - 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; - - return uv__stream_open(container->data.stream, pipefds[0], flags); -} - - -static void uv__process_close_stream(uv_stdio_container_t* container) { - if (!(container->flags & UV_CREATE_PIPE)) return; - uv__stream_close((uv_stream_t*)container->data.stream); -} - - -static void uv__write_int(int fd, int val) { - ssize_t n; - - do - n = write(fd, &val, sizeof(val)); - while (n == -1 && errno == EINTR); - - if (n == -1 && errno == EPIPE) - return; /* parent process has quit */ - - assert(n == sizeof(val)); -} - - -static void uv__process_child_init(const uv_process_options_t* options, - int stdio_count, - int (*pipes)[2], - int error_fd) { - int close_fd; - int use_fd; - int fd; - - if (options->flags & UV_PROCESS_DETACHED) - setsid(); - - for (fd = 0; fd < stdio_count; fd++) { - close_fd = pipes[fd][0]; - use_fd = pipes[fd][1]; - - if (use_fd < 0) { - if (fd >= 3) - continue; - else { - /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is - * set - */ - use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR); - close_fd = use_fd; - - if (use_fd == -1) { - uv__write_int(error_fd, -errno); - perror("failed to open stdio"); - _exit(127); - } - } - } - - if (fd == use_fd) - uv__cloexec(use_fd, 0); - else - dup2(use_fd, fd); - - if (fd <= 2) - uv__nonblock(fd, 0); - - if (close_fd != -1) - uv__close(close_fd); - } - - for (fd = 0; fd < stdio_count; fd++) { - use_fd = pipes[fd][1]; - - if (use_fd >= 0 && fd != use_fd) - close(use_fd); - } - - if (options->cwd != NULL && chdir(options->cwd)) { - uv__write_int(error_fd, -errno); - perror("chdir()"); - _exit(127); - } - - if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) { - uv__write_int(error_fd, -errno); - perror("setgid()"); - _exit(127); - } - - if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) { - uv__write_int(error_fd, -errno); - perror("setuid()"); - _exit(127); - } - - if (options->env != NULL) { - environ = options->env; - } - - execvp(options->file, options->args); - uv__write_int(error_fd, -errno); - perror("execvp()"); - _exit(127); -} - - -int uv_spawn(uv_loop_t* loop, - uv_process_t* process, - const uv_process_options_t* options) { - int signal_pipe[2] = { -1, -1 }; - int (*pipes)[2]; - int stdio_count; - QUEUE* q; - ssize_t r; - pid_t pid; - int err; - int exec_errorno; - int i; - - assert(options->file != NULL); - assert(!(options->flags & ~(UV_PROCESS_DETACHED | - UV_PROCESS_SETGID | - UV_PROCESS_SETUID | - UV_PROCESS_WINDOWS_HIDE | - UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); - - uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS); - QUEUE_INIT(&process->queue); - - stdio_count = options->stdio_count; - if (stdio_count < 3) - stdio_count = 3; - - err = -ENOMEM; - pipes = malloc(stdio_count * sizeof(*pipes)); - if (pipes == NULL) - goto error; - - for (i = 0; i < stdio_count; i++) { - pipes[i][0] = -1; - pipes[i][1] = -1; - } - - for (i = 0; i < options->stdio_count; i++) { - err = uv__process_init_stdio(options->stdio + i, pipes[i]); - if (err) - goto error; - } - - /* This pipe is used by the parent to wait until - * the child has called `execve()`. We need this - * to avoid the following race condition: - * - * if ((pid = fork()) > 0) { - * kill(pid, SIGTERM); - * } - * else if (pid == 0) { - * execve("/bin/cat", argp, envp); - * } - * - * The parent sends a signal immediately after forking. - * Since the child may not have called `execve()` yet, - * there is no telling what process receives the signal, - * our fork or /bin/cat. - * - * To avoid ambiguity, we create a pipe with both ends - * marked close-on-exec. Then, after the call to `fork()`, - * the parent polls the read end until it EOFs or errors with EPIPE. - */ - err = uv__make_pipe(signal_pipe, 0); - if (err) - goto error; - - uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD); - - pid = fork(); - - if (pid == -1) { - err = -errno; - uv__close(signal_pipe[0]); - uv__close(signal_pipe[1]); - goto error; - } - - if (pid == 0) { - uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]); - abort(); - } - - uv__close(signal_pipe[1]); - - process->status = 0; - exec_errorno = 0; - do - r = read(signal_pipe[0], &exec_errorno, sizeof(exec_errorno)); - while (r == -1 && errno == EINTR); - - if (r == 0) - ; /* okay, EOF */ - else if (r == sizeof(exec_errorno)) - ; /* okay, read errorno */ - else if (r == -1 && errno == EPIPE) - ; /* okay, got EPIPE */ - else - abort(); - - uv__close(signal_pipe[0]); - - for (i = 0; i < options->stdio_count; i++) { - err = uv__process_open_stream(options->stdio + i, pipes[i], i == 0); - if (err == 0) - continue; - - while (i--) - uv__process_close_stream(options->stdio + i); - - goto error; - } - - /* Only activate this handle if exec() happened successfully */ - if (exec_errorno == 0) { - q = uv__process_queue(loop, pid); - QUEUE_INSERT_TAIL(q, &process->queue); - uv__handle_start(process); - } - - process->pid = pid; - process->exit_cb = options->exit_cb; - - free(pipes); - return exec_errorno; - -error: - if (pipes != NULL) { - for (i = 0; i < stdio_count; i++) { - if (i < options->stdio_count) - if (options->stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM)) - continue; - if (pipes[i][0] != -1) - close(pipes[i][0]); - if (pipes[i][1] != -1) - close(pipes[i][1]); - } - free(pipes); - } - - return err; -} - - -int uv_process_kill(uv_process_t* process, int signum) { - return uv_kill(process->pid, signum); -} - - -int uv_kill(int pid, int signum) { - if (kill(pid, signum)) - return -errno; - else - return 0; -} - - -void uv__process_close(uv_process_t* handle) { - /* TODO stop signal watcher when this is the last handle */ - QUEUE_REMOVE(&handle->queue); - uv__handle_stop(handle); -} diff --git a/third-party/libuv/src/unix/proctitle.c b/third-party/libuv/src/unix/proctitle.c deleted file mode 100644 index 16b0523731..0000000000 --- a/third-party/libuv/src/unix/proctitle.c +++ /dev/null @@ -1,102 +0,0 @@ -/* 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 - * 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 <stdlib.h> -#include <string.h> - -extern void uv__set_process_title(const char* title); - -static void* args_mem; - -static struct { - char* str; - size_t len; -} process_title; - - -char** uv_setup_args(int argc, char** argv) { - char** new_argv; - size_t size; - char* s; - int i; - - if (argc <= 0) - return argv; - - /* Calculate how much memory we need for the argv strings. */ - size = 0; - for (i = 0; i < argc; i++) - size += strlen(argv[i]) + 1; - - process_title.str = argv[0]; - process_title.len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[0]; - assert(process_title.len + 1 == size); /* argv memory should be adjacent. */ - - /* Add space for the argv pointers. */ - size += (argc + 1) * sizeof(char*); - - new_argv = malloc(size); - if (new_argv == NULL) - return argv; - args_mem = new_argv; - - /* Copy over the strings and set up the pointer table. */ - s = (char*) &new_argv[argc + 1]; - for (i = 0; i < argc; i++) { - size = strlen(argv[i]) + 1; - memcpy(s, argv[i], size); - new_argv[i] = s; - s += size; - } - new_argv[i] = NULL; - - return new_argv; -} - - -int uv_set_process_title(const char* title) { - if (process_title.len == 0) - return 0; - - /* No need to terminate, byte after is always '\0'. */ - strncpy(process_title.str, title, process_title.len); - uv__set_process_title(title); - - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (process_title.len > 0) - strncpy(buffer, process_title.str, size); - else if (size > 0) - buffer[0] = '\0'; - - return 0; -} - - -UV_DESTRUCTOR(static void free_args_mem(void)) { - free(args_mem); /* Keep valgrind happy. */ - args_mem = NULL; -} diff --git a/third-party/libuv/src/unix/pthread-fixes.c b/third-party/libuv/src/unix/pthread-fixes.c deleted file mode 100644 index 2e4c542bc2..0000000000 --- a/third-party/libuv/src/unix/pthread-fixes.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2013, Sony Mobile Communications AB - * Copyright (c) 2012, Google Inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -/*Android doesn't provide pthread_barrier_t for now.*/ -#ifndef PTHREAD_BARRIER_SERIAL_THREAD - -#include "pthread-fixes.h" - -int pthread_barrier_init(pthread_barrier_t* barrier, - const void* barrier_attr, - unsigned count) { - barrier->count = count; - pthread_mutex_init(&barrier->mutex, NULL); - pthread_cond_init(&barrier->cond, NULL); - return 0; -} - -int pthread_barrier_wait(pthread_barrier_t* barrier) { - /* Lock the mutex*/ - pthread_mutex_lock(&barrier->mutex); - /* Decrement the count. If this is the first thread to reach 0, wake up - waiters, unlock the mutex, then return PTHREAD_BARRIER_SERIAL_THREAD.*/ - if (--barrier->count == 0) { - /* First thread to reach the barrier */ - pthread_cond_broadcast(&barrier->cond); - pthread_mutex_unlock(&barrier->mutex); - return PTHREAD_BARRIER_SERIAL_THREAD; - } - /* Otherwise, wait for other threads until the count reaches 0, then - return 0 to indicate this is not the first thread.*/ - do { - pthread_cond_wait(&barrier->cond, &barrier->mutex); - } while (barrier->count > 0); - - pthread_mutex_unlock(&barrier->mutex); - return 0; -} - -int pthread_barrier_destroy(pthread_barrier_t *barrier) { - barrier->count = 0; - pthread_cond_destroy(&barrier->cond); - pthread_mutex_destroy(&barrier->mutex); - return 0; -} - -#endif /* defined(PTHREAD_BARRIER_SERIAL_THREAD) */ - -int pthread_yield(void) { - sched_yield(); - return 0; -} diff --git a/third-party/libuv/src/unix/signal.c b/third-party/libuv/src/unix/signal.c deleted file mode 100644 index 0b7a405c15..0000000000 --- a/third-party/libuv/src/unix/signal.c +++ /dev/null @@ -1,465 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <errno.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - - -typedef struct { - uv_signal_t* handle; - int signum; -} uv__signal_msg_t; - -RB_HEAD(uv__signal_tree_s, uv_signal_s); - - -static int uv__signal_unlock(void); -static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events); -static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2); -static void uv__signal_stop(uv_signal_t* handle); - - -static pthread_once_t uv__signal_global_init_guard = PTHREAD_ONCE_INIT; -static struct uv__signal_tree_s uv__signal_tree = - RB_INITIALIZER(uv__signal_tree); -static int uv__signal_lock_pipefd[2]; - - -RB_GENERATE_STATIC(uv__signal_tree_s, - uv_signal_s, tree_entry, - uv__signal_compare) - - -static void uv__signal_global_init(void) { - if (uv__make_pipe(uv__signal_lock_pipefd, 0)) - abort(); - - if (uv__signal_unlock()) - abort(); -} - - -void uv__signal_global_once_init(void) { - pthread_once(&uv__signal_global_init_guard, uv__signal_global_init); -} - - - -static int uv__signal_lock(void) { - int r; - char data; - - do { - r = read(uv__signal_lock_pipefd[0], &data, sizeof data); - } while (r < 0 && errno == EINTR); - - return (r < 0) ? -1 : 0; -} - - -static int uv__signal_unlock(void) { - int r; - char data = 42; - - do { - r = write(uv__signal_lock_pipefd[1], &data, sizeof data); - } while (r < 0 && errno == EINTR); - - return (r < 0) ? -1 : 0; -} - - -static void uv__signal_block_and_lock(sigset_t* saved_sigmask) { - sigset_t new_mask; - - if (sigfillset(&new_mask)) - abort(); - - if (pthread_sigmask(SIG_SETMASK, &new_mask, saved_sigmask)) - abort(); - - if (uv__signal_lock()) - abort(); -} - - -static void uv__signal_unlock_and_unblock(sigset_t* saved_sigmask) { - if (uv__signal_unlock()) - abort(); - - if (pthread_sigmask(SIG_SETMASK, saved_sigmask, NULL)) - abort(); -} - - -static uv_signal_t* uv__signal_first_handle(int signum) { - /* This function must be called with the signal lock held. */ - uv_signal_t lookup; - uv_signal_t* handle; - - lookup.signum = signum; - lookup.loop = NULL; - - handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup); - - if (handle != NULL && handle->signum == signum) - return handle; - - return NULL; -} - - -static void uv__signal_handler(int signum) { - uv__signal_msg_t msg; - uv_signal_t* handle; - int saved_errno; - - saved_errno = errno; - memset(&msg, 0, sizeof msg); - - if (uv__signal_lock()) { - errno = saved_errno; - return; - } - - for (handle = uv__signal_first_handle(signum); - handle != NULL && handle->signum == signum; - handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) { - int r; - - msg.signum = signum; - msg.handle = handle; - - /* write() should be atomic for small data chunks, so the entire message - * should be written at once. In theory the pipe could become full, in - * which case the user is out of luck. - */ - do { - r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg); - } while (r == -1 && errno == EINTR); - - assert(r == sizeof msg || - (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))); - - if (r != -1) - handle->caught_signals++; - } - - uv__signal_unlock(); - errno = saved_errno; -} - - -static int uv__signal_register_handler(int signum) { - /* When this function is called, the signal lock must be held. */ - struct sigaction sa; - - /* XXX use a separate signal stack? */ - memset(&sa, 0, sizeof(sa)); - if (sigfillset(&sa.sa_mask)) - abort(); - sa.sa_handler = uv__signal_handler; - - /* XXX save old action so we can restore it later on? */ - if (sigaction(signum, &sa, NULL)) - return -errno; - - return 0; -} - - -static void uv__signal_unregister_handler(int signum) { - /* When this function is called, the signal lock must be held. */ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - - /* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a - * signal implies that it was successfully registered earlier, so EINVAL - * should never happen. - */ - if (sigaction(signum, &sa, NULL)) - abort(); -} - - -static int uv__signal_loop_once_init(uv_loop_t* loop) { - int err; - - /* Return if already initialized. */ - if (loop->signal_pipefd[0] != -1) - return 0; - - err = uv__make_pipe(loop->signal_pipefd, UV__F_NONBLOCK); - if (err) - return err; - - uv__io_init(&loop->signal_io_watcher, - uv__signal_event, - loop->signal_pipefd[0]); - uv__io_start(loop, &loop->signal_io_watcher, UV__POLLIN); - - return 0; -} - - -void uv__signal_loop_cleanup(uv_loop_t* loop) { - QUEUE* q; - - /* Stop all the signal watchers that are still attached to this loop. This - * ensures that the (shared) signal tree doesn't contain any invalid entries - * entries, and that signal handlers are removed when appropriate. - */ - QUEUE_FOREACH(q, &loop->handle_queue) { - uv_handle_t* handle = QUEUE_DATA(q, uv_handle_t, handle_queue); - - if (handle->type == UV_SIGNAL) - uv__signal_stop((uv_signal_t*) handle); - } - - if (loop->signal_pipefd[0] != -1) { - uv__close(loop->signal_pipefd[0]); - loop->signal_pipefd[0] = -1; - } - - if (loop->signal_pipefd[1] != -1) { - uv__close(loop->signal_pipefd[1]); - loop->signal_pipefd[1] = -1; - } -} - - -int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { - int err; - - err = uv__signal_loop_once_init(loop); - if (err) - return err; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); - handle->signum = 0; - handle->caught_signals = 0; - handle->dispatched_signals = 0; - - return 0; -} - - -void uv__signal_close(uv_signal_t* handle) { - - uv__signal_stop(handle); - - /* If there are any caught signals "trapped" in the signal pipe, we can't - * call the close callback yet. Otherwise, add the handle to the finish_close - * queue. - */ - if (handle->caught_signals == handle->dispatched_signals) { - uv__make_close_pending((uv_handle_t*) handle); - } -} - - -int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { - sigset_t saved_sigmask; - int err; - - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - - /* If the user supplies signum == 0, then return an error already. If the - * signum is otherwise invalid then uv__signal_register will find out - * eventually. - */ - if (signum == 0) - return -EINVAL; - - /* Short circuit: if the signal watcher is already watching {signum} don't - * go through the process of deregistering and registering the handler. - * Additionally, this avoids pending signals getting lost in the small time - * time frame that handle->signum == 0. - */ - if (signum == handle->signum) { - handle->signal_cb = signal_cb; - return 0; - } - - /* If the signal handler was already active, stop it first. */ - if (handle->signum != 0) { - uv__signal_stop(handle); - } - - uv__signal_block_and_lock(&saved_sigmask); - - /* If at this point there are no active signal watchers for this signum (in - * any of the loops), it's time to try and register a handler for it here. - */ - if (uv__signal_first_handle(signum) == NULL) { - err = uv__signal_register_handler(signum); - if (err) { - /* Registering the signal handler failed. Must be an invalid signal. */ - uv__signal_unlock_and_unblock(&saved_sigmask); - return err; - } - } - - handle->signum = signum; - RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle); - - uv__signal_unlock_and_unblock(&saved_sigmask); - - handle->signal_cb = signal_cb; - uv__handle_start(handle); - - return 0; -} - - -static void uv__signal_event(uv_loop_t* loop, - uv__io_t* w, - unsigned int events) { - uv__signal_msg_t* msg; - uv_signal_t* handle; - char buf[sizeof(uv__signal_msg_t) * 32]; - size_t bytes, end, i; - int r; - - bytes = 0; - end = 0; - - do { - r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes); - - if (r == -1 && errno == EINTR) - continue; - - if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { - /* If there are bytes in the buffer already (which really is extremely - * unlikely if possible at all) we can't exit the function here. We'll - * spin until more bytes are read instead. - */ - if (bytes > 0) - continue; - - /* Otherwise, there was nothing there. */ - return; - } - - /* Other errors really should never happen. */ - if (r == -1) - abort(); - - bytes += r; - - /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */ - end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t); - - for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) { - msg = (uv__signal_msg_t*) (buf + i); - handle = msg->handle; - - if (msg->signum == handle->signum) { - assert(!(handle->flags & UV_CLOSING)); - handle->signal_cb(handle, handle->signum); - } - - handle->dispatched_signals++; - - /* If uv_close was called while there were caught signals that were not - * yet dispatched, the uv__finish_close was deferred. Make close pending - * now if this has happened. - */ - if ((handle->flags & UV_CLOSING) && - (handle->caught_signals == handle->dispatched_signals)) { - uv__make_close_pending((uv_handle_t*) handle); - } - } - - bytes -= end; - - /* If there are any "partial" messages left, move them to the start of the - * the buffer, and spin. This should not happen. - */ - if (bytes) { - memmove(buf, buf + end, bytes); - continue; - } - } while (end == sizeof buf); -} - - -static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { - /* Compare signums first so all watchers with the same signnum end up - * adjacent. - */ - if (w1->signum < w2->signum) return -1; - if (w1->signum > w2->signum) return 1; - - /* Sort by loop pointer, so we can easily look up the first item after - * { .signum = x, .loop = NULL }. - */ - if (w1->loop < w2->loop) return -1; - if (w1->loop > w2->loop) return 1; - - if (w1 < w2) return -1; - if (w1 > w2) return 1; - - return 0; -} - - -int uv_signal_stop(uv_signal_t* handle) { - assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - uv__signal_stop(handle); - return 0; -} - - -static void uv__signal_stop(uv_signal_t* handle) { - uv_signal_t* removed_handle; - sigset_t saved_sigmask; - - /* If the watcher wasn't started, this is a no-op. */ - if (handle->signum == 0) - return; - - uv__signal_block_and_lock(&saved_sigmask); - - removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle); - assert(removed_handle == handle); - (void) removed_handle; - - /* Check if there are other active signal watchers observing this signal. If - * not, unregister the signal handler. - */ - if (uv__signal_first_handle(handle->signum) == NULL) - uv__signal_unregister_handler(handle->signum); - - uv__signal_unlock_and_unblock(&saved_sigmask); - - handle->signum = 0; - uv__handle_stop(handle); -} diff --git a/third-party/libuv/src/unix/spinlock.h b/third-party/libuv/src/unix/spinlock.h deleted file mode 100644 index a20c83cc60..0000000000 --- a/third-party/libuv/src/unix/spinlock.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef UV_SPINLOCK_H_ -#define UV_SPINLOCK_H_ - -#include "internal.h" /* ACCESS_ONCE, UV_UNUSED */ -#include "atomic-ops.h" - -#define UV_SPINLOCK_INITIALIZER { 0 } - -typedef struct { - int lock; -} uv_spinlock_t; - -UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock)); -UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock)); -UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock)); -UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock)); - -UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock)) { - ACCESS_ONCE(int, spinlock->lock) = 0; -} - -UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock)) { - while (!uv_spinlock_trylock(spinlock)) cpu_relax(); -} - -UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock)) { - ACCESS_ONCE(int, spinlock->lock) = 0; -} - -UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock)) { - /* TODO(bnoordhuis) Maybe change to a ticket lock to guarantee fair queueing. - * Not really critical until we have locks that are (frequently) contended - * for by several threads. - */ - return 0 == cmpxchgi(&spinlock->lock, 0, 1); -} - -#endif /* UV_SPINLOCK_H_ */ diff --git a/third-party/libuv/src/unix/stream.c b/third-party/libuv/src/unix/stream.c deleted file mode 100644 index 9f5d40cf4b..0000000000 --- a/third-party/libuv/src/unix/stream.c +++ /dev/null @@ -1,1511 +0,0 @@ -/* 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 - * 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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <sys/un.h> -#include <unistd.h> -#include <limits.h> /* IOV_MAX */ - -#if defined(__APPLE__) -# include <sys/event.h> -# include <sys/time.h> -# include <sys/select.h> - -/* Forward declaration */ -typedef struct uv__stream_select_s uv__stream_select_t; - -struct uv__stream_select_s { - uv_stream_t* stream; - uv_thread_t thread; - uv_sem_t close_sem; - uv_sem_t async_sem; - uv_async_t async; - int events; - int fake_fd; - int int_fd; - int fd; -}; -#endif /* defined(__APPLE__) */ - -static void uv__stream_connect(uv_stream_t*); -static void uv__write(uv_stream_t* stream); -static void uv__read(uv_stream_t* stream); -static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events); -static size_t uv__write_req_size(uv_write_t* req); - - -/* Used by the accept() EMFILE party trick. */ -static int uv__open_cloexec(const char* path, int flags) { - int err; - int fd; - -#if defined(__linux__) - fd = open(path, flags | UV__O_CLOEXEC); - if (fd != -1) - return fd; - - if (errno != EINVAL) - return -errno; - - /* O_CLOEXEC not supported. */ -#endif - - fd = open(path, flags); - if (fd == -1) - return -errno; - - err = uv__cloexec(fd, 1); - if (err) { - uv__close(fd); - return err; - } - - return fd; -} - - -static size_t uv_count_bufs(const uv_buf_t bufs[], unsigned int nbufs) { - unsigned int i; - size_t bytes; - - bytes = 0; - for (i = 0; i < nbufs; i++) - bytes += bufs[i].len; - - return bytes; -} - - -void uv__stream_init(uv_loop_t* loop, - uv_stream_t* stream, - uv_handle_type type) { - int err; - - uv__handle_init(loop, (uv_handle_t*)stream, type); - stream->read_cb = NULL; - stream->read2_cb = NULL; - stream->alloc_cb = NULL; - stream->close_cb = NULL; - stream->connection_cb = NULL; - stream->connect_req = NULL; - stream->shutdown_req = NULL; - stream->accepted_fd = -1; - stream->delayed_error = 0; - QUEUE_INIT(&stream->write_queue); - QUEUE_INIT(&stream->write_completed_queue); - stream->write_queue_size = 0; - - if (loop->emfile_fd == -1) { - err = uv__open_cloexec("/", O_RDONLY); - if (err >= 0) - loop->emfile_fd = err; - } - -#if defined(__APPLE__) - stream->select = NULL; -#endif /* defined(__APPLE_) */ - - uv__io_init(&stream->io_watcher, uv__stream_io, -1); -} - - -static void uv__stream_osx_interrupt_select(uv_stream_t* stream) { -#if defined(__APPLE__) - /* Notify select() thread about state change */ - uv__stream_select_t* s; - int r; - - s = stream->select; - if (s == NULL) - return; - - /* Interrupt select() loop - * NOTE: fake_fd and int_fd are socketpair(), thus writing to one will - * emit read event on other side - */ - do - r = write(s->fake_fd, "x", 1); - while (r == -1 && errno == EINTR); - - assert(r == 1); -#else /* !defined(__APPLE__) */ - /* No-op on any other platform */ -#endif /* !defined(__APPLE__) */ -} - - -#if defined(__APPLE__) -static void uv__stream_osx_select(void* arg) { - uv_stream_t* stream; - uv__stream_select_t* s; - char buf[1024]; - fd_set sread; - fd_set swrite; - int events; - int fd; - int r; - int max_fd; - - stream = arg; - s = stream->select; - fd = s->fd; - - if (fd > s->int_fd) - max_fd = fd; - else - max_fd = s->int_fd; - - while (1) { - /* Terminate on semaphore */ - if (uv_sem_trywait(&s->close_sem) == 0) - break; - - /* Watch fd using select(2) */ - FD_ZERO(&sread); - FD_ZERO(&swrite); - - if (uv__io_active(&stream->io_watcher, UV__POLLIN)) - FD_SET(fd, &sread); - if (uv__io_active(&stream->io_watcher, UV__POLLOUT)) - FD_SET(fd, &swrite); - FD_SET(s->int_fd, &sread); - - /* Wait indefinitely for fd events */ - r = select(max_fd + 1, &sread, &swrite, NULL, NULL); - if (r == -1) { - if (errno == EINTR) - continue; - - /* XXX: Possible?! */ - abort(); - } - - /* Ignore timeouts */ - if (r == 0) - continue; - - /* Empty socketpair's buffer in case of interruption */ - if (FD_ISSET(s->int_fd, &sread)) - while (1) { - r = read(s->int_fd, buf, sizeof(buf)); - - if (r == sizeof(buf)) - continue; - - if (r != -1) - break; - - if (errno == EAGAIN || errno == EWOULDBLOCK) - break; - - if (errno == EINTR) - continue; - - abort(); - } - - /* Handle events */ - events = 0; - if (FD_ISSET(fd, &sread)) - events |= UV__POLLIN; - if (FD_ISSET(fd, &swrite)) - events |= UV__POLLOUT; - - assert(events != 0 || FD_ISSET(s->int_fd, &sread)); - if (events != 0) { - ACCESS_ONCE(int, s->events) = events; - - uv_async_send(&s->async); - uv_sem_wait(&s->async_sem); - - /* Should be processed at this stage */ - assert((s->events == 0) || (stream->flags & UV_CLOSING)); - } - } -} - - -static void uv__stream_osx_select_cb(uv_async_t* handle, int status) { - uv__stream_select_t* s; - uv_stream_t* stream; - int events; - - s = container_of(handle, uv__stream_select_t, async); - stream = s->stream; - - /* Get and reset stream's events */ - events = s->events; - ACCESS_ONCE(int, s->events) = 0; - uv_sem_post(&s->async_sem); - - assert(events != 0); - assert(events == (events & (UV__POLLIN | UV__POLLOUT))); - - /* Invoke callback on event-loop */ - if ((events & UV__POLLIN) && uv__io_active(&stream->io_watcher, UV__POLLIN)) - uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLIN); - - if ((events & UV__POLLOUT) && uv__io_active(&stream->io_watcher, UV__POLLOUT)) - uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLOUT); -} - - -static void uv__stream_osx_cb_close(uv_handle_t* async) { - uv__stream_select_t* s; - - s = container_of(async, uv__stream_select_t, async); - free(s); -} - - -int uv__stream_try_select(uv_stream_t* stream, int* fd) { - /* - * kqueue doesn't work with some files from /dev mount on osx. - * select(2) in separate thread for those fds - */ - - struct kevent filter[1]; - struct kevent events[1]; - struct timespec timeout; - uv__stream_select_t* s; - int fds[2]; - int err; - int ret; - int kq; - - kq = kqueue(); - if (kq == -1) { - perror("(libuv) kqueue()"); - return -errno; - } - - EV_SET(&filter[0], *fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0); - - /* Use small timeout, because we only want to capture EINVALs */ - timeout.tv_sec = 0; - timeout.tv_nsec = 1; - - ret = kevent(kq, filter, 1, events, 1, &timeout); - uv__close(kq); - - if (ret == -1) - return -errno; - - if (ret == 0 || (events[0].flags & EV_ERROR) == 0 || events[0].data != EINVAL) - return 0; - - /* At this point we definitely know that this fd won't work with kqueue */ - s = malloc(sizeof(*s)); - if (s == NULL) - return -ENOMEM; - - s->events = 0; - s->fd = *fd; - - err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb); - if (err) { - free(s); - return err; - } - - s->async.flags |= UV__HANDLE_INTERNAL; - uv__handle_unref(&s->async); - - if (uv_sem_init(&s->close_sem, 0)) - goto fatal1; - - if (uv_sem_init(&s->async_sem, 0)) - goto fatal2; - - /* Create fds for io watcher and to interrupt the select() loop. */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) - goto fatal3; - - s->fake_fd = fds[0]; - s->int_fd = fds[1]; - - if (uv_thread_create(&s->thread, uv__stream_osx_select, stream)) - goto fatal4; - - s->stream = stream; - stream->select = s; - *fd = s->fake_fd; - - return 0; - -fatal4: - uv__close(s->fake_fd); - uv__close(s->int_fd); - s->fake_fd = -1; - s->int_fd = -1; -fatal3: - uv_sem_destroy(&s->async_sem); -fatal2: - uv_sem_destroy(&s->close_sem); -fatal1: - uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); - return -errno; -} -#endif /* defined(__APPLE__) */ - - -int uv__stream_open(uv_stream_t* stream, int fd, int flags) { - assert(fd >= 0); - stream->flags |= flags; - - if (stream->type == UV_TCP) { - if ((stream->flags & UV_TCP_NODELAY) && uv__tcp_nodelay(fd, 1)) - return -errno; - - /* TODO Use delay the user passed in. */ - if ((stream->flags & UV_TCP_KEEPALIVE) && uv__tcp_keepalive(fd, 1, 60)) - return -errno; - } - - stream->io_watcher.fd = fd; - - return 0; -} - - -void uv__stream_destroy(uv_stream_t* stream) { - uv_write_t* req; - QUEUE* q; - - assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT)); - assert(stream->flags & UV_CLOSED); - - if (stream->connect_req) { - uv__req_unregister(stream->loop, stream->connect_req); - stream->connect_req->cb(stream->connect_req, -ECANCELED); - stream->connect_req = NULL; - } - - while (!QUEUE_EMPTY(&stream->write_queue)) { - q = QUEUE_HEAD(&stream->write_queue); - QUEUE_REMOVE(q); - - req = QUEUE_DATA(q, uv_write_t, queue); - uv__req_unregister(stream->loop, req); - - if (req->bufs != req->bufsml) - free(req->bufs); - req->bufs = NULL; - - if (req->cb != NULL) - req->cb(req, -ECANCELED); - } - - while (!QUEUE_EMPTY(&stream->write_completed_queue)) { - q = QUEUE_HEAD(&stream->write_completed_queue); - QUEUE_REMOVE(q); - - req = QUEUE_DATA(q, uv_write_t, queue); - uv__req_unregister(stream->loop, req); - - if (req->bufs != NULL) { - stream->write_queue_size -= uv__write_req_size(req); - if (req->bufs != req->bufsml) - free(req->bufs); - req->bufs = NULL; - } - - if (req->cb) - req->cb(req, req->error); - } - - if (stream->shutdown_req) { - /* The ECANCELED error code is a lie, the shutdown(2) syscall is a - * fait accompli at this point. Maybe we should revisit this in v0.11. - * A possible reason for leaving it unchanged is that it informs the - * callee that the handle has been destroyed. - */ - uv__req_unregister(stream->loop, stream->shutdown_req); - stream->shutdown_req->cb(stream->shutdown_req, -ECANCELED); - stream->shutdown_req = NULL; - } -} - - -/* Implements a best effort approach to mitigating accept() EMFILE errors. - * We have a spare file descriptor stashed away that we close to get below - * the EMFILE limit. Next, we accept all pending connections and close them - * immediately to signal the clients that we're overloaded - and we are, but - * we still keep on trucking. - * - * There is one caveat: it's not reliable in a multi-threaded environment. - * The file descriptor limit is per process. Our party trick fails if another - * thread opens a file or creates a socket in the time window between us - * calling close() and accept(). - */ -static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) { - int err; - - if (loop->emfile_fd == -1) - return -EMFILE; - - uv__close(loop->emfile_fd); - loop->emfile_fd = -1; - - do { - err = uv__accept(accept_fd); - if (err >= 0) - uv__close(err); - } while (err >= 0 || err == -EINTR); - - SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY)); - return err; -} - - -#if defined(UV_HAVE_KQUEUE) -# define UV_DEC_BACKLOG(w) w->rcount--; -#else -# define UV_DEC_BACKLOG(w) /* no-op */ -#endif /* defined(UV_HAVE_KQUEUE) */ - - -void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - uv_stream_t* stream; - int err; - - stream = container_of(w, uv_stream_t, io_watcher); - assert(events == UV__POLLIN); - assert(stream->accepted_fd == -1); - assert(!(stream->flags & UV_CLOSING)); - - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN); - - /* connection_cb can close the server socket while we're - * in the loop so check it on each iteration. - */ - while (uv__stream_fd(stream) != -1) { - assert(stream->accepted_fd == -1); - -#if defined(UV_HAVE_KQUEUE) - if (w->rcount <= 0) - return; -#endif /* defined(UV_HAVE_KQUEUE) */ - - err = uv__accept(uv__stream_fd(stream)); - if (err < 0) { - if (err == -EAGAIN || err == -EWOULDBLOCK) - return; /* Not an error. */ - - if (err == -ECONNABORTED) - continue; /* Ignore. Nothing we can do about that. */ - - if (err == -EMFILE || err == -ENFILE) { - err = uv__emfile_trick(loop, uv__stream_fd(stream)); - if (err == -EAGAIN || err == -EWOULDBLOCK) - break; - } - - stream->connection_cb(stream, err); - continue; - } - - UV_DEC_BACKLOG(w) - stream->accepted_fd = err; - stream->connection_cb(stream, 0); - - if (stream->accepted_fd != -1) { - /* The user hasn't yet accepted called uv_accept() */ - uv__io_stop(loop, &stream->io_watcher, UV__POLLIN); - return; - } - - if (stream->type == UV_TCP && (stream->flags & UV_TCP_SINGLE_ACCEPT)) { - /* Give other processes a chance to accept connections. */ - struct timespec timeout = { 0, 1 }; - nanosleep(&timeout, NULL); - } - } -} - - -#undef UV_DEC_BACKLOG - - -int uv_accept(uv_stream_t* server, uv_stream_t* client) { - int err; - - /* TODO document this */ - assert(server->loop == client->loop); - - if (server->accepted_fd == -1) - return -EAGAIN; - - switch (client->type) { - case UV_NAMED_PIPE: - case UV_TCP: - err = uv__stream_open(client, - server->accepted_fd, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); - if (err) { - /* TODO handle error */ - uv__close(server->accepted_fd); - server->accepted_fd = -1; - return err; - } - break; - - case UV_UDP: - err = uv_udp_open((uv_udp_t*) client, server->accepted_fd); - if (err) { - uv__close(server->accepted_fd); - server->accepted_fd = -1; - return err; - } - break; - - default: - assert(0); - } - - uv__io_start(server->loop, &server->io_watcher, UV__POLLIN); - server->accepted_fd = -1; - return 0; -} - - -int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { - int err; - - err = -EINVAL; - switch (stream->type) { - case UV_TCP: - err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb); - break; - - case UV_NAMED_PIPE: - err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb); - break; - - default: - assert(0); - } - - if (err == 0) - uv__handle_start(stream); - - return err; -} - - -static void uv__drain(uv_stream_t* stream) { - uv_shutdown_t* req; - int err; - - assert(QUEUE_EMPTY(&stream->write_queue)); - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); - uv__stream_osx_interrupt_select(stream); - - /* Shutdown? */ - if ((stream->flags & UV_STREAM_SHUTTING) && - !(stream->flags & UV_CLOSING) && - !(stream->flags & UV_STREAM_SHUT)) { - assert(stream->shutdown_req); - - req = stream->shutdown_req; - stream->shutdown_req = NULL; - stream->flags &= ~UV_STREAM_SHUTTING; - uv__req_unregister(stream->loop, req); - - err = 0; - if (shutdown(uv__stream_fd(stream), SHUT_WR)) - err = -errno; - - if (err == 0) - stream->flags |= UV_STREAM_SHUT; - - if (req->cb != NULL) - req->cb(req, err); - } -} - - -static size_t uv__write_req_size(uv_write_t* req) { - size_t size; - - assert(req->bufs != NULL); - size = uv_count_bufs(req->bufs + req->write_index, - req->nbufs - req->write_index); - assert(req->handle->write_queue_size >= size); - - return size; -} - - -static void uv__write_req_finish(uv_write_t* req) { - uv_stream_t* stream = req->handle; - - /* Pop the req off tcp->write_queue. */ - QUEUE_REMOVE(&req->queue); - - /* Only free when there was no error. On error, we touch up write_queue_size - * right before making the callback. The reason we don't do that right away - * is that a write_queue_size > 0 is our only way to signal to the user that - * they should stop writing - which they should if we got an error. Something - * to revisit in future revisions of the libuv API. - */ - if (req->error == 0) { - if (req->bufs != req->bufsml) - free(req->bufs); - req->bufs = NULL; - } - - /* Add it to the write_completed_queue where it will have its - * callback called in the near future. - */ - QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue); - uv__io_feed(stream->loop, &stream->io_watcher); -} - - -static int uv__handle_fd(uv_handle_t* handle) { - switch (handle->type) { - case UV_NAMED_PIPE: - case UV_TCP: - return ((uv_stream_t*) handle)->io_watcher.fd; - - case UV_UDP: - return ((uv_udp_t*) handle)->io_watcher.fd; - - default: - return -1; - } -} - -static int uv__getiovmax() { -#if defined(IOV_MAX) - return IOV_MAX; -#elif defined(_SC_IOV_MAX) - static int iovmax = -1; - if (iovmax == -1) - iovmax = sysconf(_SC_IOV_MAX); - return iovmax; -#else - return 1024; -#endif -} - -static void uv__write(uv_stream_t* stream) { - struct iovec* iov; - QUEUE* q; - uv_write_t* req; - int iovmax; - int iovcnt; - ssize_t n; - -start: - - assert(uv__stream_fd(stream) >= 0); - - if (QUEUE_EMPTY(&stream->write_queue)) - return; - - q = QUEUE_HEAD(&stream->write_queue); - req = QUEUE_DATA(q, uv_write_t, queue); - assert(req->handle == stream); - - /* - * Cast to iovec. We had to have our own uv_buf_t instead of iovec - * because Windows's WSABUF is not an iovec. - */ - assert(sizeof(uv_buf_t) == sizeof(struct iovec)); - iov = (struct iovec*) &(req->bufs[req->write_index]); - iovcnt = req->nbufs - req->write_index; - - iovmax = uv__getiovmax(); - - /* Limit iov count to avoid EINVALs from writev() */ - if (iovcnt > iovmax) - iovcnt = iovmax; - - /* - * Now do the actual writev. Note that we've been updating the pointers - * inside the iov each time we write. So there is no need to offset it. - */ - - if (req->send_handle) { - struct msghdr msg; - char scratch[64]; - struct cmsghdr *cmsg; - int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); - - assert(fd_to_send >= 0); - - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = iov; - msg.msg_iovlen = iovcnt; - msg.msg_flags = 0; - - msg.msg_control = (void*) scratch; - msg.msg_controllen = CMSG_LEN(sizeof(fd_to_send)); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = msg.msg_controllen; - - /* silence aliasing warning */ - { - void* pv = CMSG_DATA(cmsg); - int* pi = pv; - *pi = fd_to_send; - } - - do { - n = sendmsg(uv__stream_fd(stream), &msg, 0); - } - while (n == -1 && errno == EINTR); - } else { - do { - if (iovcnt == 1) { - n = write(uv__stream_fd(stream), iov[0].iov_base, iov[0].iov_len); - } else { - n = writev(uv__stream_fd(stream), iov, iovcnt); - } - } - while (n == -1 && errno == EINTR); - } - - if (n < 0) { - if (errno != EAGAIN && errno != EWOULDBLOCK) { - /* Error */ - req->error = -errno; - uv__write_req_finish(req); - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); - if (!uv__io_active(&stream->io_watcher, UV__POLLIN)) - uv__handle_stop(stream); - uv__stream_osx_interrupt_select(stream); - return; - } else if (stream->flags & UV_STREAM_BLOCKING) { - /* If this is a blocking stream, try again. */ - goto start; - } - } else { - /* Successful write */ - - while (n >= 0) { - uv_buf_t* buf = &(req->bufs[req->write_index]); - size_t len = buf->len; - - assert(req->write_index < req->nbufs); - - if ((size_t)n < len) { - buf->base += n; - buf->len -= n; - stream->write_queue_size -= n; - n = 0; - - /* There is more to write. */ - if (stream->flags & UV_STREAM_BLOCKING) { - /* - * If we're blocking then we should not be enabling the write - * watcher - instead we need to try again. - */ - goto start; - } else { - /* Break loop and ensure the watcher is pending. */ - break; - } - - } else { - /* Finished writing the buf at index req->write_index. */ - req->write_index++; - - assert((size_t)n >= len); - n -= len; - - assert(stream->write_queue_size >= len); - stream->write_queue_size -= len; - - if (req->write_index == req->nbufs) { - /* Then we're done! */ - assert(n == 0); - uv__write_req_finish(req); - /* TODO: start trying to write the next request. */ - return; - } - } - } - } - - /* Either we've counted n down to zero or we've got EAGAIN. */ - assert(n == 0 || n == -1); - - /* Only non-blocking streams should use the write_watcher. */ - assert(!(stream->flags & UV_STREAM_BLOCKING)); - - /* We're not done. */ - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT); - - /* Notify select() thread about state change */ - uv__stream_osx_interrupt_select(stream); -} - - -static void uv__write_callbacks(uv_stream_t* stream) { - uv_write_t* req; - QUEUE* q; - - while (!QUEUE_EMPTY(&stream->write_completed_queue)) { - /* Pop a req off write_completed_queue. */ - q = QUEUE_HEAD(&stream->write_completed_queue); - req = QUEUE_DATA(q, uv_write_t, queue); - QUEUE_REMOVE(q); - uv__req_unregister(stream->loop, req); - - if (req->bufs != NULL) { - stream->write_queue_size -= uv__write_req_size(req); - if (req->bufs != req->bufsml) - free(req->bufs); - req->bufs = NULL; - } - - /* NOTE: call callback AFTER freeing the request data. */ - if (req->cb) - req->cb(req, req->error); - } - - assert(QUEUE_EMPTY(&stream->write_completed_queue)); - - /* Write queue drained. */ - if (QUEUE_EMPTY(&stream->write_queue)) - uv__drain(stream); -} - - -static uv_handle_type uv__handle_type(int fd) { - struct sockaddr_storage ss; - socklen_t len; - int type; - - memset(&ss, 0, sizeof(ss)); - len = sizeof(ss); - - if (getsockname(fd, (struct sockaddr*)&ss, &len)) - return UV_UNKNOWN_HANDLE; - - len = sizeof type; - - if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len)) - return UV_UNKNOWN_HANDLE; - - if (type == SOCK_STREAM) { - switch (ss.ss_family) { - case AF_UNIX: - return UV_NAMED_PIPE; - case AF_INET: - case AF_INET6: - return UV_TCP; - } - } - - if (type == SOCK_DGRAM && - (ss.ss_family == AF_INET || ss.ss_family == AF_INET6)) - return UV_UDP; - - return UV_UNKNOWN_HANDLE; -} - - -static void uv__stream_read_cb(uv_stream_t* stream, - int status, - const uv_buf_t* buf, - uv_handle_type type) { - if (stream->read_cb != NULL) - stream->read_cb(stream, status, buf); - else - stream->read2_cb((uv_pipe_t*) stream, status, buf, type); -} - - -static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) { - stream->flags |= UV_STREAM_READ_EOF; - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN); - if (!uv__io_active(&stream->io_watcher, UV__POLLOUT)) - uv__handle_stop(stream); - uv__stream_osx_interrupt_select(stream); - uv__stream_read_cb(stream, UV_EOF, buf, UV_UNKNOWN_HANDLE); -} - - -static void uv__read(uv_stream_t* stream) { - uv_buf_t buf; - ssize_t nread; - struct msghdr msg; - struct cmsghdr* cmsg; - char cmsg_space[64]; - int count; - - stream->flags &= ~UV_STREAM_READ_PARTIAL; - - /* Prevent loop starvation when the data comes in as fast as (or faster than) - * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O. - */ - count = 32; - - /* XXX: Maybe instead of having UV_STREAM_READING we just test if - * tcp->read_cb is NULL or not? - */ - while ((stream->read_cb || stream->read2_cb) - && (stream->flags & UV_STREAM_READING) - && (count-- > 0)) { - assert(stream->alloc_cb != NULL); - - stream->alloc_cb((uv_handle_t*)stream, 64 * 1024, &buf); - if (buf.len == 0) { - /* User indicates it can't or won't handle the read. */ - uv__stream_read_cb(stream, UV_ENOBUFS, &buf, UV_UNKNOWN_HANDLE); - return; - } - - assert(buf.base != NULL); - assert(uv__stream_fd(stream) >= 0); - - if (stream->read_cb) { - do { - nread = read(uv__stream_fd(stream), buf.base, buf.len); - } - while (nread < 0 && errno == EINTR); - } else { - assert(stream->read2_cb); - /* read2_cb uses recvmsg */ - msg.msg_flags = 0; - msg.msg_iov = (struct iovec*) &buf; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - /* Set up to receive a descriptor even if one isn't in the message */ - msg.msg_controllen = 64; - msg.msg_control = (void*) cmsg_space; - - do { - nread = uv__recvmsg(uv__stream_fd(stream), &msg, 0); - } - while (nread < 0 && errno == EINTR); - } - - if (nread < 0) { - /* Error */ - if (errno == EAGAIN || errno == EWOULDBLOCK) { - /* Wait for the next one. */ - if (stream->flags & UV_STREAM_READING) { - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN); - uv__stream_osx_interrupt_select(stream); - } - uv__stream_read_cb(stream, 0, &buf, UV_UNKNOWN_HANDLE); - } else { - /* Error. User should call uv_close(). */ - uv__stream_read_cb(stream, -errno, &buf, UV_UNKNOWN_HANDLE); - assert(!uv__io_active(&stream->io_watcher, UV__POLLIN) && - "stream->read_cb(status=-1) did not call uv_close()"); - } - return; - } else if (nread == 0) { - uv__stream_eof(stream, &buf); - return; - } else { - /* Successful read */ - ssize_t buflen = buf.len; - - if (stream->read_cb) { - stream->read_cb(stream, nread, &buf); - } else { - assert(stream->read2_cb); - - /* - * XXX: Some implementations can send multiple file descriptors in a - * single message. We should be using CMSG_NXTHDR() to walk the - * chain to get at them all. This would require changing the API to - * hand these back up the caller, is a pain. - */ - - for (cmsg = CMSG_FIRSTHDR(&msg); - msg.msg_controllen > 0 && cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - - if (cmsg->cmsg_type == SCM_RIGHTS) { - if (stream->accepted_fd != -1) { - fprintf(stderr, "(libuv) ignoring extra FD received\n"); - } - - /* silence aliasing warning */ - { - void* pv = CMSG_DATA(cmsg); - int* pi = pv; - stream->accepted_fd = *pi; - } - - } else { - fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n", - cmsg->cmsg_type); - } - } - - - if (stream->accepted_fd >= 0) { - stream->read2_cb((uv_pipe_t*) stream, - nread, - &buf, - uv__handle_type(stream->accepted_fd)); - } else { - stream->read2_cb((uv_pipe_t*) stream, nread, &buf, UV_UNKNOWN_HANDLE); - } - } - - /* Return if we didn't fill the buffer, there is no more data to read. */ - if (nread < buflen) { - stream->flags |= UV_STREAM_READ_PARTIAL; - return; - } - } - } -} - - -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"); - - if (!(stream->flags & UV_STREAM_WRITABLE) || - stream->flags & UV_STREAM_SHUT || - stream->flags & UV_CLOSED || - stream->flags & UV_CLOSING) { - return -ENOTCONN; - } - - assert(uv__stream_fd(stream) >= 0); - - /* Initialize request */ - uv__req_init(stream->loop, req, UV_SHUTDOWN); - req->handle = stream; - req->cb = cb; - stream->shutdown_req = req; - stream->flags |= UV_STREAM_SHUTTING; - - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT); - uv__stream_osx_interrupt_select(stream); - - return 0; -} - - -static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - uv_stream_t* stream; - - stream = container_of(w, uv_stream_t, io_watcher); - - assert(stream->type == UV_TCP || - stream->type == UV_NAMED_PIPE || - stream->type == UV_TTY); - assert(!(stream->flags & UV_CLOSING)); - - if (stream->connect_req) { - uv__stream_connect(stream); - return; - } - - assert(uv__stream_fd(stream) >= 0); - - /* Ignore POLLHUP here. Even it it's set, there may still be data to read. */ - if (events & (UV__POLLIN | UV__POLLERR)) - uv__read(stream); - - if (uv__stream_fd(stream) == -1) - return; /* read_cb closed stream. */ - - /* Short-circuit iff POLLHUP is set, the user is still interested in read - * events and uv__read() reported a partial read but not EOF. If the EOF - * flag is set, uv__read() called read_cb with err=UV_EOF and we don't - * have to do anything. If the partial read flag is not set, we can't - * report the EOF yet because there is still data to read. - */ - if ((events & UV__POLLHUP) && - (stream->flags & UV_STREAM_READING) && - (stream->flags & UV_STREAM_READ_PARTIAL) && - !(stream->flags & UV_STREAM_READ_EOF)) { - uv_buf_t buf = { NULL, 0 }; - uv__stream_eof(stream, &buf); - } - - if (uv__stream_fd(stream) == -1) - return; /* read_cb closed stream. */ - - if (events & (UV__POLLOUT | UV__POLLERR | UV__POLLHUP)) { - uv__write(stream); - uv__write_callbacks(stream); - } -} - - -/** - * We get called here from directly following a call to connect(2). - * In order to determine if we've errored out or succeeded must call - * getsockopt. - */ -static void uv__stream_connect(uv_stream_t* stream) { - int error; - uv_connect_t* req = stream->connect_req; - socklen_t errorsize = sizeof(int); - - assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE); - assert(req); - - if (stream->delayed_error) { - /* To smooth over the differences between unixes errors that - * were reported synchronously on the first connect can be delayed - * until the next tick--which is now. - */ - error = stream->delayed_error; - stream->delayed_error = 0; - } else { - /* Normal situation: we need to get the socket error from the kernel. */ - assert(uv__stream_fd(stream) >= 0); - getsockopt(uv__stream_fd(stream), - SOL_SOCKET, - SO_ERROR, - &error, - &errorsize); - error = -error; - } - - if (error == -EINPROGRESS) - return; - - stream->connect_req = NULL; - uv__req_unregister(stream->loop, req); - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); - - if (req->cb) - req->cb(req, error); -} - - -int uv_write2(uv_write_t* req, - uv_stream_t* stream, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - int empty_queue; - - assert(nbufs > 0); - assert((stream->type == UV_TCP || - stream->type == UV_NAMED_PIPE || - stream->type == UV_TTY) && - "uv_write (unix) does not yet support other types of streams"); - - if (uv__stream_fd(stream) < 0) - return -EBADF; - - if (send_handle) { - if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) - return -EINVAL; - - /* XXX We abuse uv_write2() to send over UDP handles to child processes. - * Don't call uv__stream_fd() on those handles, it's a macro that on OS X - * evaluates to a function that operates on a uv_stream_t with a couple of - * OS X specific fields. On other Unices it does (handle)->io_watcher.fd, - * which works but only by accident. - */ - if (uv__handle_fd((uv_handle_t*) send_handle) < 0) - return -EBADF; - } - - /* It's legal for write_queue_size > 0 even when the write_queue is empty; - * it means there are error-state requests in the write_completed_queue that - * will touch up write_queue_size later, see also uv__write_req_finish(). - * We chould check that write_queue is empty instead but that implies making - * a write() syscall when we know that the handle is in error mode. - */ - empty_queue = (stream->write_queue_size == 0); - - /* Initialize the req */ - uv__req_init(stream->loop, req, UV_WRITE); - req->cb = cb; - req->handle = stream; - req->error = 0; - req->send_handle = send_handle; - QUEUE_INIT(&req->queue); - - req->bufs = req->bufsml; - if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = malloc(nbufs * sizeof(bufs[0])); - - if (req->bufs == NULL) - return -ENOMEM; - - memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0])); - req->nbufs = nbufs; - req->write_index = 0; - stream->write_queue_size += uv_count_bufs(bufs, nbufs); - - /* Append the request to write_queue. */ - QUEUE_INSERT_TAIL(&stream->write_queue, &req->queue); - - /* If the queue was empty when this function began, we should attempt to - * do the write immediately. Otherwise start the write_watcher and wait - * for the fd to become writable. - */ - if (stream->connect_req) { - /* Still connecting, do nothing. */ - } - else if (empty_queue) { - uv__write(stream); - } - else { - /* - * blocking streams should never have anything in the queue. - * if this assert fires then somehow the blocking stream isn't being - * sufficiently flushed in uv__write. - */ - assert(!(stream->flags & UV_STREAM_BLOCKING)); - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT); - uv__stream_osx_interrupt_select(stream); - } - - return 0; -} - - -/* The buffers to be written must remain valid until the callback is called. - * This is not required for the uv_buf_t array. - */ -int uv_write(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - return uv_write2(req, handle, bufs, nbufs, NULL, cb); -} - - -void uv_try_write_cb(uv_write_t* req, int status) { - /* Should not be called */ - abort(); -} - - -int uv_try_write(uv_stream_t* stream, - const uv_buf_t bufs[], - unsigned int nbufs) { - int r; - int has_pollout; - size_t written; - size_t req_size; - uv_write_t req; - - /* Connecting or already writing some data */ - if (stream->connect_req != NULL || stream->write_queue_size != 0) - return 0; - - has_pollout = uv__io_active(&stream->io_watcher, UV__POLLOUT); - - r = uv_write(&req, stream, bufs, nbufs, uv_try_write_cb); - if (r != 0) - return r; - - /* Remove not written bytes from write queue size */ - written = uv_count_bufs(bufs, nbufs); - if (req.bufs != NULL) - req_size = uv__write_req_size(&req); - else - req_size = 0; - written -= req_size; - stream->write_queue_size -= req_size; - - /* Unqueue request, regardless of immediateness */ - QUEUE_REMOVE(&req.queue); - uv__req_unregister(stream->loop, &req); - if (req.bufs != req.bufsml) - free(req.bufs); - req.bufs = NULL; - - /* Do not poll for writable, if we wasn't before calling this */ - if (!has_pollout) { - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); - uv__stream_osx_interrupt_select(stream); - } - - return (int) written; -} - - -static int uv__read_start_common(uv_stream_t* stream, - uv_alloc_cb alloc_cb, - uv_read_cb read_cb, - uv_read2_cb read2_cb) { - assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE || - stream->type == UV_TTY); - - if (stream->flags & UV_CLOSING) - return -EINVAL; - - /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just - * expresses the desired state of the user. - */ - stream->flags |= UV_STREAM_READING; - - /* TODO: try to do the read inline? */ - /* TODO: keep track of tcp state. If we've gotten a EOF then we should - * not start the IO watcher. - */ - assert(uv__stream_fd(stream) >= 0); - assert(alloc_cb); - - stream->read_cb = read_cb; - stream->read2_cb = read2_cb; - stream->alloc_cb = alloc_cb; - - uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN); - uv__handle_start(stream); - uv__stream_osx_interrupt_select(stream); - - return 0; -} - - -int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - return uv__read_start_common(stream, alloc_cb, read_cb, NULL); -} - - -int uv_read2_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, - uv_read2_cb read_cb) { - return uv__read_start_common(stream, alloc_cb, NULL, read_cb); -} - - -int uv_read_stop(uv_stream_t* stream) { - /* Sanity check. We're going to stop the handle unless it's primed for - * writing but that means there should be some kind of write action in - * progress. - */ - assert(!uv__io_active(&stream->io_watcher, UV__POLLOUT) || - !QUEUE_EMPTY(&stream->write_completed_queue) || - !QUEUE_EMPTY(&stream->write_queue) || - stream->shutdown_req != NULL || - stream->connect_req != NULL); - - stream->flags &= ~UV_STREAM_READING; - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN); - if (!uv__io_active(&stream->io_watcher, UV__POLLOUT)) - uv__handle_stop(stream); - uv__stream_osx_interrupt_select(stream); - - stream->read_cb = NULL; - stream->read2_cb = NULL; - stream->alloc_cb = NULL; - return 0; -} - - -int uv_is_readable(const uv_stream_t* stream) { - return !!(stream->flags & UV_STREAM_READABLE); -} - - -int uv_is_writable(const uv_stream_t* stream) { - return !!(stream->flags & UV_STREAM_WRITABLE); -} - - -#if defined(__APPLE__) -int uv___stream_fd(uv_stream_t* handle) { - uv__stream_select_t* s; - - assert(handle->type == UV_TCP || - handle->type == UV_TTY || - handle->type == UV_NAMED_PIPE); - - s = handle->select; - if (s != NULL) - return s->fd; - - return handle->io_watcher.fd; -} -#endif /* defined(__APPLE__) */ - - -void uv__stream_close(uv_stream_t* handle) { -#if defined(__APPLE__) - /* Terminate select loop first */ - if (handle->select != NULL) { - uv__stream_select_t* s; - - s = handle->select; - - uv_sem_post(&s->close_sem); - uv_sem_post(&s->async_sem); - uv__stream_osx_interrupt_select(handle); - uv_thread_join(&s->thread); - uv_sem_destroy(&s->close_sem); - uv_sem_destroy(&s->async_sem); - uv__close(s->fake_fd); - uv__close(s->int_fd); - uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); - - handle->select = NULL; - } -#endif /* defined(__APPLE__) */ - - uv__io_close(handle->loop, &handle->io_watcher); - uv_read_stop(handle); - uv__handle_stop(handle); - - if (handle->io_watcher.fd != -1) { - /* Don't close stdio file descriptors. Nothing good comes from it. */ - if (handle->io_watcher.fd > STDERR_FILENO) - uv__close(handle->io_watcher.fd); - handle->io_watcher.fd = -1; - } - - if (handle->accepted_fd != -1) { - uv__close(handle->accepted_fd); - handle->accepted_fd = -1; - } - - assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT)); -} - - -int uv_stream_set_blocking(uv_stream_t* handle, int blocking) { - assert(0 && "implement me"); - abort(); - return 0; -} diff --git a/third-party/libuv/src/unix/sunos.c b/third-party/libuv/src/unix/sunos.c deleted file mode 100644 index f31a23fb3c..0000000000 --- a/third-party/libuv/src/unix/sunos.c +++ /dev/null @@ -1,734 +0,0 @@ -/* 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 - * 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 <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <errno.h> - -#ifndef SUNOS_NO_IFADDRS -# include <ifaddrs.h> -#endif -#include <net/if.h> -#include <net/if_dl.h> - -#include <sys/loadavg.h> -#include <sys/time.h> -#include <unistd.h> -#include <kstat.h> -#include <fcntl.h> - -#include <sys/port.h> -#include <port.h> - -#define PORT_FIRED 0x69 -#define PORT_UNUSED 0x0 -#define PORT_LOADED 0x99 -#define PORT_DELETED -1 - -#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64) -#define PROCFS_FILE_OFFSET_BITS_HACK 1 -#undef _FILE_OFFSET_BITS -#else -#define PROCFS_FILE_OFFSET_BITS_HACK 0 -#endif - -#include <procfs.h> - -#if (PROCFS_FILE_OFFSET_BITS_HACK - 0 == 1) -#define _FILE_OFFSET_BITS 64 -#endif - - -int uv__platform_loop_init(uv_loop_t* loop, int default_loop) { - int err; - int fd; - - loop->fs_fd = -1; - loop->backend_fd = -1; - - fd = port_create(); - if (fd == -1) - return -errno; - - err = uv__cloexec(fd, 1); - if (err) { - uv__close(fd); - return err; - } - loop->backend_fd = fd; - - return 0; -} - - -void uv__platform_loop_delete(uv_loop_t* loop) { - if (loop->fs_fd != -1) { - uv__close(loop->fs_fd); - loop->fs_fd = -1; - } - - if (loop->backend_fd != -1) { - uv__close(loop->backend_fd); - loop->backend_fd = -1; - } -} - - -void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { - struct port_event* events; - uintptr_t i; - uintptr_t nfds; - - assert(loop->watchers != NULL); - - events = (struct port_event*) loop->watchers[loop->nwatchers]; - nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; - if (events == NULL) - return; - - /* Invalidate events with same file descriptor */ - for (i = 0; i < nfds; i++) - if ((int) events[i].portev_object == fd) - events[i].portev_object = -1; -} - - -void uv__io_poll(uv_loop_t* loop, int timeout) { - struct port_event events[1024]; - struct port_event* pe; - struct timespec spec; - QUEUE* q; - uv__io_t* w; - uint64_t base; - uint64_t diff; - unsigned int nfds; - unsigned int i; - int saved_errno; - int nevents; - int count; - int fd; - - if (loop->nfds == 0) { - assert(QUEUE_EMPTY(&loop->watcher_queue)); - return; - } - - while (!QUEUE_EMPTY(&loop->watcher_queue)) { - q = QUEUE_HEAD(&loop->watcher_queue); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - w = QUEUE_DATA(q, uv__io_t, watcher_queue); - assert(w->pevents != 0); - - if (port_associate(loop->backend_fd, PORT_SOURCE_FD, w->fd, w->pevents, 0)) - abort(); - - w->events = w->pevents; - } - - assert(timeout >= -1); - base = loop->time; - count = 48; /* Benchmarks suggest this gives the best throughput. */ - - for (;;) { - if (timeout != -1) { - spec.tv_sec = timeout / 1000; - spec.tv_nsec = (timeout % 1000) * 1000000; - } - - /* Work around a kernel bug where nfds is not updated. */ - events[0].portev_source = 0; - - nfds = 1; - saved_errno = 0; - if (port_getn(loop->backend_fd, - events, - ARRAY_SIZE(events), - &nfds, - timeout == -1 ? NULL : &spec)) { - /* Work around another kernel bug: port_getn() may return events even - * on error. - */ - if (errno == EINTR || errno == ETIME) - saved_errno = errno; - else - abort(); - } - - /* Update loop->time unconditionally. It's tempting to skip the update when - * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the - * operating system didn't reschedule our process while in the syscall. - */ - SAVE_ERRNO(uv__update_time(loop)); - - if (events[0].portev_source == 0) { - if (timeout == 0) - return; - - if (timeout == -1) - continue; - - goto update_timeout; - } - - if (nfds == 0) { - assert(timeout != -1); - return; - } - - nevents = 0; - - assert(loop->watchers != NULL); - loop->watchers[loop->nwatchers] = (void*) events; - loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; - for (i = 0; i < nfds; i++) { - pe = events + i; - fd = pe->portev_object; - - /* Skip invalidated events, see uv__platform_invalidate_fd */ - if (fd == -1) - continue; - - assert(fd >= 0); - assert((unsigned) fd < loop->nwatchers); - - w = loop->watchers[fd]; - - /* File descriptor that we've stopped watching, ignore. */ - if (w == NULL) - continue; - - w->cb(loop, w, pe->portev_events); - nevents++; - - if (w != loop->watchers[fd]) - continue; /* Disabled by callback. */ - - /* Events Ports operates in oneshot mode, rearm timer on next run. */ - if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) - QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); - } - loop->watchers[loop->nwatchers] = NULL; - loop->watchers[loop->nwatchers + 1] = NULL; - - if (nevents != 0) { - if (nfds == ARRAY_SIZE(events) && --count != 0) { - /* Poll for more events but don't block this time. */ - timeout = 0; - continue; - } - return; - } - - if (saved_errno == ETIME) { - assert(timeout != -1); - return; - } - - if (timeout == 0) - return; - - if (timeout == -1) - continue; - -update_timeout: - assert(timeout > 0); - - diff = loop->time - base; - if (diff >= (uint64_t) timeout) - return; - - timeout -= diff; - } -} - - -uint64_t uv__hrtime(uv_clocktype_t type) { - return gethrtime(); -} - - -/* - * 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. - */ -int uv_exepath(char* buffer, size_t* size) { - ssize_t res; - char buf[128]; - - if (buffer == NULL || size == NULL) - return -EINVAL; - - snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid()); - res = readlink(buf, buffer, *size - 1); - if (res == -1) - return -errno; - - buffer[res] = '\0'; - *size = res; - return 0; -} - - -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]) { - (void) getloadavg(avg, 3); -} - - -#if defined(PORT_SOURCE_FILE) - -static int uv__fs_event_rearm(uv_fs_event_t *handle) { - if (handle->fd == -1) - return -EBADF; - - if (port_associate(handle->loop->fs_fd, - PORT_SOURCE_FILE, - (uintptr_t) &handle->fo, - FILE_ATTRIB | FILE_MODIFIED, - handle) == -1) { - return -errno; - } - handle->fd = PORT_LOADED; - - return 0; -} - - -static void uv__fs_event_read(uv_loop_t* loop, - uv__io_t* w, - unsigned int revents) { - uv_fs_event_t *handle = NULL; - timespec_t timeout; - port_event_t pe; - int events; - int r; - - (void) w; - (void) revents; - - do { - uint_t n = 1; - - /* - * Note that our use of port_getn() here (and not port_get()) is deliberate: - * there is a bug in event ports (Sun bug 6456558) whereby a zeroed timeout - * causes port_get() to return success instead of ETIME when there aren't - * actually any events (!); by using port_getn() in lieu of port_get(), - * we can at least workaround the bug by checking for zero returned events - * and treating it as we would ETIME. - */ - do { - memset(&timeout, 0, sizeof timeout); - r = port_getn(loop->fs_fd, &pe, 1, &n, &timeout); - } - while (r == -1 && errno == EINTR); - - if ((r == -1 && errno == ETIME) || n == 0) - break; - - handle = (uv_fs_event_t*) pe.portev_user; - assert((r == 0) && "unexpected port_get() error"); - - events = 0; - if (pe.portev_events & (FILE_ATTRIB | FILE_MODIFIED)) - events |= UV_CHANGE; - if (pe.portev_events & ~(FILE_ATTRIB | FILE_MODIFIED)) - events |= UV_RENAME; - assert(events != 0); - handle->fd = PORT_FIRED; - handle->cb(handle, NULL, events, 0); - } - while (handle->fd != PORT_DELETED); - - if (handle != NULL && handle->fd != PORT_DELETED) - uv__fs_event_rearm(handle); /* FIXME(bnoordhuis) Check return code. */ -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); - return 0; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* filename, - unsigned int flags) { - int portfd; - int first_run; - - if (uv__is_active(handle)) - return -EINVAL; - - first_run = 0; - if (handle->loop->fs_fd == -1) { - portfd = port_create(); - if (portfd == -1) - return -errno; - handle->loop->fs_fd = portfd; - first_run = 1; - } - - uv__handle_start(handle); - handle->filename = strdup(filename); - handle->fd = PORT_UNUSED; - handle->cb = cb; - - memset(&handle->fo, 0, sizeof handle->fo); - handle->fo.fo_name = handle->filename; - uv__fs_event_rearm(handle); /* FIXME(bnoordhuis) Check return code. */ - - if (first_run) { - uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd); - uv__io_start(handle->loop, &handle->loop->fs_event_watcher, UV__POLLIN); - } - - return 0; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - if (!uv__is_active(handle)) - return -EINVAL; - - if (handle->fd == PORT_FIRED || handle->fd == PORT_LOADED) { - port_dissociate(handle->loop->fs_fd, - PORT_SOURCE_FILE, - (uintptr_t) &handle->fo); - } - - handle->fd = PORT_DELETED; - free(handle->filename); - handle->filename = NULL; - handle->fo.fo_name = NULL; - uv__handle_stop(handle); - - return 0; -} - -void uv__fs_event_close(uv_fs_event_t* handle) { - uv_fs_event_stop(handle); -} - -#else /* !defined(PORT_SOURCE_FILE) */ - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - return -ENOSYS; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* filename, - unsigned int flags) { - return -ENOSYS; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - return -ENOSYS; -} - - -void uv__fs_event_close(uv_fs_event_t* handle) { - UNREACHABLE(); -} - -#endif /* defined(PORT_SOURCE_FILE) */ - - -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (size > 0) { - buffer[0] = '\0'; - } - return 0; -} - - -int uv_resident_set_memory(size_t* rss) { - psinfo_t psinfo; - int err; - int fd; - - fd = open("/proc/self/psinfo", O_RDONLY); - if (fd == -1) - return -errno; - - /* FIXME(bnoordhuis) Handle EINTR. */ - err = -EINVAL; - if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) { - *rss = (size_t)psinfo.pr_rssize * 1024; - err = 0; - } - uv__close(fd); - - return err; -} - - -int uv_uptime(double* uptime) { - kstat_ctl_t *kc; - kstat_t *ksp; - kstat_named_t *knp; - - long hz = sysconf(_SC_CLK_TCK); - - kc = kstat_open(); - if (kc == NULL) - return -EPERM; - - ksp = kstat_lookup(kc, (char*) "unix", 0, (char*) "system_misc"); - if (kstat_read(kc, ksp, NULL) == -1) { - *uptime = -1; - } else { - knp = (kstat_named_t*) kstat_data_lookup(ksp, (char*) "clk_intr"); - *uptime = knp->value.ul / hz; - } - kstat_close(kc); - - return 0; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - int lookup_instance; - kstat_ctl_t *kc; - kstat_t *ksp; - kstat_named_t *knp; - uv_cpu_info_t* cpu_info; - - kc = kstat_open(); - if (kc == NULL) - return -EPERM; - - /* Get count of cpus */ - lookup_instance = 0; - while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) { - lookup_instance++; - } - - *cpu_infos = malloc(lookup_instance * sizeof(**cpu_infos)); - if (!(*cpu_infos)) { - kstat_close(kc); - return -ENOMEM; - } - - *count = lookup_instance; - - cpu_info = *cpu_infos; - lookup_instance = 0; - while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) { - if (kstat_read(kc, ksp, NULL) == -1) { - cpu_info->speed = 0; - cpu_info->model = NULL; - } else { - knp = kstat_data_lookup(ksp, (char*) "clock_MHz"); - assert(knp->data_type == KSTAT_DATA_INT32 || - knp->data_type == KSTAT_DATA_INT64); - cpu_info->speed = (knp->data_type == KSTAT_DATA_INT32) ? knp->value.i32 - : knp->value.i64; - - knp = kstat_data_lookup(ksp, (char*) "brand"); - assert(knp->data_type == KSTAT_DATA_STRING); - cpu_info->model = strdup(KSTAT_NAMED_STR_PTR(knp)); - } - - lookup_instance++; - cpu_info++; - } - - cpu_info = *cpu_infos; - lookup_instance = 0; - for (;;) { - ksp = kstat_lookup(kc, (char*) "cpu", lookup_instance, (char*) "sys"); - - if (ksp == NULL) - break; - - if (kstat_read(kc, ksp, NULL) == -1) { - cpu_info->cpu_times.user = 0; - cpu_info->cpu_times.nice = 0; - cpu_info->cpu_times.sys = 0; - cpu_info->cpu_times.idle = 0; - cpu_info->cpu_times.irq = 0; - } else { - knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_user"); - assert(knp->data_type == KSTAT_DATA_UINT64); - cpu_info->cpu_times.user = knp->value.ui64; - - knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_kernel"); - assert(knp->data_type == KSTAT_DATA_UINT64); - cpu_info->cpu_times.sys = knp->value.ui64; - - knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_idle"); - assert(knp->data_type == KSTAT_DATA_UINT64); - cpu_info->cpu_times.idle = knp->value.ui64; - - knp = kstat_data_lookup(ksp, (char*) "intr"); - assert(knp->data_type == KSTAT_DATA_UINT64); - cpu_info->cpu_times.irq = knp->value.ui64; - cpu_info->cpu_times.nice = 0; - } - - lookup_instance++; - cpu_info++; - } - - kstat_close(kc); - - return 0; -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - free(cpu_infos[i].model); - } - - free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { -#ifdef SUNOS_NO_IFADDRS - return -ENOSYS; -#else - uv_interface_address_t* address; - struct sockaddr_dl* sa_addr; - struct ifaddrs* addrs; - struct ifaddrs* ent; - int i; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { - continue; - } - - (*count)++; - } - - *addresses = malloc(*count * sizeof(**addresses)); - if (!(*addresses)) - return -ENOMEM; - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - address->name = strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!((ent->ifa_flags & IFF_PRIVATE) || - (ent->ifa_flags & IFF_LOOPBACK)); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -#endif /* SUNOS_NO_IFADDRS */ -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - free(addresses[i].name); - } - - free(addresses); -} diff --git a/third-party/libuv/src/unix/tcp.c b/third-party/libuv/src/unix/tcp.c deleted file mode 100644 index 2c36dc3ffc..0000000000 --- a/third-party/libuv/src/unix/tcp.c +++ /dev/null @@ -1,312 +0,0 @@ -/* 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 - * 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 <stdlib.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> - - -int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) { - uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP); - return 0; -} - - -static int maybe_new_socket(uv_tcp_t* handle, int domain, int flags) { - int sockfd; - int err; - - if (uv__stream_fd(handle) != -1) - return 0; - - err = uv__socket(domain, SOCK_STREAM, 0); - if (err < 0) - return err; - sockfd = err; - - err = uv__stream_open((uv_stream_t*) handle, sockfd, flags); - if (err) { - uv__close(sockfd); - return err; - } - - return 0; -} - - -int uv__tcp_bind(uv_tcp_t* tcp, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - int on; - - err = maybe_new_socket(tcp, - addr->sa_family, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); - if (err) - return err; - - on = 1; - if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) - return -errno; - -#ifdef IPV6_V6ONLY - if (addr->sa_family == AF_INET6) { - on = (flags & UV_TCP_IPV6ONLY) != 0; - if (setsockopt(tcp->io_watcher.fd, - IPPROTO_IPV6, - IPV6_V6ONLY, - &on, - sizeof on) == -1) { - return -errno; - } - } -#endif - - errno = 0; - if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE) - return -errno; - - tcp->delayed_error = -errno; - return 0; -} - - -int uv__tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb) { - int err; - int r; - - assert(handle->type == UV_TCP); - - if (handle->connect_req != NULL) - return -EALREADY; /* FIXME(bnoordhuis) -EINVAL or maybe -EBUSY. */ - - err = maybe_new_socket(handle, - addr->sa_family, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); - if (err) - return err; - - handle->delayed_error = 0; - - do - r = connect(uv__stream_fd(handle), addr, addrlen); - while (r == -1 && errno == EINTR); - - if (r == -1) { - if (errno == EINPROGRESS) - ; /* not an error */ - else if (errno == ECONNREFUSED) - /* If we get a ECONNREFUSED wait until the next tick to report the - * error. Solaris wants to report immediately--other unixes want to - * wait. - */ - handle->delayed_error = -errno; - else - return -errno; - } - - uv__req_init(handle->loop, req, UV_CONNECT); - req->cb = cb; - req->handle = (uv_stream_t*) handle; - QUEUE_INIT(&req->queue); - handle->connect_req = req; - - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT); - - if (handle->delayed_error) - uv__io_feed(handle->loop, &handle->io_watcher); - - return 0; -} - - -int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { - return uv__stream_open((uv_stream_t*)handle, - sock, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); -} - - -int uv_tcp_getsockname(uv_tcp_t* handle, - struct sockaddr* name, - int* namelen) { - socklen_t socklen; - - if (handle->delayed_error) - return handle->delayed_error; - - if (uv__stream_fd(handle) < 0) - return -EINVAL; /* FIXME(bnoordhuis) -EBADF */ - - /* sizeof(socklen_t) != sizeof(int) on some systems. */ - socklen = (socklen_t) *namelen; - - if (getsockname(uv__stream_fd(handle), name, &socklen)) - return -errno; - - *namelen = (int) socklen; - return 0; -} - - -int uv_tcp_getpeername(uv_tcp_t* handle, - struct sockaddr* name, - int* namelen) { - socklen_t socklen; - - if (handle->delayed_error) - return handle->delayed_error; - - if (uv__stream_fd(handle) < 0) - return -EINVAL; /* FIXME(bnoordhuis) -EBADF */ - - /* sizeof(socklen_t) != sizeof(int) on some systems. */ - socklen = (socklen_t) *namelen; - - if (getpeername(uv__stream_fd(handle), name, &socklen)) - return -errno; - - *namelen = (int) socklen; - return 0; -} - - -int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { - static int single_accept = -1; - int err; - - if (tcp->delayed_error) - return tcp->delayed_error; - - if (single_accept == -1) { - const char* val = getenv("UV_TCP_SINGLE_ACCEPT"); - single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */ - } - - if (single_accept) - tcp->flags |= UV_TCP_SINGLE_ACCEPT; - - err = maybe_new_socket(tcp, AF_INET, UV_STREAM_READABLE); - if (err) - return err; - - if (listen(tcp->io_watcher.fd, backlog)) - return -errno; - - tcp->connection_cb = cb; - - /* Start listening for connections. */ - tcp->io_watcher.cb = uv__server_io; - uv__io_start(tcp->loop, &tcp->io_watcher, UV__POLLIN); - - return 0; -} - - -int uv__tcp_nodelay(int fd, int on) { - return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); -} - - -int uv__tcp_keepalive(int fd, int on, unsigned int delay) { - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on))) - return -errno; - -#ifdef TCP_KEEPIDLE - if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay))) - return -errno; -#endif - - /* Solaris/SmartOS, if you don't support keep-alive, - * then don't advertise it in your system headers... - */ - /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */ -#if defined(TCP_KEEPALIVE) && !defined(__sun) - if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay))) - return -errno; -#endif - - return 0; -} - - -int uv_tcp_nodelay(uv_tcp_t* handle, int on) { - int err; - - if (uv__stream_fd(handle) != -1) { - err = uv__tcp_nodelay(uv__stream_fd(handle), on); - if (err) - return err; - } - - if (on) - handle->flags |= UV_TCP_NODELAY; - else - handle->flags &= ~UV_TCP_NODELAY; - - return 0; -} - - -int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) { - int err; - - if (uv__stream_fd(handle) != -1) { - err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay); - if (err) - return err; - } - - if (on) - handle->flags |= UV_TCP_KEEPALIVE; - else - handle->flags &= ~UV_TCP_KEEPALIVE; - - /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge - * uv_tcp_t with an int that's almost never used... - */ - - return 0; -} - - -int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { - if (enable) - handle->flags &= ~UV_TCP_SINGLE_ACCEPT; - else - handle->flags |= UV_TCP_SINGLE_ACCEPT; - return 0; -} - - -void uv__tcp_close(uv_tcp_t* handle) { - uv__stream_close((uv_stream_t*)handle); -} diff --git a/third-party/libuv/src/unix/thread.c b/third-party/libuv/src/unix/thread.c deleted file mode 100644 index f2ce082842..0000000000 --- a/third-party/libuv/src/unix/thread.c +++ /dev/null @@ -1,464 +0,0 @@ -/* 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 - * 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 <pthread.h> -#include <assert.h> -#include <errno.h> - -#include <sys/time.h> - -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - -int uv_thread_join(uv_thread_t *tid) { - return -pthread_join(*tid, NULL); -} - - -int uv_mutex_init(uv_mutex_t* mutex) { -#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK) - return -pthread_mutex_init(mutex, NULL); -#else - pthread_mutexattr_t attr; - int err; - - if (pthread_mutexattr_init(&attr)) - abort(); - - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)) - abort(); - - err = pthread_mutex_init(mutex, &attr); - - if (pthread_mutexattr_destroy(&attr)) - abort(); - - return -err; -#endif -} - - -void uv_mutex_destroy(uv_mutex_t* mutex) { - if (pthread_mutex_destroy(mutex)) - abort(); -} - - -void uv_mutex_lock(uv_mutex_t* mutex) { - if (pthread_mutex_lock(mutex)) - abort(); -} - - -int uv_mutex_trylock(uv_mutex_t* mutex) { - int err; - - /* FIXME(bnoordhuis) EAGAIN means recursive lock limit reached. Arguably - * a bug, should probably abort rather than return -EAGAIN. - */ - err = pthread_mutex_trylock(mutex); - if (err && err != EBUSY && err != EAGAIN) - abort(); - - return -err; -} - - -void uv_mutex_unlock(uv_mutex_t* mutex) { - if (pthread_mutex_unlock(mutex)) - abort(); -} - - -int uv_rwlock_init(uv_rwlock_t* rwlock) { - return -pthread_rwlock_init(rwlock, NULL); -} - - -void uv_rwlock_destroy(uv_rwlock_t* rwlock) { - if (pthread_rwlock_destroy(rwlock)) - abort(); -} - - -void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { - if (pthread_rwlock_rdlock(rwlock)) - abort(); -} - - -int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { - int err; - - err = pthread_rwlock_tryrdlock(rwlock); - if (err && err != EBUSY && err != EAGAIN) - abort(); - - return -err; -} - - -void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { - if (pthread_rwlock_unlock(rwlock)) - abort(); -} - - -void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { - if (pthread_rwlock_wrlock(rwlock)) - abort(); -} - - -int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { - int err; - - err = pthread_rwlock_trywrlock(rwlock); - if (err && err != EBUSY && err != EAGAIN) - abort(); - - return -err; -} - - -void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { - if (pthread_rwlock_unlock(rwlock)) - abort(); -} - - -void uv_once(uv_once_t* guard, void (*callback)(void)) { - if (pthread_once(guard, callback)) - abort(); -} - -#if defined(__APPLE__) && defined(__MACH__) - -int uv_sem_init(uv_sem_t* sem, unsigned int value) { - kern_return_t err; - - err = semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value); - if (err == KERN_SUCCESS) - return 0; - if (err == KERN_INVALID_ARGUMENT) - return -EINVAL; - if (err == KERN_RESOURCE_SHORTAGE) - return -ENOMEM; - - abort(); - return -EINVAL; /* Satisfy the compiler. */ -} - - -void uv_sem_destroy(uv_sem_t* sem) { - if (semaphore_destroy(mach_task_self(), *sem)) - abort(); -} - - -void uv_sem_post(uv_sem_t* sem) { - if (semaphore_signal(*sem)) - abort(); -} - - -void uv_sem_wait(uv_sem_t* sem) { - int r; - - do - r = semaphore_wait(*sem); - while (r == KERN_ABORTED); - - if (r != KERN_SUCCESS) - abort(); -} - - -int uv_sem_trywait(uv_sem_t* sem) { - mach_timespec_t interval; - kern_return_t err; - - interval.tv_sec = 0; - interval.tv_nsec = 0; - - err = semaphore_timedwait(*sem, interval); - if (err == KERN_SUCCESS) - return 0; - if (err == KERN_OPERATION_TIMED_OUT) - return -EAGAIN; - - abort(); - return -EINVAL; /* Satisfy the compiler. */ -} - -#else /* !(defined(__APPLE__) && defined(__MACH__)) */ - -int uv_sem_init(uv_sem_t* sem, unsigned int value) { - if (sem_init(sem, 0, value)) - return -errno; - return 0; -} - - -void uv_sem_destroy(uv_sem_t* sem) { - if (sem_destroy(sem)) - abort(); -} - - -void uv_sem_post(uv_sem_t* sem) { - if (sem_post(sem)) - abort(); -} - - -void uv_sem_wait(uv_sem_t* sem) { - int r; - - do - r = sem_wait(sem); - while (r == -1 && errno == EINTR); - - if (r) - abort(); -} - - -int uv_sem_trywait(uv_sem_t* sem) { - int r; - - do - r = sem_trywait(sem); - while (r == -1 && errno == EINTR); - - if (r) { - if (errno == EAGAIN) - return -EAGAIN; - abort(); - } - - return 0; -} - -#endif /* defined(__APPLE__) && defined(__MACH__) */ - - -#if defined(__APPLE__) && defined(__MACH__) - -int uv_cond_init(uv_cond_t* cond) { - return -pthread_cond_init(cond, NULL); -} - -#else /* !(defined(__APPLE__) && defined(__MACH__)) */ - -int uv_cond_init(uv_cond_t* cond) { - pthread_condattr_t attr; - int err; - - err = pthread_condattr_init(&attr); - if (err) - return -err; - -#if !defined(__ANDROID__) - err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); - if (err) - goto error2; -#endif - - err = pthread_cond_init(cond, &attr); - if (err) - goto error2; - - err = pthread_condattr_destroy(&attr); - if (err) - goto error; - - return 0; - -error: - pthread_cond_destroy(cond); -error2: - pthread_condattr_destroy(&attr); - return -err; -} - -#endif /* defined(__APPLE__) && defined(__MACH__) */ - -void uv_cond_destroy(uv_cond_t* cond) { - if (pthread_cond_destroy(cond)) - abort(); -} - -void uv_cond_signal(uv_cond_t* cond) { - if (pthread_cond_signal(cond)) - abort(); -} - -void uv_cond_broadcast(uv_cond_t* cond) { - if (pthread_cond_broadcast(cond)) - abort(); -} - -void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (pthread_cond_wait(cond, mutex)) - abort(); -} - - -int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) { - int r; - struct timespec ts; - -#if defined(__APPLE__) && defined(__MACH__) - ts.tv_sec = timeout / NANOSEC; - ts.tv_nsec = timeout % NANOSEC; - r = pthread_cond_timedwait_relative_np(cond, mutex, &ts); -#else - timeout += uv__hrtime(UV_CLOCK_PRECISE); - ts.tv_sec = timeout / NANOSEC; - ts.tv_nsec = timeout % NANOSEC; -#if defined(__ANDROID__) - /* - * The bionic pthread implementation doesn't support CLOCK_MONOTONIC, - * but has this alternative function instead. - */ - r = pthread_cond_timedwait_monotonic_np(cond, mutex, &ts); -#else - r = pthread_cond_timedwait(cond, mutex, &ts); -#endif /* __ANDROID__ */ -#endif - - - if (r == 0) - return 0; - - if (r == ETIMEDOUT) - return -ETIMEDOUT; - - abort(); - return -EINVAL; /* Satisfy the compiler. */ -} - - -#if defined(__APPLE__) && defined(__MACH__) - -int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { - int err; - - barrier->n = count; - barrier->count = 0; - - err = uv_mutex_init(&barrier->mutex); - if (err) - return -err; - - err = uv_sem_init(&barrier->turnstile1, 0); - if (err) - goto error2; - - err = uv_sem_init(&barrier->turnstile2, 1); - if (err) - goto error; - - return 0; - -error: - uv_sem_destroy(&barrier->turnstile1); -error2: - uv_mutex_destroy(&barrier->mutex); - return -err; - -} - - -void uv_barrier_destroy(uv_barrier_t* barrier) { - uv_sem_destroy(&barrier->turnstile2); - uv_sem_destroy(&barrier->turnstile1); - uv_mutex_destroy(&barrier->mutex); -} - - -void uv_barrier_wait(uv_barrier_t* barrier) { - uv_mutex_lock(&barrier->mutex); - if (++barrier->count == barrier->n) { - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile1); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile1); - - uv_mutex_lock(&barrier->mutex); - if (--barrier->count == 0) { - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile2); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile2); -} - -#else /* !(defined(__APPLE__) && defined(__MACH__)) */ - -int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { - return -pthread_barrier_init(barrier, NULL, count); -} - - -void uv_barrier_destroy(uv_barrier_t* barrier) { - if (pthread_barrier_destroy(barrier)) - abort(); -} - - -void uv_barrier_wait(uv_barrier_t* barrier) { - int r = pthread_barrier_wait(barrier); - if (r && r != PTHREAD_BARRIER_SERIAL_THREAD) - abort(); -} - -#endif /* defined(__APPLE__) && defined(__MACH__) */ - -int uv_key_create(uv_key_t* key) { - return -pthread_key_create(key, NULL); -} - - -void uv_key_delete(uv_key_t* key) { - if (pthread_key_delete(*key)) - abort(); -} - - -void* uv_key_get(uv_key_t* key) { - return pthread_getspecific(*key); -} - - -void uv_key_set(uv_key_t* key, void* value) { - if (pthread_setspecific(*key, value)) - abort(); -} diff --git a/third-party/libuv/src/unix/threadpool.c b/third-party/libuv/src/unix/threadpool.c deleted file mode 100644 index 7923250a09..0000000000 --- a/third-party/libuv/src/unix/threadpool.c +++ /dev/null @@ -1,280 +0,0 @@ -/* 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 - * 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 "internal.h" -#include <stdlib.h> - -#define MAX_THREADPOOL_SIZE 128 - -static uv_once_t once = UV_ONCE_INIT; -static uv_cond_t cond; -static uv_mutex_t mutex; -static unsigned int nthreads; -static uv_thread_t* threads; -static uv_thread_t default_threads[4]; -static QUEUE exit_message; -static QUEUE wq; -static volatile int initialized; - - -static void uv__cancelled(struct uv__work* w) { - abort(); -} - - -/* To avoid deadlock with uv_cancel() it's crucial that the worker - * never holds the global mutex and the loop-local mutex at the same time. - */ -static void worker(void* arg) { - struct uv__work* w; - QUEUE* q; - - (void) arg; - - for (;;) { - uv_mutex_lock(&mutex); - - while (QUEUE_EMPTY(&wq)) - uv_cond_wait(&cond, &mutex); - - q = QUEUE_HEAD(&wq); - - if (q == &exit_message) - uv_cond_signal(&cond); - else { - QUEUE_REMOVE(q); - QUEUE_INIT(q); /* Signal uv_cancel() that the work req is - executing. */ - } - - uv_mutex_unlock(&mutex); - - if (q == &exit_message) - break; - - w = QUEUE_DATA(q, struct uv__work, wq); - w->work(w); - - uv_mutex_lock(&w->loop->wq_mutex); - w->work = NULL; /* Signal uv_cancel() that the work req is done - executing. */ - QUEUE_INSERT_TAIL(&w->loop->wq, &w->wq); - uv_async_send(&w->loop->wq_async); - uv_mutex_unlock(&w->loop->wq_mutex); - } -} - - -static void post(QUEUE* q) { - uv_mutex_lock(&mutex); - QUEUE_INSERT_TAIL(&wq, q); - uv_cond_signal(&cond); - uv_mutex_unlock(&mutex); -} - - -static void init_once(void) { - unsigned int i; - const char* val; - - nthreads = ARRAY_SIZE(default_threads); - val = getenv("UV_THREADPOOL_SIZE"); - if (val != NULL) - nthreads = atoi(val); - if (nthreads == 0) - nthreads = 1; - if (nthreads > MAX_THREADPOOL_SIZE) - nthreads = MAX_THREADPOOL_SIZE; - - threads = default_threads; - if (nthreads > ARRAY_SIZE(default_threads)) { - threads = malloc(nthreads * sizeof(threads[0])); - if (threads == NULL) { - nthreads = ARRAY_SIZE(default_threads); - threads = default_threads; - } - } - - if (uv_cond_init(&cond)) - abort(); - - if (uv_mutex_init(&mutex)) - abort(); - - QUEUE_INIT(&wq); - - for (i = 0; i < nthreads; i++) - if (uv_thread_create(threads + i, worker, NULL)) - abort(); - - initialized = 1; -} - - -UV_DESTRUCTOR(static void cleanup(void)) { - unsigned int i; - - if (initialized == 0) - return; - - post(&exit_message); - - for (i = 0; i < nthreads; i++) - if (uv_thread_join(threads + i)) - abort(); - - if (threads != default_threads) - free(threads); - - uv_mutex_destroy(&mutex); - uv_cond_destroy(&cond); - - threads = NULL; - nthreads = 0; - initialized = 0; -} - - -void uv__work_submit(uv_loop_t* loop, - struct uv__work* w, - void (*work)(struct uv__work* w), - void (*done)(struct uv__work* w, int status)) { - uv_once(&once, init_once); - w->loop = loop; - w->work = work; - w->done = done; - post(&w->wq); -} - - -static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) { - int cancelled; - - uv_mutex_lock(&mutex); - uv_mutex_lock(&w->loop->wq_mutex); - - cancelled = !QUEUE_EMPTY(&w->wq) && w->work != NULL; - if (cancelled) - QUEUE_REMOVE(&w->wq); - - uv_mutex_unlock(&w->loop->wq_mutex); - uv_mutex_unlock(&mutex); - - if (!cancelled) - return -EBUSY; - - w->work = uv__cancelled; - uv_mutex_lock(&loop->wq_mutex); - QUEUE_INSERT_TAIL(&loop->wq, &w->wq); - uv_async_send(&loop->wq_async); - uv_mutex_unlock(&loop->wq_mutex); - - return 0; -} - - -void uv__work_done(uv_async_t* handle, int status) { - struct uv__work* w; - uv_loop_t* loop; - QUEUE* q; - QUEUE wq; - int err; - - loop = container_of(handle, uv_loop_t, wq_async); - QUEUE_INIT(&wq); - - uv_mutex_lock(&loop->wq_mutex); - if (!QUEUE_EMPTY(&loop->wq)) { - q = QUEUE_HEAD(&loop->wq); - QUEUE_SPLIT(&loop->wq, q, &wq); - } - uv_mutex_unlock(&loop->wq_mutex); - - while (!QUEUE_EMPTY(&wq)) { - q = QUEUE_HEAD(&wq); - QUEUE_REMOVE(q); - - w = container_of(q, struct uv__work, wq); - err = (w->work == uv__cancelled) ? -ECANCELED : 0; - w->done(w, err); - } -} - - -static void uv__queue_work(struct uv__work* w) { - uv_work_t* req = container_of(w, uv_work_t, work_req); - - req->work_cb(req); -} - - -static void uv__queue_done(struct uv__work* w, int err) { - uv_work_t* req; - - req = container_of(w, uv_work_t, work_req); - uv__req_unregister(req->loop, req); - - if (req->after_work_cb == NULL) - return; - - req->after_work_cb(req, err); -} - - -int uv_queue_work(uv_loop_t* loop, - uv_work_t* req, - uv_work_cb work_cb, - uv_after_work_cb after_work_cb) { - if (work_cb == NULL) - return -EINVAL; - - uv__req_init(loop, req, UV_WORK); - req->loop = loop; - req->work_cb = work_cb; - req->after_work_cb = after_work_cb; - uv__work_submit(loop, &req->work_req, uv__queue_work, uv__queue_done); - return 0; -} - - -int uv_cancel(uv_req_t* req) { - struct uv__work* wreq; - uv_loop_t* loop; - - switch (req->type) { - case UV_FS: - loop = ((uv_fs_t*) req)->loop; - wreq = &((uv_fs_t*) req)->work_req; - break; - case UV_GETADDRINFO: - loop = ((uv_getaddrinfo_t*) req)->loop; - wreq = &((uv_getaddrinfo_t*) req)->work_req; - break; - case UV_WORK: - loop = ((uv_work_t*) req)->loop; - wreq = &((uv_work_t*) req)->work_req; - break; - default: - return -EINVAL; - } - - return uv__work_cancel(loop, req, wreq); -} diff --git a/third-party/libuv/src/unix/timer.c b/third-party/libuv/src/unix/timer.c deleted file mode 100644 index 240efad503..0000000000 --- a/third-party/libuv/src/unix/timer.c +++ /dev/null @@ -1,153 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <limits.h> - - -static int uv__timer_cmp(const uv_timer_t* a, const uv_timer_t* b) { - if (a->timeout < b->timeout) - return -1; - if (a->timeout > b->timeout) - return 1; - /* - * compare start_id when both has the same timeout. start_id is - * allocated with loop->timer_counter in uv_timer_start(). - */ - if (a->start_id < b->start_id) - return -1; - if (a->start_id > b->start_id) - return 1; - return 0; -} - - -RB_GENERATE_STATIC(uv__timers, uv_timer_s, tree_entry, uv__timer_cmp) - - -int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER); - handle->timer_cb = NULL; - handle->repeat = 0; - - return 0; -} - - -int uv_timer_start(uv_timer_t* handle, - uv_timer_cb cb, - uint64_t timeout, - uint64_t repeat) { - uint64_t clamped_timeout; - - if (uv__is_active(handle)) - uv_timer_stop(handle); - - clamped_timeout = handle->loop->time + timeout; - if (clamped_timeout < timeout) - clamped_timeout = (uint64_t) -1; - - handle->timer_cb = cb; - handle->timeout = clamped_timeout; - handle->repeat = repeat; - /* start_id is the second index to be compared in uv__timer_cmp() */ - handle->start_id = handle->loop->timer_counter++; - - RB_INSERT(uv__timers, &handle->loop->timer_handles, handle); - uv__handle_start(handle); - - return 0; -} - - -int uv_timer_stop(uv_timer_t* handle) { - if (!uv__is_active(handle)) - return 0; - - RB_REMOVE(uv__timers, &handle->loop->timer_handles, handle); - uv__handle_stop(handle); - - return 0; -} - - -int uv_timer_again(uv_timer_t* handle) { - if (handle->timer_cb == NULL) - return -EINVAL; - - if (handle->repeat) { - uv_timer_stop(handle); - uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat); - } - - return 0; -} - - -void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) { - handle->repeat = repeat; -} - - -uint64_t uv_timer_get_repeat(const uv_timer_t* handle) { - return handle->repeat; -} - - -int uv__next_timeout(const uv_loop_t* loop) { - const uv_timer_t* handle; - uint64_t diff; - - /* RB_MIN expects a non-const tree root. That's okay, it doesn't modify it. */ - handle = RB_MIN(uv__timers, (struct uv__timers*) &loop->timer_handles); - - if (handle == NULL) - return -1; /* block indefinitely */ - - if (handle->timeout <= loop->time) - return 0; - - diff = handle->timeout - loop->time; - if (diff > INT_MAX) - diff = INT_MAX; - - return diff; -} - - -void uv__run_timers(uv_loop_t* loop) { - uv_timer_t* handle; - - while ((handle = RB_MIN(uv__timers, &loop->timer_handles))) { - if (handle->timeout > loop->time) - break; - - uv_timer_stop(handle); - uv_timer_again(handle); - handle->timer_cb(handle, 0); - } -} - - -void uv__timer_close(uv_timer_t* handle) { - uv_timer_stop(handle); -} diff --git a/third-party/libuv/src/unix/tty.c b/third-party/libuv/src/unix/tty.c deleted file mode 100644 index ca9459dd0d..0000000000 --- a/third-party/libuv/src/unix/tty.c +++ /dev/null @@ -1,184 +0,0 @@ -/* 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 - * 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 "spinlock.h" - -#include <assert.h> -#include <unistd.h> -#include <termios.h> -#include <errno.h> -#include <sys/ioctl.h> - -static int orig_termios_fd = -1; -static struct termios orig_termios; -static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER; - - -int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) { - uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY); - -#if defined(__APPLE__) - { - int err = uv__stream_try_select((uv_stream_t*) tty, &fd); - if (err) - return err; - } -#endif /* defined(__APPLE__) */ - - if (readable) { - uv__nonblock(fd, 1); - uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_READABLE); - } else { - /* Note: writable tty we set to blocking mode. */ - uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_WRITABLE); - tty->flags |= UV_STREAM_BLOCKING; - } - - tty->mode = 0; - return 0; -} - - -int uv_tty_set_mode(uv_tty_t* tty, int mode) { - struct termios raw; - int fd; - - fd = uv__stream_fd(tty); - - if (mode && tty->mode == 0) { /* on */ - if (tcgetattr(fd, &tty->orig_termios)) - return -errno; - - /* This is used for uv_tty_reset_mode() */ - uv_spinlock_lock(&termios_spinlock); - if (orig_termios_fd == -1) { - orig_termios = tty->orig_termios; - orig_termios_fd = fd; - } - uv_spinlock_unlock(&termios_spinlock); - - raw = tty->orig_termios; - raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); - raw.c_oflag |= (ONLCR); - raw.c_cflag |= (CS8); - raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); - raw.c_cc[VMIN] = 1; - raw.c_cc[VTIME] = 0; - - /* Put terminal in raw mode after draining */ - if (tcsetattr(fd, TCSADRAIN, &raw)) - return -errno; - - tty->mode = 1; - } else if (mode == 0 && tty->mode) { /* off */ - /* Put terminal in original mode after flushing */ - if (tcsetattr(fd, TCSAFLUSH, &tty->orig_termios)) - return -errno; - tty->mode = 0; - } - - return 0; -} - - -int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { - struct winsize ws; - - if (ioctl(uv__stream_fd(tty), TIOCGWINSZ, &ws)) - return -errno; - - *width = ws.ws_col; - *height = ws.ws_row; - - return 0; -} - - -uv_handle_type uv_guess_handle(uv_file file) { - struct sockaddr sa; - struct stat s; - socklen_t len; - int type; - - if (file < 0) - return UV_UNKNOWN_HANDLE; - - if (isatty(file)) - return UV_TTY; - - if (fstat(file, &s)) - return UV_UNKNOWN_HANDLE; - - if (S_ISREG(s.st_mode)) - return UV_FILE; - - if (S_ISCHR(s.st_mode)) - return UV_FILE; /* XXX UV_NAMED_PIPE? */ - - if (S_ISFIFO(s.st_mode)) - return UV_NAMED_PIPE; - - if (!S_ISSOCK(s.st_mode)) - return UV_UNKNOWN_HANDLE; - - len = sizeof(type); - if (getsockopt(file, SOL_SOCKET, SO_TYPE, &type, &len)) - return UV_UNKNOWN_HANDLE; - - len = sizeof(sa); - if (getsockname(file, &sa, &len)) - return UV_UNKNOWN_HANDLE; - - if (type == SOCK_DGRAM) - if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6) - return UV_UDP; - - if (type == SOCK_STREAM) { - if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6) - return UV_TCP; - if (sa.sa_family == AF_UNIX) - return UV_NAMED_PIPE; - } - - return UV_UNKNOWN_HANDLE; -} - - -/* This function is async signal-safe, meaning that it's safe to call from - * inside a signal handler _unless_ execution was inside uv_tty_set_mode()'s - * critical section when the signal was raised. - */ -int uv_tty_reset_mode(void) { - int err; - - if (!uv_spinlock_trylock(&termios_spinlock)) - return -EBUSY; /* In uv_tty_set_mode(). */ - - err = 0; - if (orig_termios_fd != -1) - if (tcsetattr(orig_termios_fd, TCSANOW, &orig_termios)) - err = -errno; - - uv_spinlock_unlock(&termios_spinlock); - return err; -} diff --git a/third-party/libuv/src/unix/udp.c b/third-party/libuv/src/unix/udp.c deleted file mode 100644 index a2b3dc3298..0000000000 --- a/third-party/libuv/src/unix/udp.c +++ /dev/null @@ -1,595 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> - - -static void uv__udp_run_completed(uv_udp_t* handle); -static void uv__udp_run_pending(uv_udp_t* handle); -static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents); -static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents); -static void uv__udp_sendmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents); -static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain); - - -void uv__udp_close(uv_udp_t* handle) { - uv__io_close(handle->loop, &handle->io_watcher); - uv__handle_stop(handle); - - if (handle->io_watcher.fd != -1) { - uv__close(handle->io_watcher.fd); - handle->io_watcher.fd = -1; - } -} - - -void uv__udp_finish_close(uv_udp_t* handle) { - uv_udp_send_t* req; - QUEUE* q; - - assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT)); - assert(handle->io_watcher.fd == -1); - - uv__udp_run_completed(handle); - - while (!QUEUE_EMPTY(&handle->write_queue)) { - q = QUEUE_HEAD(&handle->write_queue); - QUEUE_REMOVE(q); - - req = QUEUE_DATA(q, uv_udp_send_t, queue); - uv__req_unregister(handle->loop, req); - - if (req->bufs != req->bufsml) - free(req->bufs); - req->bufs = NULL; - - if (req->send_cb != NULL) - req->send_cb(req, -ECANCELED); - } - - /* Now tear down the handle. */ - handle->recv_cb = NULL; - handle->alloc_cb = NULL; - /* but _do not_ touch close_cb */ -} - - -static void uv__udp_run_pending(uv_udp_t* handle) { - uv_udp_send_t* req; - QUEUE* q; - struct msghdr h; - ssize_t size; - - while (!QUEUE_EMPTY(&handle->write_queue)) { - q = QUEUE_HEAD(&handle->write_queue); - assert(q != NULL); - - req = QUEUE_DATA(q, uv_udp_send_t, queue); - assert(req != NULL); - - memset(&h, 0, sizeof h); - h.msg_name = &req->addr; - h.msg_namelen = (req->addr.sin6_family == AF_INET6 ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); - h.msg_iov = (struct iovec*) req->bufs; - h.msg_iovlen = req->nbufs; - - do { - size = sendmsg(handle->io_watcher.fd, &h, 0); - } - while (size == -1 && errno == EINTR); - - /* TODO try to write once or twice more in the - * hope that the socket becomes readable again? - */ - if (size == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) - break; - - req->status = (size == -1 ? -errno : size); - - /* Sending a datagram is an atomic operation: either all data - * is written or nothing is (and EMSGSIZE is raised). That is - * why we don't handle partial writes. Just pop the request - * off the write queue and onto the completed queue, done. - */ - QUEUE_REMOVE(&req->queue); - QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue); - } -} - - -static void uv__udp_run_completed(uv_udp_t* handle) { - uv_udp_send_t* req; - QUEUE* q; - - while (!QUEUE_EMPTY(&handle->write_completed_queue)) { - q = QUEUE_HEAD(&handle->write_completed_queue); - QUEUE_REMOVE(q); - - req = QUEUE_DATA(q, uv_udp_send_t, queue); - uv__req_unregister(handle->loop, req); - - if (req->bufs != req->bufsml) - free(req->bufs); - req->bufs = NULL; - - if (req->send_cb == NULL) - continue; - - /* req->status >= 0 == bytes written - * req->status < 0 == errno - */ - if (req->status >= 0) - req->send_cb(req, 0); - else - req->send_cb(req, req->status); - } -} - - -static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) { - if (revents & UV__POLLIN) - uv__udp_recvmsg(loop, w, revents); - - if (revents & UV__POLLOUT) - uv__udp_sendmsg(loop, w, revents); -} - - -static void uv__udp_recvmsg(uv_loop_t* loop, - uv__io_t* w, - unsigned int revents) { - struct sockaddr_storage peer; - struct msghdr h; - uv_udp_t* handle; - ssize_t nread; - uv_buf_t buf; - int flags; - int count; - - handle = container_of(w, uv_udp_t, io_watcher); - assert(handle->type == UV_UDP); - assert(revents & UV__POLLIN); - - assert(handle->recv_cb != NULL); - assert(handle->alloc_cb != NULL); - - /* Prevent loop starvation when the data comes in as fast as (or faster than) - * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O. - */ - count = 32; - - memset(&h, 0, sizeof(h)); - h.msg_name = &peer; - - do { - handle->alloc_cb((uv_handle_t*) handle, 64 * 1024, &buf); - if (buf.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); - return; - } - assert(buf.base != NULL); - - h.msg_namelen = sizeof(peer); - h.msg_iov = (void*) &buf; - h.msg_iovlen = 1; - - do { - nread = recvmsg(handle->io_watcher.fd, &h, 0); - } - while (nread == -1 && errno == EINTR); - - if (nread == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) - handle->recv_cb(handle, 0, &buf, NULL, 0); - else - handle->recv_cb(handle, -errno, &buf, NULL, 0); - } - else { - flags = 0; - - if (h.msg_flags & MSG_TRUNC) - flags |= UV_UDP_PARTIAL; - - handle->recv_cb(handle, - nread, - &buf, - (const struct sockaddr*) &peer, - flags); - } - } - /* recv_cb callback may decide to pause or close the handle */ - while (nread != -1 - && count-- > 0 - && handle->io_watcher.fd != -1 - && handle->recv_cb != NULL); -} - - -static void uv__udp_sendmsg(uv_loop_t* loop, - uv__io_t* w, - unsigned int revents) { - uv_udp_t* handle; - - handle = container_of(w, uv_udp_t, io_watcher); - assert(handle->type == UV_UDP); - assert(revents & UV__POLLOUT); - - assert(!QUEUE_EMPTY(&handle->write_queue) - || !QUEUE_EMPTY(&handle->write_completed_queue)); - - /* Write out pending data first. */ - uv__udp_run_pending(handle); - - /* Drain 'request completed' queue. */ - uv__udp_run_completed(handle); - - if (!QUEUE_EMPTY(&handle->write_completed_queue)) { - /* Schedule completion callbacks. */ - uv__io_feed(handle->loop, &handle->io_watcher); - } - else if (QUEUE_EMPTY(&handle->write_queue)) { - /* Pending queue and completion queue empty, stop watcher. */ - uv__io_stop(loop, &handle->io_watcher, UV__POLLOUT); - - if (!uv__io_active(&handle->io_watcher, UV__POLLIN)) - uv__handle_stop(handle); - } -} - - -/* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional - * refinements for programs that use multicast. - * - * Linux as of 3.9 has a SO_REUSEPORT socket option but with semantics that - * are different from the BSDs: it _shares_ the port rather than steal it - * from the current listener. While useful, it's not something we can emulate - * on other platforms so we don't enable it. - */ -static int uv__set_reuse(int fd) { - int yes; - -#if defined(SO_REUSEPORT) && !defined(__linux__) - yes = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) - return -errno; -#else - yes = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))) - return -errno; -#endif - - return 0; -} - - -int uv__udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - int yes; - int fd; - - err = -EINVAL; - fd = -1; - - /* Check for bad flags. */ - if (flags & ~UV_UDP_IPV6ONLY) - return -EINVAL; - - /* Cannot set IPv6-only mode on non-IPv6 socket. */ - if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) - return -EINVAL; - - fd = handle->io_watcher.fd; - if (fd == -1) { - fd = uv__socket(addr->sa_family, SOCK_DGRAM, 0); - if (fd == -1) - return -errno; - handle->io_watcher.fd = fd; - } - - err = uv__set_reuse(fd); - if (err) - goto out; - - if (flags & UV_UDP_IPV6ONLY) { -#ifdef IPV6_V6ONLY - yes = 1; - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) { - err = -errno; - goto out; - } -#else - err = -ENOTSUP; - goto out; -#endif - } - - if (bind(fd, addr, addrlen)) { - err = -errno; - goto out; - } - - return 0; - -out: - uv__close(handle->io_watcher.fd); - handle->io_watcher.fd = -1; - return err; -} - - -static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain) { - unsigned char taddr[sizeof(struct sockaddr_in6)]; - socklen_t addrlen; - - assert(domain == AF_INET || domain == AF_INET6); - - if (handle->io_watcher.fd != -1) - return 0; - - switch (domain) { - case AF_INET: - { - struct sockaddr_in* addr = (void*)&taddr; - memset(addr, 0, sizeof *addr); - addr->sin_family = AF_INET; - addr->sin_addr.s_addr = INADDR_ANY; - addrlen = sizeof *addr; - break; - } - case AF_INET6: - { - struct sockaddr_in6* addr = (void*)&taddr; - memset(addr, 0, sizeof *addr); - addr->sin6_family = AF_INET6; - addr->sin6_addr = in6addr_any; - addrlen = sizeof *addr; - break; - } - default: - assert(0 && "unsupported address family"); - abort(); - } - - return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, 0); -} - - -int uv__udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb send_cb) { - int err; - - assert(nbufs > 0); - - err = uv__udp_maybe_deferred_bind(handle, addr->sa_family); - if (err) - return err; - - uv__req_init(handle->loop, req, UV_UDP_SEND); - - assert(addrlen <= sizeof(req->addr)); - memcpy(&req->addr, addr, addrlen); - req->send_cb = send_cb; - req->handle = handle; - req->nbufs = nbufs; - - req->bufs = req->bufsml; - if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = malloc(nbufs * sizeof(bufs[0])); - - if (req->bufs == NULL) - return -ENOMEM; - - memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0])); - QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue); - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT); - uv__handle_start(handle); - - return 0; -} - - -int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP); - handle->alloc_cb = NULL; - handle->recv_cb = NULL; - uv__io_init(&handle->io_watcher, uv__udp_io, -1); - QUEUE_INIT(&handle->write_queue); - QUEUE_INIT(&handle->write_completed_queue); - return 0; -} - - -int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { - int err; - - /* Check for already active socket. */ - if (handle->io_watcher.fd != -1) - return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */ - - err = uv__set_reuse(sock); - if (err) - return err; - - handle->io_watcher.fd = sock; - return 0; -} - - -int uv_udp_set_membership(uv_udp_t* handle, - const char* multicast_addr, - const char* interface_addr, - uv_membership membership) { - struct ip_mreq mreq; - int optname; - - memset(&mreq, 0, sizeof mreq); - - if (interface_addr) { - mreq.imr_interface.s_addr = inet_addr(interface_addr); - } else { - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - } - - mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr); - - switch (membership) { - case UV_JOIN_GROUP: - optname = IP_ADD_MEMBERSHIP; - break; - case UV_LEAVE_GROUP: - optname = IP_DROP_MEMBERSHIP; - break; - default: - return -EINVAL; - } - - if (setsockopt(handle->io_watcher.fd, - IPPROTO_IP, - optname, - &mreq, - sizeof(mreq))) { - return -errno; - } - - return 0; -} - - -static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) { -#if defined(__sun) - char arg = val; -#else - int arg = val; -#endif - - if (val < 0 || val > 255) - return -EINVAL; - - if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, option, &arg, sizeof(arg))) - return -errno; - - return 0; -} - - -int uv_udp_set_broadcast(uv_udp_t* handle, int on) { - if (setsockopt(handle->io_watcher.fd, - SOL_SOCKET, - SO_BROADCAST, - &on, - sizeof(on))) { - return -errno; - } - - return 0; -} - - -int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { - if (ttl < 1 || ttl > 255) - return -EINVAL; - - if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))) - return -errno; - - return 0; -} - - -int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { - return uv__setsockopt_maybe_char(handle, IP_MULTICAST_TTL, ttl); -} - - -int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) { - return uv__setsockopt_maybe_char(handle, IP_MULTICAST_LOOP, on); -} - - -int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) { - socklen_t socklen; - - if (handle->io_watcher.fd == -1) - return -EINVAL; /* FIXME(bnoordhuis) -EBADF */ - - /* sizeof(socklen_t) != sizeof(int) on some systems. */ - socklen = (socklen_t) *namelen; - - if (getsockname(handle->io_watcher.fd, name, &socklen)) - return -errno; - - *namelen = (int) socklen; - return 0; -} - - -int uv__udp_recv_start(uv_udp_t* handle, - uv_alloc_cb alloc_cb, - uv_udp_recv_cb recv_cb) { - int err; - - if (alloc_cb == NULL || recv_cb == NULL) - return -EINVAL; - - if (uv__io_active(&handle->io_watcher, UV__POLLIN)) - return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */ - - err = uv__udp_maybe_deferred_bind(handle, AF_INET); - if (err) - return err; - - handle->alloc_cb = alloc_cb; - handle->recv_cb = recv_cb; - - uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN); - uv__handle_start(handle); - - return 0; -} - - -int uv__udp_recv_stop(uv_udp_t* handle) { - uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN); - - if (!uv__io_active(&handle->io_watcher, UV__POLLOUT)) - uv__handle_stop(handle); - - handle->alloc_cb = NULL; - handle->recv_cb = NULL; - - return 0; -} diff --git a/third-party/libuv/src/unix/uv-dtrace.d b/third-party/libuv/src/unix/uv-dtrace.d deleted file mode 100644 index 7848450c94..0000000000 --- a/third-party/libuv/src/unix/uv-dtrace.d +++ /dev/null @@ -1,25 +0,0 @@ -/* 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 - * 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. - */ - -provider uv { - probe tick__start(void* loop, int mode); - probe tick__stop(void* loop, int mode); -}; diff --git a/third-party/libuv/src/uv-common.c b/third-party/libuv/src/uv-common.c deleted file mode 100644 index e5fc507756..0000000000 --- a/third-party/libuv/src/uv-common.c +++ /dev/null @@ -1,446 +0,0 @@ -/* 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 - * 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. - */ - -/* Expose glibc-specific EAI_* error codes. Needs to be defined before we - * include any headers. - */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif - -#include "uv.h" -#include "uv-common.h" - -#include <stdio.h> -#include <assert.h> -#include <stddef.h> /* NULL */ -#include <stdlib.h> /* malloc */ -#include <string.h> /* memset */ - -#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS) && !defined(_WIN32) -# include <net/if.h> /* if_nametoindex */ -#endif - -/* EAI_* constants. */ -#if !defined(_WIN32) -# include <sys/types.h> -# include <sys/socket.h> -# include <netdb.h> -#endif - -#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t); - -size_t uv_handle_size(uv_handle_type type) { - switch (type) { - UV_HANDLE_TYPE_MAP(XX) - default: - return -1; - } -} - -size_t uv_req_size(uv_req_type type) { - switch(type) { - UV_REQ_TYPE_MAP(XX) - default: - return -1; - } -} - -#undef XX - - -uv_buf_t uv_buf_init(char* base, unsigned int len) { - uv_buf_t buf; - buf.base = base; - buf.len = len; - return buf; -} - - -#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name; -const char* uv_err_name(int err) { - switch (err) { - UV_ERRNO_MAP(UV_ERR_NAME_GEN) - default: - assert(0); - return NULL; - } -} -#undef UV_ERR_NAME_GEN - - -#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg; -const char* uv_strerror(int err) { - switch (err) { - UV_ERRNO_MAP(UV_STRERROR_GEN) - default: - return "Unknown system error"; - } -} -#undef UV_STRERROR_GEN - - -int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) { - memset(addr, 0, sizeof(*addr)); - addr->sin_family = AF_INET; - addr->sin_port = htons(port); - return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr)); -} - - -int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) { -#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS) - char address_part[40]; - size_t address_part_size; - const char* zone_index; -#endif - - memset(addr, 0, sizeof(*addr)); - addr->sin6_family = AF_INET6; - addr->sin6_port = htons(port); - -#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS) - zone_index = strchr(ip, '%'); - if (zone_index != NULL) { - address_part_size = zone_index - ip; - if (address_part_size >= sizeof(address_part)) - address_part_size = sizeof(address_part) - 1; - - memcpy(address_part, ip, address_part_size); - address_part[address_part_size] = '\0'; - ip = address_part; - - zone_index++; /* skip '%' */ - /* NOTE: unknown interface (id=0) is silently ignored */ -#ifdef _WIN32 - addr->sin6_scope_id = atoi(zone_index); -#else - addr->sin6_scope_id = if_nametoindex(zone_index); -#endif - } -#endif - - return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr); -} - - -int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) { - return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size); -} - - -int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) { - return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size); -} - - -int uv_tcp_bind(uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int flags) { - unsigned int addrlen; - - if (handle->type != UV_TCP) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) - addrlen = sizeof(struct sockaddr_in); - else if (addr->sa_family == AF_INET6) - addrlen = sizeof(struct sockaddr_in6); - else - return UV_EINVAL; - - return uv__tcp_bind(handle, addr, addrlen, flags); -} - - -int uv_udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int flags) { - unsigned int addrlen; - - if (handle->type != UV_UDP) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) - addrlen = sizeof(struct sockaddr_in); - else if (addr->sa_family == AF_INET6) - addrlen = sizeof(struct sockaddr_in6); - else - return UV_EINVAL; - - return uv__udp_bind(handle, addr, addrlen, flags); -} - - -int uv_tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - uv_connect_cb cb) { - unsigned int addrlen; - - if (handle->type != UV_TCP) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) - addrlen = sizeof(struct sockaddr_in); - else if (addr->sa_family == AF_INET6) - addrlen = sizeof(struct sockaddr_in6); - else - return UV_EINVAL; - - return uv__tcp_connect(req, handle, addr, addrlen, cb); -} - - -int uv_udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - uv_udp_send_cb send_cb) { - unsigned int addrlen; - - if (handle->type != UV_UDP) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) - addrlen = sizeof(struct sockaddr_in); - else if (addr->sa_family == AF_INET6) - addrlen = sizeof(struct sockaddr_in6); - else - return UV_EINVAL; - - return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb); -} - - -int uv_udp_recv_start(uv_udp_t* handle, - uv_alloc_cb alloc_cb, - uv_udp_recv_cb recv_cb) { - if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL) - return UV_EINVAL; - else - return uv__udp_recv_start(handle, alloc_cb, recv_cb); -} - - -int uv_udp_recv_stop(uv_udp_t* handle) { - if (handle->type != UV_UDP) - return UV_EINVAL; - else - return uv__udp_recv_stop(handle); -} - - -struct thread_ctx { - void (*entry)(void* arg); - void* arg; -}; - - -#ifdef _WIN32 -static UINT __stdcall uv__thread_start(void* arg) -#else -static void* uv__thread_start(void *arg) -#endif -{ - struct thread_ctx *ctx_p; - struct thread_ctx ctx; - - ctx_p = arg; - ctx = *ctx_p; - free(ctx_p); - ctx.entry(ctx.arg); - - return 0; -} - - -int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { - struct thread_ctx* ctx; - int err; - - ctx = malloc(sizeof(*ctx)); - if (ctx == NULL) - return UV_ENOMEM; - - ctx->entry = entry; - ctx->arg = arg; - -#ifdef _WIN32 - *tid = (HANDLE) _beginthreadex(NULL, 0, uv__thread_start, ctx, 0, NULL); - err = *tid ? 0 : errno; -#else - err = pthread_create(tid, NULL, uv__thread_start, ctx); -#endif - - if (err) - free(ctx); - - return err ? -1 : 0; -} - - -unsigned long uv_thread_self(void) { -#ifdef _WIN32 - return (unsigned long) GetCurrentThreadId(); -#else - return (unsigned long) pthread_self(); -#endif -} - - -void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) { - QUEUE* q; - uv_handle_t* h; - - QUEUE_FOREACH(q, &loop->handle_queue) { - h = QUEUE_DATA(q, uv_handle_t, handle_queue); - if (h->flags & UV__HANDLE_INTERNAL) continue; - walk_cb(h, arg); - } -} - - -#ifndef NDEBUG -static void uv__print_handles(uv_loop_t* loop, int only_active) { - const char* type; - QUEUE* q; - uv_handle_t* h; - - if (loop == NULL) - loop = uv_default_loop(); - - QUEUE_FOREACH(q, &loop->handle_queue) { - h = QUEUE_DATA(q, uv_handle_t, handle_queue); - - if (only_active && !uv__is_active(h)) - continue; - - switch (h->type) { -#define X(uc, lc) case UV_##uc: type = #lc; break; - UV_HANDLE_TYPE_MAP(X) -#undef X - default: type = "<unknown>"; - } - - fprintf(stderr, - "[%c%c%c] %-8s %p\n", - "R-"[!(h->flags & UV__HANDLE_REF)], - "A-"[!(h->flags & UV__HANDLE_ACTIVE)], - "I-"[!(h->flags & UV__HANDLE_INTERNAL)], - type, - (void*)h); - } -} - - -void uv_print_all_handles(uv_loop_t* loop) { - uv__print_handles(loop, 0); -} - - -void uv_print_active_handles(uv_loop_t* loop) { - uv__print_handles(loop, 1); -} -#endif - - -void uv_ref(uv_handle_t* handle) { - uv__handle_ref(handle); -} - - -void uv_unref(uv_handle_t* handle) { - uv__handle_unref(handle); -} - - -int uv_has_ref(const uv_handle_t* handle) { - return uv__has_ref(handle); -} - - -void uv_stop(uv_loop_t* loop) { - loop->stop_flag = 1; -} - - -uint64_t uv_now(uv_loop_t* loop) { - return loop->time; -} - - -int uv__getaddrinfo_translate_error(int sys_err) { - switch (sys_err) { - case 0: return 0; -#if defined(EAI_ADDRFAMILY) - case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY; -#endif -#if defined(EAI_AGAIN) - case EAI_AGAIN: return UV_EAI_AGAIN; -#endif -#if defined(EAI_BADFLAGS) - case EAI_BADFLAGS: return UV_EAI_BADFLAGS; -#endif -#if defined(EAI_BADHINTS) - case EAI_BADHINTS: return UV_EAI_BADHINTS; -#endif -#if defined(EAI_CANCELED) - case EAI_CANCELED: return UV_EAI_CANCELED; -#endif -#if defined(EAI_FAIL) - case EAI_FAIL: return UV_EAI_FAIL; -#endif -#if defined(EAI_FAMILY) - case EAI_FAMILY: return UV_EAI_FAMILY; -#endif -#if defined(EAI_MEMORY) - case EAI_MEMORY: return UV_EAI_MEMORY; -#endif -#if defined(EAI_NODATA) - case EAI_NODATA: return UV_EAI_NODATA; -#endif -#if defined(EAI_NONAME) -# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME - case EAI_NONAME: return UV_EAI_NONAME; -# endif -#endif -#if defined(EAI_OVERFLOW) - case EAI_OVERFLOW: return UV_EAI_OVERFLOW; -#endif -#if defined(EAI_PROTOCOL) - case EAI_PROTOCOL: return UV_EAI_PROTOCOL; -#endif -#if defined(EAI_SERVICE) - case EAI_SERVICE: return UV_EAI_SERVICE; -#endif -#if defined(EAI_SOCKTYPE) - case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE; -#endif -#if defined(EAI_SYSTEM) - case EAI_SYSTEM: return UV_EAI_SYSTEM; -#endif - } - assert(!"unknown EAI_* error code"); - abort(); - return 0; /* Pacify compiler. */ -} diff --git a/third-party/libuv/src/uv-common.h b/third-party/libuv/src/uv-common.h deleted file mode 100644 index 3bcdcef3d4..0000000000 --- a/third-party/libuv/src/uv-common.h +++ /dev/null @@ -1,187 +0,0 @@ -/* 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 - * 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. - */ - -/* - * This file is private to libuv. It provides common functionality to both - * Windows and Unix backends. - */ - -#ifndef UV_COMMON_H_ -#define UV_COMMON_H_ - -#include <assert.h> -#include <stddef.h> - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include <stdint.h> -#endif - -#include "uv.h" -#include "tree.h" -#include "queue.h" - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -#define container_of(ptr, type, member) \ - ((type *) ((char *) (ptr) - offsetof(type, member))) - -#ifndef _WIN32 -enum { - UV__HANDLE_INTERNAL = 0x8000, - UV__HANDLE_ACTIVE = 0x4000, - UV__HANDLE_REF = 0x2000, - UV__HANDLE_CLOSING = 0 /* no-op on unix */ -}; -#else -# define UV__HANDLE_INTERNAL 0x80 -# define UV__HANDLE_ACTIVE 0x40 -# define UV__HANDLE_REF 0x20 -# define UV__HANDLE_CLOSING 0x01 -#endif - -int uv__tcp_bind(uv_tcp_t* tcp, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags); - -int uv__tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb); - -int uv__udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags); - -int uv__udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb send_cb); - -int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloccb, - uv_udp_recv_cb recv_cb); - -int uv__udp_recv_stop(uv_udp_t* handle); - -void uv__fs_poll_close(uv_fs_poll_t* handle); - -int uv__getaddrinfo_translate_error(int sys_err); /* EAI_* error. */ - -#define uv__has_active_reqs(loop) \ - (QUEUE_EMPTY(&(loop)->active_reqs) == 0) - -#define uv__req_register(loop, req) \ - do { \ - QUEUE_INSERT_TAIL(&(loop)->active_reqs, &(req)->active_queue); \ - } \ - while (0) - -#define uv__req_unregister(loop, req) \ - do { \ - assert(uv__has_active_reqs(loop)); \ - QUEUE_REMOVE(&(req)->active_queue); \ - } \ - while (0) - -#define uv__has_active_handles(loop) \ - ((loop)->active_handles > 0) - -#define uv__active_handle_add(h) \ - do { \ - (h)->loop->active_handles++; \ - } \ - while (0) - -#define uv__active_handle_rm(h) \ - do { \ - (h)->loop->active_handles--; \ - } \ - while (0) - -#define uv__is_active(h) \ - (((h)->flags & UV__HANDLE_ACTIVE) != 0) - -#define uv__is_closing(h) \ - (((h)->flags & (UV_CLOSING | UV_CLOSED)) != 0) - -#define uv__handle_start(h) \ - do { \ - assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \ - if (((h)->flags & UV__HANDLE_ACTIVE) != 0) break; \ - (h)->flags |= UV__HANDLE_ACTIVE; \ - if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_add(h); \ - } \ - while (0) - -#define uv__handle_stop(h) \ - do { \ - assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \ - if (((h)->flags & UV__HANDLE_ACTIVE) == 0) break; \ - (h)->flags &= ~UV__HANDLE_ACTIVE; \ - if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_rm(h); \ - } \ - while (0) - -#define uv__handle_ref(h) \ - do { \ - if (((h)->flags & UV__HANDLE_REF) != 0) break; \ - (h)->flags |= UV__HANDLE_REF; \ - if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \ - if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_add(h); \ - } \ - while (0) - -#define uv__handle_unref(h) \ - do { \ - if (((h)->flags & UV__HANDLE_REF) == 0) break; \ - (h)->flags &= ~UV__HANDLE_REF; \ - if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \ - if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_rm(h); \ - } \ - while (0) - -#define uv__has_ref(h) \ - (((h)->flags & UV__HANDLE_REF) != 0) - -#if defined(_WIN32) -# define uv__handle_platform_init(h) -#else -# define uv__handle_platform_init(h) ((h)->next_closing = NULL) -#endif - -#define uv__handle_init(loop_, h, type_) \ - do { \ - (h)->loop = (loop_); \ - (h)->type = (type_); \ - (h)->flags = UV__HANDLE_REF; /* Ref the loop when active. */ \ - QUEUE_INSERT_TAIL(&(loop_)->handle_queue, &(h)->handle_queue); \ - uv__handle_platform_init(h); \ - } \ - while (0) - -#endif /* UV_COMMON_H_ */ diff --git a/third-party/libuv/src/version.c b/third-party/libuv/src/version.c deleted file mode 100644 index 0636348dae..0000000000 --- a/third-party/libuv/src/version.c +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - * 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" - - /* - * Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI - * stable. When the minor version is odd, the API can change between patch - * releases. Make sure you update the -soname directives in config-unix.mk - * and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but - * not UV_VERSION_PATCH.) - */ - -#define UV_VERSION_MAJOR 0 -#define UV_VERSION_MINOR 11 -#define UV_VERSION_PATCH 19 -#define UV_VERSION_IS_RELEASE 1 - - -#define UV_VERSION ((UV_VERSION_MAJOR << 16) | \ - (UV_VERSION_MINOR << 8) | \ - (UV_VERSION_PATCH)) - -#define UV_STRINGIFY(v) UV_STRINGIFY_HELPER(v) -#define UV_STRINGIFY_HELPER(v) #v - -#define UV_VERSION_STRING_BASE UV_STRINGIFY(UV_VERSION_MAJOR) "." \ - UV_STRINGIFY(UV_VERSION_MINOR) "." \ - UV_STRINGIFY(UV_VERSION_PATCH) - -#if UV_VERSION_IS_RELEASE -# define UV_VERSION_STRING UV_VERSION_STRING_BASE -#else -# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-pre" -#endif - - -unsigned int uv_version(void) { - return UV_VERSION; -} - - -const char* uv_version_string(void) { - return UV_VERSION_STRING; -} diff --git a/third-party/libuv/src/win/async.c b/third-party/libuv/src/win/async.c deleted file mode 100644 index e192ead90d..0000000000 --- a/third-party/libuv/src/win/async.c +++ /dev/null @@ -1,99 +0,0 @@ -/* 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 - * 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 <assert.h> - -#include "uv.h" -#include "internal.h" -#include "atomicops-inl.h" -#include "handle-inl.h" -#include "req-inl.h" - - -void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING && - !handle->async_sent) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { - uv_req_t* req; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC); - handle->async_sent = 0; - handle->async_cb = async_cb; - - req = &handle->async_req; - uv_req_init(loop, req); - req->type = UV_WAKEUP; - req->data = handle; - - uv__handle_start(handle); - - return 0; -} - - -void uv_async_close(uv_loop_t* loop, uv_async_t* handle) { - if (!((uv_async_t*)handle)->async_sent) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - - uv__handle_closing(handle); -} - - -int uv_async_send(uv_async_t* handle) { - uv_loop_t* loop = handle->loop; - - if (handle->type != UV_ASYNC) { - /* Can't set errno because that's not thread-safe. */ - return -1; - } - - /* The user should make sure never to call uv_async_send to a closing */ - /* or closed handle. */ - assert(!(handle->flags & UV__HANDLE_CLOSING)); - - if (!uv__atomic_exchange_set(&handle->async_sent)) { - POST_COMPLETION_FOR_REQ(loop, &handle->async_req); - } - - return 0; -} - - -void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, - uv_req_t* req) { - assert(handle->type == UV_ASYNC); - assert(req->type == UV_WAKEUP); - - handle->async_sent = 0; - - if (handle->flags & UV__HANDLE_CLOSING) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } else if (handle->async_cb != NULL) { - handle->async_cb(handle, 0); - } -} diff --git a/third-party/libuv/src/win/atomicops-inl.h b/third-party/libuv/src/win/atomicops-inl.h deleted file mode 100644 index 61e006026c..0000000000 --- a/third-party/libuv/src/win/atomicops-inl.h +++ /dev/null @@ -1,56 +0,0 @@ -/* 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 - * 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. - */ - -#ifndef UV_WIN_ATOMICOPS_INL_H_ -#define UV_WIN_ATOMICOPS_INL_H_ - -#include "uv.h" - - -/* Atomic set operation on char */ -#ifdef _MSC_VER /* MSVC */ - -/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */ -/* efficient than InterlockedExchange, but InterlockedExchange8 does not */ -/* exist, and interlocked operations on larger targets might require the */ -/* target to be aligned. */ -#pragma intrinsic(_InterlockedOr8) - -static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) { - return _InterlockedOr8(target, 1); -} - -#else /* GCC */ - -/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */ -static inline char uv__atomic_exchange_set(char volatile* target) { - const char one = 1; - char old_value; - __asm__ __volatile__ ("lock xchgb %0, %1\n\t" - : "=r"(old_value), "=m"(*target) - : "0"(one), "m"(*target) - : "memory"); - return old_value; -} - -#endif - -#endif /* UV_WIN_ATOMICOPS_INL_H_ */ diff --git a/third-party/libuv/src/win/core.c b/third-party/libuv/src/win/core.c deleted file mode 100644 index e1a77655ac..0000000000 --- a/third-party/libuv/src/win/core.c +++ /dev/null @@ -1,362 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <errno.h> -#include <limits.h> -#include <malloc.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <crtdbg.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -/* The only event loop we support right now */ -static uv_loop_t uv_default_loop_; - -/* uv_once intialization guards */ -static uv_once_t uv_init_guard_ = UV_ONCE_INIT; -static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT; - - -#ifdef _DEBUG -/* Our crt debug report handler allows us to temporarily disable asserts */ -/* just for the current thread. */ - -__declspec( thread ) int uv__crt_assert_enabled = TRUE; - -static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) { - if (uv__crt_assert_enabled || report_type != _CRT_ASSERT) - return FALSE; - - if (ret_val) { - /* Set ret_val to 0 to continue with normal execution. */ - /* Set ret_val to 1 to trigger a breakpoint. */ - - if(IsDebuggerPresent()) - *ret_val = 1; - else - *ret_val = 0; - } - - /* Don't call _CrtDbgReport. */ - return TRUE; -} -#endif - - -static void uv__crt_invalid_parameter_handler(const wchar_t* expression, - const wchar_t* function, const wchar_t * file, unsigned int line, - uintptr_t reserved) { - /* No-op. */ -} - - -static void uv_init(void) { - /* Tell Windows that we will handle critical errors. */ - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | - SEM_NOOPENFILEERRORBOX); - - /* Tell the CRT to not exit the application when an invalid parameter is */ - /* passed. The main issue is that invalid FDs will trigger this behavior. */ -#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800 - _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler); -#endif - - /* We also need to setup our debug report handler because some CRT */ - /* functions (eg _get_osfhandle) raise an assert when called with invalid */ - /* FDs even though they return the proper error code in the release build. */ -#ifdef _DEBUG - _CrtSetReportHook(uv__crt_dbg_report_handler); -#endif - - /* Fetch winapi function pointers. This must be done first because other */ - /* intialization code might need these function pointers to be loaded. */ - uv_winapi_init(); - - /* Initialize winsock */ - uv_winsock_init(); - - /* Initialize FS */ - uv_fs_init(); - - /* Initialize signal stuff */ - uv_signals_init(); - - /* Initialize console */ - uv_console_init(); - - /* Initialize utilities */ - uv__util_init(); -} - - -static void uv_loop_init(uv_loop_t* loop) { - /* Create an I/O completion port */ - loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); - if (loop->iocp == NULL) { - uv_fatal_error(GetLastError(), "CreateIoCompletionPort"); - } - - /* To prevent uninitialized memory access, loop->time must be intialized */ - /* to zero before calling uv_update_time for the first time. */ - loop->time = 0; - loop->last_tick_count = 0; - uv_update_time(loop); - - QUEUE_INIT(&loop->handle_queue); - QUEUE_INIT(&loop->active_reqs); - loop->active_handles = 0; - - loop->pending_reqs_tail = NULL; - - loop->endgame_handles = NULL; - - RB_INIT(&loop->timers); - - loop->check_handles = NULL; - loop->prepare_handles = NULL; - loop->idle_handles = NULL; - - loop->next_prepare_handle = NULL; - loop->next_check_handle = NULL; - loop->next_idle_handle = NULL; - - memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets); - - loop->active_tcp_streams = 0; - loop->active_udp_streams = 0; - - loop->timer_counter = 0; - loop->stop_flag = 0; -} - - -static void uv_default_loop_init(void) { - /* Initialize libuv itself first */ - uv__once_init(); - - /* Initialize the main loop */ - uv_loop_init(&uv_default_loop_); -} - - -void uv__once_init(void) { - uv_once(&uv_init_guard_, uv_init); -} - - -uv_loop_t* uv_default_loop(void) { - uv_once(&uv_default_loop_init_guard_, uv_default_loop_init); - return &uv_default_loop_; -} - - -uv_loop_t* uv_loop_new(void) { - uv_loop_t* loop; - - /* Initialize libuv itself first */ - uv__once_init(); - - loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); - - if (!loop) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - uv_loop_init(loop); - return loop; -} - - -void uv_loop_delete(uv_loop_t* loop) { - if (loop != &uv_default_loop_) { - int i; - for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) { - SOCKET sock = loop->poll_peer_sockets[i]; - if (sock != 0 && sock != INVALID_SOCKET) { - closesocket(sock); - } - } - - free(loop); - } -} - - -int uv_backend_fd(const uv_loop_t* loop) { - return -1; -} - - -int uv_backend_timeout(const uv_loop_t* loop) { - return 0; -} - - -static void uv_poll(uv_loop_t* loop, int block) { - DWORD bytes, timeout; - ULONG_PTR key; - OVERLAPPED* overlapped; - uv_req_t* req; - - if (block) { - timeout = uv_get_poll_timeout(loop); - } else { - timeout = 0; - } - - GetQueuedCompletionStatus(loop->iocp, - &bytes, - &key, - &overlapped, - timeout); - - if (overlapped) { - /* Package was dequeued */ - req = uv_overlapped_to_req(overlapped); - uv_insert_pending_req(loop, req); - } else if (GetLastError() != WAIT_TIMEOUT) { - /* Serious error */ - uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus"); - } else { - /* We're sure that at least `timeout` milliseconds have expired, but */ - /* this may not be reflected yet in the GetTickCount() return value. */ - /* Therefore we ensure it's taken into account here. */ - uv__time_forward(loop, timeout); - } -} - - -static void uv_poll_ex(uv_loop_t* loop, int block) { - BOOL success; - DWORD timeout; - uv_req_t* req; - OVERLAPPED_ENTRY overlappeds[128]; - ULONG count; - ULONG i; - - if (block) { - timeout = uv_get_poll_timeout(loop); - } else { - timeout = 0; - } - - success = pGetQueuedCompletionStatusEx(loop->iocp, - overlappeds, - ARRAY_SIZE(overlappeds), - &count, - timeout, - FALSE); - - if (success) { - for (i = 0; i < count; i++) { - /* Package was dequeued */ - req = uv_overlapped_to_req(overlappeds[i].lpOverlapped); - uv_insert_pending_req(loop, req); - } - } else if (GetLastError() != WAIT_TIMEOUT) { - /* Serious error */ - uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx"); - } else if (timeout > 0) { - /* We're sure that at least `timeout` milliseconds have expired, but */ - /* this may not be reflected yet in the GetTickCount() return value. */ - /* Therefore we ensure it's taken into account here. */ - uv__time_forward(loop, timeout); - } -} - - -static int uv__loop_alive(const uv_loop_t* loop) { - return loop->active_handles > 0 || - !QUEUE_EMPTY(&loop->active_reqs) || - loop->endgame_handles != NULL; -} - - -int uv_loop_alive(const uv_loop_t* loop) { - return uv__loop_alive(loop); -} - - -int uv_run(uv_loop_t *loop, uv_run_mode mode) { - int r; - void (*poll)(uv_loop_t* loop, int block); - - if (pGetQueuedCompletionStatusEx) - poll = &uv_poll_ex; - else - poll = &uv_poll; - - r = uv__loop_alive(loop); - if (!r) - uv_update_time(loop); - - while (r != 0 && loop->stop_flag == 0) { - uv_update_time(loop); - uv_process_timers(loop); - - uv_process_reqs(loop); - uv_idle_invoke(loop); - uv_prepare_invoke(loop); - - (*poll)(loop, loop->idle_handles == NULL && - loop->pending_reqs_tail == NULL && - loop->endgame_handles == NULL && - !loop->stop_flag && - (loop->active_handles > 0 || - !QUEUE_EMPTY(&loop->active_reqs)) && - !(mode & UV_RUN_NOWAIT)); - - uv_check_invoke(loop); - uv_process_endgames(loop); - - if (mode == UV_RUN_ONCE) { - /* UV_RUN_ONCE implies forward progess: at least one callback must have - * been invoked when it returns. uv__io_poll() can return without doing - * I/O (meaning: no callbacks) when its timeout expires - which means we - * have pending timers that satisfy the forward progress constraint. - * - * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from - * the check. - */ - uv_update_time(loop); - uv_process_timers(loop); - } - - r = uv__loop_alive(loop); - if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT)) - break; - } - - /* The if statement lets the compiler compile it to a conditional store. - * Avoids dirtying a cache line. - */ - if (loop->stop_flag != 0) - loop->stop_flag = 0; - - return r; -} diff --git a/third-party/libuv/src/win/dl.c b/third-party/libuv/src/win/dl.c deleted file mode 100644 index d5b8f7c7d3..0000000000 --- a/third-party/libuv/src/win/dl.c +++ /dev/null @@ -1,86 +0,0 @@ -/* 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 - * 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" - -static int uv__dlerror(uv_lib_t* lib, int errorno); - - -int uv_dlopen(const char* filename, uv_lib_t* lib) { - WCHAR filename_w[32768]; - - lib->handle = NULL; - lib->errmsg = NULL; - - if (!uv_utf8_to_utf16(filename, filename_w, ARRAY_SIZE(filename_w))) { - return uv__dlerror(lib, GetLastError()); - } - - lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - if (lib->handle == NULL) { - return uv__dlerror(lib, GetLastError()); - } - - return 0; -} - - -void uv_dlclose(uv_lib_t* lib) { - if (lib->errmsg) { - LocalFree((void*)lib->errmsg); - lib->errmsg = NULL; - } - - if (lib->handle) { - /* Ignore errors. No good way to signal them without leaking memory. */ - FreeLibrary(lib->handle); - lib->handle = NULL; - } -} - - -int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { - *ptr = (void*) GetProcAddress(lib->handle, name); - return uv__dlerror(lib, *ptr ? 0 : GetLastError()); -} - - -const char* uv_dlerror(uv_lib_t* lib) { - return lib->errmsg ? lib->errmsg : "no error"; -} - - -static int uv__dlerror(uv_lib_t* lib, int errorno) { - if (lib->errmsg) { - LocalFree((void*)lib->errmsg); - lib->errmsg = NULL; - } - - if (errorno) { - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (LPSTR)&lib->errmsg, 0, NULL); - } - - return errorno ? -1 : 0; -} diff --git a/third-party/libuv/src/win/error.c b/third-party/libuv/src/win/error.c deleted file mode 100644 index 3162bc787f..0000000000 --- a/third-party/libuv/src/win/error.c +++ /dev/null @@ -1,169 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <errno.h> -#include <malloc.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" - - -/* - * Display an error message and abort the event loop. - */ -void uv_fatal_error(const int errorno, const char* syscall) { - char* buf = NULL; - const char* errmsg; - - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL); - - if (buf) { - errmsg = buf; - } else { - errmsg = "Unknown error"; - } - - /* FormatMessage messages include a newline character already, */ - /* so don't add another. */ - if (syscall) { - fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg); - } else { - fprintf(stderr, "(%d) %s", errorno, errmsg); - } - - if (buf) { - LocalFree(buf); - } - - *((char*)NULL) = 0xff; /* Force debug break */ - abort(); -} - - -int uv_translate_sys_error(int sys_errno) { - if (sys_errno <= 0) { - return sys_errno; /* If < 0 then it's already a libuv error. */ - } - - switch (sys_errno) { - case ERROR_NOACCESS: return UV_EACCES; - case WSAEACCES: return UV_EACCES; - case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE; - case WSAEADDRINUSE: return UV_EADDRINUSE; - case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL; - case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT; - case WSAEWOULDBLOCK: return UV_EAGAIN; - case WSAEALREADY: return UV_EALREADY; - case ERROR_INVALID_FLAGS: return UV_EBADF; - case ERROR_INVALID_HANDLE: return UV_EBADF; - case ERROR_LOCK_VIOLATION: return UV_EBUSY; - case ERROR_PIPE_BUSY: return UV_EBUSY; - case ERROR_SHARING_VIOLATION: return UV_EBUSY; - case ERROR_OPERATION_ABORTED: return UV_ECANCELED; - case WSAEINTR: return UV_ECANCELED; - case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET; - case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED; - case WSAECONNABORTED: return UV_ECONNABORTED; - case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED; - case WSAECONNREFUSED: return UV_ECONNREFUSED; - case ERROR_NETNAME_DELETED: return UV_ECONNRESET; - case WSAECONNRESET: return UV_ECONNRESET; - case ERROR_ALREADY_EXISTS: return UV_EEXIST; - case ERROR_FILE_EXISTS: return UV_EEXIST; - case ERROR_BUFFER_OVERFLOW: return UV_EFAULT; - case WSAEFAULT: return UV_EFAULT; - case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH; - case WSAEHOSTUNREACH: return UV_EHOSTUNREACH; - case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL; - case ERROR_INVALID_DATA: return UV_EINVAL; - case ERROR_INVALID_PARAMETER: return UV_EINVAL; - case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL; - case WSAEINVAL: return UV_EINVAL; - case WSAEPFNOSUPPORT: return UV_EINVAL; - case WSAESOCKTNOSUPPORT: return UV_EINVAL; - case ERROR_BEGINNING_OF_MEDIA: return UV_EIO; - case ERROR_BUS_RESET: return UV_EIO; - case ERROR_CRC: return UV_EIO; - case ERROR_DEVICE_DOOR_OPEN: return UV_EIO; - case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO; - case ERROR_DISK_CORRUPT: return UV_EIO; - case ERROR_EOM_OVERFLOW: return UV_EIO; - case ERROR_FILEMARK_DETECTED: return UV_EIO; - case ERROR_GEN_FAILURE: return UV_EIO; - case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO; - case ERROR_IO_DEVICE: return UV_EIO; - case ERROR_NO_DATA_DETECTED: return UV_EIO; - case ERROR_NO_SIGNAL_SENT: return UV_EIO; - case ERROR_OPEN_FAILED: return UV_EIO; - case ERROR_SETMARK_DETECTED: return UV_EIO; - case ERROR_SIGNAL_REFUSED: return UV_EIO; - case WSAEISCONN: return UV_EISCONN; - case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP; - case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE; - case WSAEMFILE: return UV_EMFILE; - case WSAEMSGSIZE: return UV_EMSGSIZE; - case ERROR_FILENAME_EXCED_RANGE: return UV_ENAMETOOLONG; - case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH; - case WSAENETUNREACH: return UV_ENETUNREACH; - case WSAENOBUFS: return UV_ENOBUFS; - case ERROR_DIRECTORY: return UV_ENOENT; - case ERROR_FILE_NOT_FOUND: return UV_ENOENT; - case ERROR_INVALID_NAME: return UV_ENOENT; - case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT; - case ERROR_MOD_NOT_FOUND: return UV_ENOENT; - case ERROR_PATH_NOT_FOUND: return UV_ENOENT; - case WSAHOST_NOT_FOUND: return UV_ENOENT; - case WSANO_DATA: return UV_ENOENT; - case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM; - case ERROR_OUTOFMEMORY: return UV_ENOMEM; - case ERROR_CANNOT_MAKE: return UV_ENOSPC; - case ERROR_DISK_FULL: return UV_ENOSPC; - case ERROR_EA_TABLE_FULL: return UV_ENOSPC; - case ERROR_END_OF_MEDIA: return UV_ENOSPC; - case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC; - case ERROR_NOT_CONNECTED: return UV_ENOTCONN; - case WSAENOTCONN: return UV_ENOTCONN; - case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY; - case WSAENOTSOCK: return UV_ENOTSOCK; - case ERROR_NOT_SUPPORTED: return UV_ENOTSUP; - case ERROR_BROKEN_PIPE: return UV_EOF; - case ERROR_ACCESS_DENIED: return UV_EPERM; - case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM; - case ERROR_BAD_PIPE: return UV_EPIPE; - case ERROR_NO_DATA: return UV_EPIPE; - case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE; - case WSAESHUTDOWN: return UV_EPIPE; - case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT; - case ERROR_WRITE_PROTECT: return UV_EROFS; - case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT; - case WSAETIMEDOUT: return UV_ETIMEDOUT; - case ERROR_NOT_SAME_DEVICE: return UV_EXDEV; - case ERROR_INVALID_FUNCTION: return UV_EISDIR; - case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG; - default: return UV_UNKNOWN; - } -} diff --git a/third-party/libuv/src/win/fs-event.c b/third-party/libuv/src/win/fs-event.c deleted file mode 100644 index 6132b79c82..0000000000 --- a/third-party/libuv/src/win/fs-event.c +++ /dev/null @@ -1,527 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <malloc.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -const unsigned int uv_directory_watcher_buffer_size = 4096; - - -static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop, - uv_fs_event_t* handle) { - assert(handle->dir_handle != INVALID_HANDLE_VALUE); - assert(!handle->req_pending); - - memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped)); - if (!ReadDirectoryChangesW(handle->dir_handle, - handle->buffer, - uv_directory_watcher_buffer_size, - FALSE, - FILE_NOTIFY_CHANGE_FILE_NAME | - FILE_NOTIFY_CHANGE_DIR_NAME | - FILE_NOTIFY_CHANGE_ATTRIBUTES | - FILE_NOTIFY_CHANGE_SIZE | - FILE_NOTIFY_CHANGE_LAST_WRITE | - FILE_NOTIFY_CHANGE_LAST_ACCESS | - FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SECURITY, - NULL, - &handle->req.overlapped, - NULL)) { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(&handle->req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)&handle->req); - } - - handle->req_pending = 1; -} - - -static int uv_split_path(const WCHAR* filename, WCHAR** dir, - WCHAR** file) { - int len = wcslen(filename); - int i = len; - while (i > 0 && filename[--i] != '\\' && filename[i] != '/'); - - if (i == 0) { - if (dir) { - *dir = (WCHAR*)malloc((MAX_PATH + 1) * sizeof(WCHAR)); - if (!*dir) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - if (!GetCurrentDirectoryW(MAX_PATH, *dir)) { - free(*dir); - *dir = NULL; - return -1; - } - } - - *file = wcsdup(filename); - } else { - if (dir) { - *dir = (WCHAR*)malloc((i + 1) * sizeof(WCHAR)); - if (!*dir) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - wcsncpy(*dir, filename, i); - (*dir)[i] = L'\0'; - } - - *file = (WCHAR*)malloc((len - i) * sizeof(WCHAR)); - if (!*file) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - wcsncpy(*file, filename + i + 1, len - i - 1); - (*file)[len - i - 1] = L'\0'; - } - - return 0; -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_FS_EVENT); - handle->dir_handle = INVALID_HANDLE_VALUE; - handle->buffer = NULL; - handle->req_pending = 0; - handle->filew = NULL; - handle->short_filew = NULL; - handle->dirw = NULL; - - uv_req_init(loop, (uv_req_t*)&handle->req); - handle->req.type = UV_FS_EVENT_REQ; - handle->req.data = handle; - - return 0; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* filename, - unsigned int flags) { - int name_size, is_path_dir; - DWORD attr, last_error; - WCHAR* dir = NULL, *dir_to_watch, *filenamew = NULL; - WCHAR short_path[MAX_PATH]; - - if (uv__is_active(handle)) - return UV_EINVAL; - - handle->cb = cb; - handle->filename = strdup(filename); - if (!handle->filename) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - uv__handle_start(handle); - - /* Convert name to UTF16. */ - name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(WCHAR); - filenamew = (WCHAR*)malloc(name_size); - if (!filenamew) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - if (!uv_utf8_to_utf16(filename, filenamew, - name_size / sizeof(WCHAR))) { - return uv_translate_sys_error(GetLastError()); - } - - /* Determine whether filename is a file or a directory. */ - attr = GetFileAttributesW(filenamew); - if (attr == INVALID_FILE_ATTRIBUTES) { - last_error = GetLastError(); - goto error; - } - - is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; - - if (is_path_dir) { - /* filename is a directory, so that's the directory that we will watch. */ - handle->dirw = filenamew; - dir_to_watch = filenamew; - } else { - /* - * filename is a file. So we split filename into dir & file parts, and - * watch the dir directory. - */ - - /* Convert to short path. */ - if (!GetShortPathNameW(filenamew, short_path, ARRAY_SIZE(short_path))) { - last_error = GetLastError(); - goto error; - } - - if (uv_split_path(filenamew, &dir, &handle->filew) != 0) { - last_error = GetLastError(); - goto error; - } - - if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) { - last_error = GetLastError(); - goto error; - } - - dir_to_watch = dir; - free(filenamew); - filenamew = NULL; - } - - handle->dir_handle = CreateFileW(dir_to_watch, - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_DELETE | - FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OVERLAPPED, - NULL); - - if (dir) { - free(dir); - dir = NULL; - } - - if (handle->dir_handle == INVALID_HANDLE_VALUE) { - last_error = GetLastError(); - goto error; - } - - if (CreateIoCompletionPort(handle->dir_handle, - handle->loop->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - last_error = GetLastError(); - goto error; - } - - if (!handle->buffer) { - handle->buffer = (char*)_aligned_malloc(uv_directory_watcher_buffer_size, - sizeof(DWORD)); - } - if (!handle->buffer) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped)); - - if (!ReadDirectoryChangesW(handle->dir_handle, - handle->buffer, - uv_directory_watcher_buffer_size, - FALSE, - FILE_NOTIFY_CHANGE_FILE_NAME | - FILE_NOTIFY_CHANGE_DIR_NAME | - FILE_NOTIFY_CHANGE_ATTRIBUTES | - FILE_NOTIFY_CHANGE_SIZE | - FILE_NOTIFY_CHANGE_LAST_WRITE | - FILE_NOTIFY_CHANGE_LAST_ACCESS | - FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SECURITY, - NULL, - &handle->req.overlapped, - NULL)) { - last_error = GetLastError(); - goto error; - } - - handle->req_pending = 1; - return 0; - -error: - if (handle->filename) { - free(handle->filename); - handle->filename = NULL; - } - - if (handle->filew) { - free(handle->filew); - handle->filew = NULL; - } - - if (handle->short_filew) { - free(handle->short_filew); - handle->short_filew = NULL; - } - - free(filenamew); - - if (handle->dir_handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->dir_handle); - handle->dir_handle = INVALID_HANDLE_VALUE; - } - - if (handle->buffer) { - _aligned_free(handle->buffer); - handle->buffer = NULL; - } - - return uv_translate_sys_error(last_error); -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - if (!uv__is_active(handle)) - return UV_EINVAL; - - if (handle->dir_handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->dir_handle); - handle->dir_handle = INVALID_HANDLE_VALUE; - } - - uv__handle_stop(handle); - - if (handle->filew) { - free(handle->filew); - handle->filew = NULL; - } - - if (handle->short_filew) { - free(handle->short_filew); - handle->short_filew = NULL; - } - - if (handle->filename) { - free(handle->filename); - handle->filename = NULL; - } - - if (handle->dirw) { - free(handle->dirw); - handle->dirw = NULL; - } - - return 0; -} - - -void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, - uv_fs_event_t* handle) { - FILE_NOTIFY_INFORMATION* file_info; - int err, sizew, size, result; - char* filename = NULL; - WCHAR* filenamew, *long_filenamew = NULL; - DWORD offset = 0; - - assert(req->type == UV_FS_EVENT_REQ); - assert(handle->req_pending); - handle->req_pending = 0; - - /* Don't report any callbacks if: - * - We're closing, just push the handle onto the endgame queue - * - We are not active, just ignore the callback - */ - if (!uv__is_active(handle)) { - if (handle->flags & UV__HANDLE_CLOSING) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - return; - } - - file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset); - - if (REQ_SUCCESS(req)) { - if (req->overlapped.InternalHigh > 0) { - do { - file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset); - assert(!filename); - assert(!long_filenamew); - - /* - * Fire the event only if we were asked to watch a directory, - * or if the filename filter matches. - */ - if (handle->dirw || - _wcsnicmp(handle->filew, file_info->FileName, - file_info->FileNameLength / sizeof(WCHAR)) == 0 || - _wcsnicmp(handle->short_filew, file_info->FileName, - file_info->FileNameLength / sizeof(WCHAR)) == 0) { - - if (handle->dirw) { - /* - * We attempt to convert the file name to its long form for - * events that still point to valid files on disk. - * For removed and renamed events, we do not provide the file name. - */ - if (file_info->Action != FILE_ACTION_REMOVED && - file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) { - /* Construct a full path to the file. */ - size = wcslen(handle->dirw) + - file_info->FileNameLength / sizeof(WCHAR) + 2; - - filenamew = (WCHAR*)malloc(size * sizeof(WCHAR)); - if (!filenamew) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw, - file_info->FileNameLength / sizeof(WCHAR), - file_info->FileName); - - filenamew[size - 1] = L'\0'; - - /* Convert to long name. */ - size = GetLongPathNameW(filenamew, NULL, 0); - - if (size) { - long_filenamew = (WCHAR*)malloc(size * sizeof(WCHAR)); - if (!long_filenamew) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - size = GetLongPathNameW(filenamew, long_filenamew, size); - if (size) { - long_filenamew[size] = '\0'; - } else { - free(long_filenamew); - long_filenamew = NULL; - } - } - - free(filenamew); - - if (long_filenamew) { - /* Get the file name out of the long path. */ - result = uv_split_path(long_filenamew, NULL, &filenamew); - free(long_filenamew); - - if (result == 0) { - long_filenamew = filenamew; - sizew = -1; - } else { - long_filenamew = NULL; - } - } - - /* - * If we couldn't get the long name - just use the name - * provided by ReadDirectoryChangesW. - */ - if (!long_filenamew) { - filenamew = file_info->FileName; - sizew = file_info->FileNameLength / sizeof(WCHAR); - } - } else { - /* Removed or renamed callbacks don't provide filename. */ - filenamew = NULL; - } - } else { - /* We already have the long name of the file, so just use it. */ - filenamew = handle->filew; - sizew = -1; - } - - if (filenamew) { - /* Convert the filename to utf8. */ - size = uv_utf16_to_utf8(filenamew, - sizew, - NULL, - 0); - if (size) { - filename = (char*)malloc(size + 1); - if (!filename) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - size = uv_utf16_to_utf8(filenamew, - sizew, - filename, - size); - if (size) { - filename[size] = '\0'; - } else { - free(filename); - filename = NULL; - } - } - } - - switch (file_info->Action) { - case FILE_ACTION_ADDED: - case FILE_ACTION_REMOVED: - case FILE_ACTION_RENAMED_OLD_NAME: - case FILE_ACTION_RENAMED_NEW_NAME: - handle->cb(handle, filename, UV_RENAME, 0); - break; - - case FILE_ACTION_MODIFIED: - handle->cb(handle, filename, UV_CHANGE, 0); - break; - } - - free(filename); - filename = NULL; - free(long_filenamew); - long_filenamew = NULL; - } - - offset = file_info->NextEntryOffset; - } while (offset && !(handle->flags & UV__HANDLE_CLOSING)); - } else { - handle->cb(handle, NULL, UV_CHANGE, 0); - } - } else { - err = GET_REQ_ERROR(req); - handle->cb(handle, NULL, 0, uv_translate_sys_error(err)); - } - - if (!(handle->flags & UV__HANDLE_CLOSING)) { - uv_fs_event_queue_readdirchanges(loop, handle); - } else { - uv_want_endgame(loop, (uv_handle_t*)handle); - } -} - - -void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) { - uv_fs_event_stop(handle); - - uv__handle_closing(handle); - - if (!handle->req_pending) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - -} - - -void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) { - if ((handle->flags & UV__HANDLE_CLOSING) && !handle->req_pending) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (handle->buffer) { - _aligned_free(handle->buffer); - handle->buffer = NULL; - } - - uv__handle_close(handle); - } -} diff --git a/third-party/libuv/src/win/fs.c b/third-party/libuv/src/win/fs.c deleted file mode 100644 index c4182758c7..0000000000 --- a/third-party/libuv/src/win/fs.c +++ /dev/null @@ -1,2043 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <stdlib.h> -#include <malloc.h> -#include <direct.h> -#include <errno.h> -#include <fcntl.h> -#include <io.h> -#include <limits.h> -#include <sys/stat.h> -#include <sys/utime.h> -#include <stdio.h> - -#include "uv.h" -#include "internal.h" -#include "req-inl.h" -#include "handle-inl.h" - - -#define UV_FS_FREE_PATHS 0x0002 -#define UV_FS_FREE_PTR 0x0008 -#define UV_FS_CLEANEDUP 0x0010 - - -#define QUEUE_FS_TP_JOB(loop, req) \ - do { \ - if (!QueueUserWorkItem(&uv_fs_thread_proc, \ - req, \ - WT_EXECUTEDEFAULT)) { \ - return uv_translate_sys_error(GetLastError()); \ - } \ - uv__req_register(loop, req); \ - } while (0) - -#define SET_REQ_RESULT(req, result_value) \ - do { \ - req->result = (result_value); \ - if (req->result == -1) { \ - req->sys_errno_ = _doserrno; \ - req->result = uv_translate_sys_error(req->sys_errno_); \ - } \ - } while (0) - -#define SET_REQ_WIN32_ERROR(req, sys_errno) \ - do { \ - req->sys_errno_ = (sys_errno); \ - req->result = uv_translate_sys_error(req->sys_errno_); \ - } while (0) - -#define SET_REQ_UV_ERROR(req, uv_errno, sys_errno) \ - do { \ - req->result = (uv_errno); \ - req->sys_errno_ = (sys_errno); \ - } while (0) - -#define VERIFY_FD(fd, req) \ - if (fd == -1) { \ - req->result = UV_EBADF; \ - req->sys_errno_ = ERROR_INVALID_HANDLE; \ - return; \ - } - -#define FILETIME_TO_UINT(filetime) \ - (*((uint64_t*) &(filetime)) - 116444736000000000ULL) - -#define FILETIME_TO_TIME_T(filetime) \ - (FILETIME_TO_UINT(filetime) / 10000000ULL) - -#define FILETIME_TO_TIME_NS(filetime, secs) \ - ((FILETIME_TO_UINT(filetime) - (secs * 10000000ULL)) * 100) - -#define FILETIME_TO_TIMESPEC(ts, filetime) \ - do { \ - (ts).tv_sec = (long) FILETIME_TO_TIME_T(filetime); \ - (ts).tv_nsec = (long) FILETIME_TO_TIME_NS(filetime, (ts).tv_sec); \ - } while(0) - -#define TIME_T_TO_FILETIME(time, filetime_ptr) \ - do { \ - *(uint64_t*) (filetime_ptr) = ((int64_t) (time) * 10000000LL) + \ - 116444736000000000ULL; \ - } while(0) - -#define IS_SLASH(c) ((c) == L'\\' || (c) == L'/') -#define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \ - ((c) >= L'A' && (c) <= L'Z')) - -const WCHAR JUNCTION_PREFIX[] = L"\\??\\"; -const WCHAR JUNCTION_PREFIX_LEN = 4; - -const WCHAR LONG_PATH_PREFIX[] = L"\\\\?\\"; -const WCHAR LONG_PATH_PREFIX_LEN = 4; - - -void uv_fs_init() { - _fmode = _O_BINARY; -} - - -INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req, - const char* path, const char* new_path, const int copy_path) { - char* buf; - char* pos; - ssize_t buf_sz = 0, path_len, pathw_len, new_pathw_len; - - /* new_path can only be set if path is also set. */ - assert(new_path == NULL || path != NULL); - - if (path != NULL) { - pathw_len = MultiByteToWideChar(CP_UTF8, - 0, - path, - -1, - NULL, - 0); - if (pathw_len == 0) { - return GetLastError(); - } - - buf_sz += pathw_len * sizeof(WCHAR); - } - - if (path != NULL && copy_path) { - path_len = 1 + strlen(path); - buf_sz += path_len; - } - - if (new_path != NULL) { - new_pathw_len = MultiByteToWideChar(CP_UTF8, - 0, - new_path, - -1, - NULL, - 0); - if (new_pathw_len == 0) { - return GetLastError(); - } - - buf_sz += new_pathw_len * sizeof(WCHAR); - } - - - if (buf_sz == 0) { - req->pathw = NULL; - req->new_pathw = NULL; - req->path = NULL; - return 0; - } - - buf = (char*) malloc(buf_sz); - if (buf == NULL) { - return ERROR_OUTOFMEMORY; - } - - pos = buf; - - if (path != NULL) { - DWORD r = MultiByteToWideChar(CP_UTF8, - 0, - path, - -1, - (WCHAR*) pos, - pathw_len); - assert(r == pathw_len); - req->pathw = (WCHAR*) pos; - pos += r * sizeof(WCHAR); - } else { - req->pathw = NULL; - } - - if (new_path != NULL) { - DWORD r = MultiByteToWideChar(CP_UTF8, - 0, - new_path, - -1, - (WCHAR*) pos, - new_pathw_len); - assert(r == new_pathw_len); - req->new_pathw = (WCHAR*) pos; - pos += r * sizeof(WCHAR); - } else { - req->new_pathw = NULL; - } - - if (!copy_path) { - req->path = path; - } else if (path) { - memcpy(pos, path, path_len); - assert(path_len == buf_sz - (pos - buf)); - req->path = pos; - } else { - req->path = NULL; - } - - req->flags |= UV_FS_FREE_PATHS; - - return 0; -} - - - -INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, - uv_fs_type fs_type, const uv_fs_cb cb) { - uv_req_init(loop, (uv_req_t*) req); - - req->type = UV_FS; - req->loop = loop; - req->flags = 0; - req->fs_type = fs_type; - req->result = 0; - req->ptr = NULL; - req->path = NULL; - - if (cb != NULL) { - req->cb = cb; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - } -} - - -INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr, - uint64_t* target_len_ptr) { - char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer; - WCHAR *w_target; - DWORD w_target_len; - char* target; - int target_len; - DWORD bytes; - - if (!DeviceIoControl(handle, - FSCTL_GET_REPARSE_POINT, - NULL, - 0, - buffer, - sizeof buffer, - &bytes, - NULL)) { - return -1; - } - - if (reparse_data->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - /* Real symlink */ - w_target = reparse_data->SymbolicLinkReparseBuffer.PathBuffer + - (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / - sizeof(WCHAR)); - w_target_len = - reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / - sizeof(WCHAR); - - /* Real symlinks can contain pretty much everything, but the only thing */ - /* we really care about is undoing the implicit conversion to an NT */ - /* namespaced path that CreateSymbolicLink will perform on absolute */ - /* paths. If the path is win32-namespaced then the user must have */ - /* explicitly made it so, and we better just return the unmodified */ - /* reparse data. */ - if (w_target_len >= 4 && - w_target[0] == L'\\' && - w_target[1] == L'?' && - w_target[2] == L'?' && - w_target[3] == L'\\') { - /* Starts with \??\ */ - if (w_target_len >= 6 && - ((w_target[4] >= L'A' && w_target[4] <= L'Z') || - (w_target[4] >= L'a' && w_target[4] <= L'z')) && - w_target[5] == L':' && - (w_target_len == 6 || w_target[6] == L'\\')) { - /* \??\«drive»:\ */ - w_target += 4; - w_target_len -= 4; - - } else if (w_target_len >= 8 && - (w_target[4] == L'U' || w_target[4] == L'u') && - (w_target[5] == L'N' || w_target[5] == L'n') && - (w_target[6] == L'C' || w_target[6] == L'c') && - w_target[7] == L'\\') { - /* \??\UNC\«server»\«share»\ - make sure the final path looks like */ - /* \\«server»\«share»\ */ - w_target += 6; - w_target[0] = L'\\'; - w_target_len -= 6; - } - } - - } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { - /* Junction. */ - w_target = reparse_data->MountPointReparseBuffer.PathBuffer + - (reparse_data->MountPointReparseBuffer.SubstituteNameOffset / - sizeof(WCHAR)); - w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength / - sizeof(WCHAR); - - /* Only treat junctions that look like \??\«drive»:\ as symlink. */ - /* Junctions can also be used as mount points, like \??\Volume{«guid»}, */ - /* but that's confusing for programs since they wouldn't be able to */ - /* actually understand such a path when returned by uv_readlink(). */ - /* UNC paths are never valid for junctions so we don't care about them. */ - if (!(w_target_len >= 6 && - w_target[0] == L'\\' && - w_target[1] == L'?' && - w_target[2] == L'?' && - w_target[3] == L'\\' && - ((w_target[4] >= L'A' && w_target[4] <= L'Z') || - (w_target[4] >= L'a' && w_target[4] <= L'z')) && - w_target[5] == L':' && - (w_target_len == 6 || w_target[6] == L'\\'))) { - SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); - return -1; - } - - /* Remove leading \??\ */ - w_target += 4; - w_target_len -= 4; - - } else { - /* Reparse tag does not indicate a symlink. */ - SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); - return -1; - } - - /* If needed, compute the length of the target. */ - if (target_ptr != NULL || target_len_ptr != NULL) { - /* Compute the length of the target. */ - target_len = WideCharToMultiByte(CP_UTF8, - 0, - w_target, - w_target_len, - NULL, - 0, - NULL, - NULL); - if (target_len == 0) { - return -1; - } - } - - /* If requested, allocate memory and convert to UTF8. */ - if (target_ptr != NULL) { - int r; - target = (char*) malloc(target_len + 1); - if (target == NULL) { - SetLastError(ERROR_OUTOFMEMORY); - return -1; - } - - r = WideCharToMultiByte(CP_UTF8, - 0, - w_target, - w_target_len, - target, - target_len, - NULL, - NULL); - assert(r == target_len); - target[target_len] = '\0'; - - *target_ptr = target; - } - - if (target_len_ptr != NULL) { - *target_len_ptr = target_len; - } - - return 0; -} - - -void fs__open(uv_fs_t* req) { - DWORD access; - DWORD share; - DWORD disposition; - DWORD attributes = 0; - HANDLE file; - int fd, current_umask; - int flags = req->file_flags; - - /* Obtain the active umask. umask() never fails and returns the previous */ - /* umask. */ - current_umask = umask(0); - umask(current_umask); - - /* convert flags and mode to CreateFile parameters */ - switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) { - case _O_RDONLY: - access = FILE_GENERIC_READ; - attributes |= FILE_FLAG_BACKUP_SEMANTICS; - break; - case _O_WRONLY: - access = FILE_GENERIC_WRITE; - break; - case _O_RDWR: - access = FILE_GENERIC_READ | FILE_GENERIC_WRITE; - break; - default: - goto einval; - } - - if (flags & _O_APPEND) { - access &= ~FILE_WRITE_DATA; - access |= FILE_APPEND_DATA; - attributes &= ~FILE_FLAG_BACKUP_SEMANTICS; - } - - /* - * Here is where we deviate significantly from what CRT's _open() - * 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. - */ - share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; - - switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) { - case 0: - case _O_EXCL: - disposition = OPEN_EXISTING; - break; - case _O_CREAT: - disposition = OPEN_ALWAYS; - break; - case _O_CREAT | _O_EXCL: - case _O_CREAT | _O_TRUNC | _O_EXCL: - disposition = CREATE_NEW; - break; - case _O_TRUNC: - case _O_TRUNC | _O_EXCL: - disposition = TRUNCATE_EXISTING; - break; - case _O_CREAT | _O_TRUNC: - disposition = CREATE_ALWAYS; - break; - default: - goto einval; - } - - attributes |= FILE_ATTRIBUTE_NORMAL; - if (flags & _O_CREAT) { - if (!((req->mode & ~current_umask) & _S_IWRITE)) { - attributes |= FILE_ATTRIBUTE_READONLY; - } - } - - if (flags & _O_TEMPORARY ) { - attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY; - access |= DELETE; - } - - if (flags & _O_SHORT_LIVED) { - attributes |= FILE_ATTRIBUTE_TEMPORARY; - } - - switch (flags & (_O_SEQUENTIAL | _O_RANDOM)) { - case 0: - break; - case _O_SEQUENTIAL: - attributes |= FILE_FLAG_SEQUENTIAL_SCAN; - break; - case _O_RANDOM: - attributes |= FILE_FLAG_RANDOM_ACCESS; - break; - default: - goto einval; - } - - /* Setting this flag makes it possible to open a directory. */ - attributes |= FILE_FLAG_BACKUP_SEMANTICS; - - file = CreateFileW(req->pathw, - access, - share, - NULL, - disposition, - attributes, - NULL); - if (file == INVALID_HANDLE_VALUE) { - DWORD error = GetLastError(); - if (error == ERROR_FILE_EXISTS && (flags & _O_CREAT) && - !(flags & _O_EXCL)) { - /* Special case: when ERROR_FILE_EXISTS happens and O_CREAT was */ - /* specified, it means the path referred to a directory. */ - SET_REQ_UV_ERROR(req, UV_EISDIR, error); - } else { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } - return; - } - - fd = _open_osfhandle((intptr_t) file, flags); - if (fd < 0) { - /* The only known failure mode for _open_osfhandle() is EMFILE, in which - * case GetLastError() will return zero. However we'll try to handle other - * errors as well, should they ever occur. - */ - if (errno == EMFILE) - SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES); - else if (GetLastError() != ERROR_SUCCESS) - SET_REQ_WIN32_ERROR(req, GetLastError()); - else - SET_REQ_WIN32_ERROR(req, UV_UNKNOWN); - return; - } - - SET_REQ_RESULT(req, fd); - return; - - einval: - SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); -} - -void fs__close(uv_fs_t* req) { - int fd = req->fd; - int result; - - VERIFY_FD(fd, req); - - result = _close(fd); - SET_REQ_RESULT(req, result); -} - - -void fs__read(uv_fs_t* req) { - int fd = req->fd; - size_t length = req->length; - int64_t offset = req->offset; - HANDLE handle; - OVERLAPPED overlapped, *overlapped_ptr; - LARGE_INTEGER offset_; - DWORD bytes; - DWORD error; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (length > INT_MAX) { - SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER); - return; - } - - if (offset != -1) { - memset(&overlapped, 0, sizeof overlapped); - - offset_.QuadPart = offset; - overlapped.Offset = offset_.LowPart; - overlapped.OffsetHigh = offset_.HighPart; - - overlapped_ptr = &overlapped; - } else { - overlapped_ptr = NULL; - } - - if (ReadFile(handle, req->buf, req->length, &bytes, overlapped_ptr)) { - SET_REQ_RESULT(req, bytes); - } else { - error = GetLastError(); - if (error == ERROR_HANDLE_EOF) { - SET_REQ_RESULT(req, bytes); - } else { - SET_REQ_WIN32_ERROR(req, error); - } - } -} - - -void fs__write(uv_fs_t* req) { - int fd = req->fd; - size_t length = req->length; - int64_t offset = req->offset; - HANDLE handle; - OVERLAPPED overlapped, *overlapped_ptr; - LARGE_INTEGER offset_; - DWORD bytes; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (length > INT_MAX) { - SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER); - return; - } - - if (offset != -1) { - memset(&overlapped, 0, sizeof overlapped); - - offset_.QuadPart = offset; - overlapped.Offset = offset_.LowPart; - overlapped.OffsetHigh = offset_.HighPart; - - overlapped_ptr = &overlapped; - } else { - overlapped_ptr = NULL; - } - - if (WriteFile(handle, req->buf, length, &bytes, overlapped_ptr)) { - SET_REQ_RESULT(req, bytes); - } else { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } -} - - -void fs__rmdir(uv_fs_t* req) { - int result = _wrmdir(req->pathw); - SET_REQ_RESULT(req, result); -} - - -void fs__unlink(uv_fs_t* req) { - const WCHAR* pathw = req->pathw; - HANDLE handle; - BY_HANDLE_FILE_INFORMATION info; - FILE_DISPOSITION_INFORMATION disposition; - IO_STATUS_BLOCK iosb; - NTSTATUS status; - - handle = CreateFileW(pathw, - FILE_READ_ATTRIBUTES | DELETE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (!GetFileInformationByHandle(handle, &info)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); - return; - } - - if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - /* Do not allow deletion of directories, unless it is a symlink. When */ - /* the path refers to a non-symlink directory, report EPERM as mandated */ - /* by POSIX.1. */ - - /* Check if it is a reparse point. If it's not, it's a normal directory. */ - if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED); - CloseHandle(handle); - return; - } - - /* Read the reparse point and check if it is a valid symlink. */ - /* If not, don't unlink. */ - if (fs__readlink_handle(handle, NULL, NULL) < 0) { - DWORD error = GetLastError(); - if (error == ERROR_SYMLINK_NOT_SUPPORTED) - error = ERROR_ACCESS_DENIED; - SET_REQ_WIN32_ERROR(req, error); - CloseHandle(handle); - return; - } - } - - /* Try to set the delete flag. */ - disposition.DeleteFile = TRUE; - status = pNtSetInformationFile(handle, - &iosb, - &disposition, - sizeof disposition, - FileDispositionInformation); - if (NT_SUCCESS(status)) { - SET_REQ_SUCCESS(req); - } else { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - } - - CloseHandle(handle); -} - - -void fs__mkdir(uv_fs_t* req) { - /* TODO: use req->mode. */ - int result = _wmkdir(req->pathw); - SET_REQ_RESULT(req, result); -} - - -void fs__readdir(uv_fs_t* req) { - WCHAR* pathw = req->pathw; - size_t len = wcslen(pathw); - int result, size; - WCHAR* buf = NULL, *ptr, *name; - HANDLE dir; - WIN32_FIND_DATAW ent = { 0 }; - size_t buf_char_len = 4096; - WCHAR* path2; - const WCHAR* fmt; - - if (len == 0) { - fmt = L"./*"; - } else if (pathw[len - 1] == L'/' || pathw[len - 1] == L'\\') { - fmt = L"%s*"; - } else { - fmt = L"%s\\*"; - } - - /* Figure out whether path is a file or a directory. */ - if (!(GetFileAttributesW(pathw) & FILE_ATTRIBUTE_DIRECTORY)) { - req->result = UV_ENOTDIR; - req->sys_errno_ = ERROR_SUCCESS; - return; - } - - path2 = (WCHAR*)malloc(sizeof(WCHAR) * (len + 4)); - if (!path2) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - _snwprintf(path2, len + 3, fmt, pathw); - dir = FindFirstFileW(path2, &ent); - free(path2); - - if(dir == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - result = 0; - - do { - name = ent.cFileName; - - if (name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))) { - len = wcslen(name); - - if (!buf) { - buf = (WCHAR*)malloc(buf_char_len * sizeof(WCHAR)); - if (!buf) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - ptr = buf; - } - - while ((ptr - buf) + len + 1 > buf_char_len) { - buf_char_len *= 2; - path2 = buf; - buf = (WCHAR*)realloc(buf, buf_char_len * sizeof(WCHAR)); - if (!buf) { - uv_fatal_error(ERROR_OUTOFMEMORY, "realloc"); - } - - ptr = buf + (ptr - path2); - } - - wcscpy(ptr, name); - ptr += len + 1; - result++; - } - } while(FindNextFileW(dir, &ent)); - - FindClose(dir); - - if (buf) { - /* Convert result to UTF8. */ - size = uv_utf16_to_utf8(buf, buf_char_len, NULL, 0); - if (!size) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - req->ptr = (char*)malloc(size + 1); - if (!req->ptr) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - size = uv_utf16_to_utf8(buf, buf_char_len, (char*)req->ptr, size); - if (!size) { - free(buf); - free(req->ptr); - req->ptr = NULL; - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - free(buf); - - ((char*)req->ptr)[size] = '\0'; - req->flags |= UV_FS_FREE_PTR; - } else { - req->ptr = NULL; - } - - SET_REQ_RESULT(req, result); -} - - -INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) { - FILE_ALL_INFORMATION file_info; - FILE_FS_VOLUME_INFORMATION volume_info; - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - - nt_status = pNtQueryInformationFile(handle, - &io_status, - &file_info, - sizeof file_info, - FileAllInformation); - - /* Buffer overflow (a warning status code) is expected here. */ - if (NT_ERROR(nt_status)) { - SetLastError(pRtlNtStatusToDosError(nt_status)); - return -1; - } - - nt_status = pNtQueryVolumeInformationFile(handle, - &io_status, - &volume_info, - sizeof volume_info, - FileFsVolumeInformation); - - /* Buffer overflow (a warning status code) is expected here. */ - if (NT_ERROR(nt_status)) { - SetLastError(pRtlNtStatusToDosError(nt_status)); - return -1; - } - - /* Todo: st_mode should probably always be 0666 for everyone. We might also - * want to report 0777 if the file is a .exe or a directory. - * - * Currently it's based on whether the 'readonly' attribute is set, which - * makes little sense because the semantics are so different: the 'read-only' - * flag is just a way for a user to protect against accidental deleteion, and - * serves no security purpose. Windows uses ACLs for that. - * - * Also people now use uv_fs_chmod() to take away the writable bit for good - * reasons. Windows however just makes the file read-only, which makes it - * impossible to delete the file afterwards, since read-only files can't be - * deleted. - * - * IOW it's all just a clusterfuck and we should think of something that - * makes slighty more sense. - * - * And uv_fs_chmod should probably just fail on windows or be a total no-op. - * There's nothing sensible it can do anyway. - */ - statbuf->st_mode = 0; - - if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - statbuf->st_mode |= S_IFLNK; - if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0) - return -1; - - } else if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - statbuf->st_mode |= _S_IFDIR; - statbuf->st_size = 0; - - } else { - statbuf->st_mode |= _S_IFREG; - statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart; - } - - if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY) - statbuf->st_mode |= _S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6); - else - statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) | - ((_S_IREAD | _S_IWRITE) >> 6); - - FILETIME_TO_TIMESPEC(statbuf->st_atim, file_info.BasicInformation.LastAccessTime); - FILETIME_TO_TIMESPEC(statbuf->st_ctim, file_info.BasicInformation.ChangeTime); - FILETIME_TO_TIMESPEC(statbuf->st_mtim, file_info.BasicInformation.LastWriteTime); - FILETIME_TO_TIMESPEC(statbuf->st_birthtim, file_info.BasicInformation.CreationTime); - - statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart; - - /* st_blocks contains the on-disk allocation size in 512-byte units. */ - statbuf->st_blocks = - file_info.StandardInformation.AllocationSize.QuadPart >> 9ULL; - - statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks; - - statbuf->st_dev = volume_info.VolumeSerialNumber; - - /* The st_blksize is supposed to be the 'optimal' number of bytes for reading - * and writing to the disk. That is, for any definition of 'optimal' - it's - * supposed to at least avoid read-update-write behavior when writing to the - * disk. - * - * However nobody knows this and even fewer people actually use this value, - * and in order to fill it out we'd have to make another syscall to query the - * volume for FILE_FS_SECTOR_SIZE_INFORMATION. - * - * Therefore we'll just report a sensible value that's quite commonly okay - * on modern hardware. - */ - statbuf->st_blksize = 2048; - - /* Todo: set st_flags to something meaningful. Also provide a wrapper for - * chattr(2). - */ - statbuf->st_flags = 0; - - /* Windows has nothing sensible to say about these values, so they'll just - * remain empty. - */ - statbuf->st_gid = 0; - statbuf->st_uid = 0; - statbuf->st_rdev = 0; - statbuf->st_gen = 0; - - return 0; -} - - -INLINE static void fs__stat_prepare_path(WCHAR* pathw) { - size_t len = wcslen(pathw); - - /* TODO: ignore namespaced paths. */ - if (len > 1 && pathw[len - 2] != L':' && - (pathw[len - 1] == L'\\' || pathw[len - 1] == L'/')) { - pathw[len - 1] = '\0'; - } -} - - -INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) { - HANDLE handle; - DWORD flags; - - flags = FILE_FLAG_BACKUP_SEMANTICS; - if (do_lstat) { - flags |= FILE_FLAG_OPEN_REPARSE_POINT; - } - - handle = CreateFileW(req->pathw, - FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - flags, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__stat_handle(handle, &req->statbuf) != 0) { - DWORD error = GetLastError(); - if (do_lstat && error == ERROR_SYMLINK_NOT_SUPPORTED) { - /* We opened a reparse point but it was not a symlink. Try again. */ - fs__stat_impl(req, 0); - - } else { - /* Stat failed. */ - SET_REQ_WIN32_ERROR(req, GetLastError()); - } - - CloseHandle(handle); - return; - } - - req->ptr = &req->statbuf; - req->result = 0; - CloseHandle(handle); -} - - -static void fs__stat(uv_fs_t* req) { - fs__stat_prepare_path(req->pathw); - fs__stat_impl(req, 0); -} - - -static void fs__lstat(uv_fs_t* req) { - fs__stat_prepare_path(req->pathw); - fs__stat_impl(req, 1); -} - - -static void fs__fstat(uv_fs_t* req) { - int fd = req->fd; - HANDLE handle; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (fs__stat_handle(handle, &req->statbuf) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - req->ptr = &req->statbuf; - req->result = 0; -} - - -static void fs__rename(uv_fs_t* req) { - if (!MoveFileExW(req->pathw, req->new_pathw, MOVEFILE_REPLACE_EXISTING)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - SET_REQ_RESULT(req, 0); -} - - -INLINE static void fs__sync_impl(uv_fs_t* req) { - int fd = req->fd; - int result; - - VERIFY_FD(fd, req); - - result = FlushFileBuffers(uv__get_osfhandle(fd)) ? 0 : -1; - if (result == -1) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - SET_REQ_RESULT(req, result); - } -} - - -static void fs__fsync(uv_fs_t* req) { - fs__sync_impl(req); -} - - -static void fs__fdatasync(uv_fs_t* req) { - fs__sync_impl(req); -} - - -static void fs__ftruncate(uv_fs_t* req) { - int fd = req->fd; - HANDLE handle; - NTSTATUS status; - IO_STATUS_BLOCK io_status; - FILE_END_OF_FILE_INFORMATION eof_info; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - eof_info.EndOfFile.QuadPart = req->offset; - - status = pNtSetInformationFile(handle, - &io_status, - &eof_info, - sizeof eof_info, - FileEndOfFileInformation); - - if (NT_SUCCESS(status)) { - SET_REQ_RESULT(req, 0); - } else { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - } -} - - -static void fs__sendfile(uv_fs_t* req) { - int fd_in = req->fd, fd_out = req->fd_out; - size_t length = req->length; - int64_t offset = req->offset; - const size_t max_buf_size = 65536; - size_t buf_size = length < max_buf_size ? length : max_buf_size; - int n, result = 0; - int64_t result_offset = 0; - char* buf = (char*) malloc(buf_size); - if (!buf) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - if (offset != -1) { - result_offset = _lseeki64(fd_in, offset, SEEK_SET); - } - - if (result_offset == -1) { - result = -1; - } else { - while (length > 0) { - n = _read(fd_in, buf, length < buf_size ? length : buf_size); - if (n == 0) { - break; - } else if (n == -1) { - result = -1; - break; - } - - length -= n; - - n = _write(fd_out, buf, n); - if (n == -1) { - result = -1; - break; - } - - result += n; - } - } - - free(buf); - - SET_REQ_RESULT(req, result); -} - - -static void fs__chmod(uv_fs_t* req) { - int result = _wchmod(req->pathw, req->mode); - SET_REQ_RESULT(req, result); -} - - -static void fs__fchmod(uv_fs_t* req) { - int fd = req->fd; - HANDLE handle; - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_BASIC_INFORMATION file_info; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - nt_status = pNtQueryInformationFile(handle, - &io_status, - &file_info, - sizeof file_info, - FileBasicInformation); - - if (!NT_SUCCESS(nt_status)) { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); - return; - } - - if (req->mode & _S_IWRITE) { - file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; - } else { - file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY; - } - - nt_status = pNtSetInformationFile(handle, - &io_status, - &file_info, - sizeof file_info, - FileBasicInformation); - - if (!NT_SUCCESS(nt_status)) { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); - return; - } - - SET_REQ_SUCCESS(req); -} - - -INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) { - FILETIME filetime_a, filetime_m; - - TIME_T_TO_FILETIME((time_t) atime, &filetime_a); - TIME_T_TO_FILETIME((time_t) mtime, &filetime_m); - - if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) { - return -1; - } - - return 0; -} - - -static void fs__utime(uv_fs_t* req) { - HANDLE handle; - - handle = CreateFileW(req->pathw, - FILE_WRITE_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__utime_handle(handle, req->atime, req->mtime) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); - return; - } - - CloseHandle(handle); - - req->result = 0; -} - - -static void fs__futime(uv_fs_t* req) { - int fd = req->fd; - HANDLE handle; - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (fs__utime_handle(handle, req->atime, req->mtime) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - req->result = 0; -} - - -static void fs__link(uv_fs_t* req) { - DWORD r = CreateHardLinkW(req->new_pathw, req->pathw, NULL); - if (r == 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - req->result = 0; - } -} - - -static void fs__create_junction(uv_fs_t* req, const WCHAR* path, - const WCHAR* new_path) { - HANDLE handle = INVALID_HANDLE_VALUE; - REPARSE_DATA_BUFFER *buffer = NULL; - int created = 0; - int target_len; - int is_absolute, is_long_path; - int needed_buf_size, used_buf_size, used_data_size, path_buf_len; - int start, len, i; - int add_slash; - DWORD bytes; - WCHAR* path_buf; - - target_len = wcslen(path); - is_long_path = wcsncmp(path, LONG_PATH_PREFIX, LONG_PATH_PREFIX_LEN) == 0; - - if (is_long_path) { - is_absolute = 1; - } else { - is_absolute = target_len >= 3 && IS_LETTER(path[0]) && - path[1] == L':' && IS_SLASH(path[2]); - } - - if (!is_absolute) { - /* Not supporting relative paths */ - SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_NOT_SUPPORTED); - return; - } - - // Do a pessimistic calculation of the required buffer size - needed_buf_size = - FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + - JUNCTION_PREFIX_LEN * sizeof(WCHAR) + - 2 * (target_len + 2) * sizeof(WCHAR); - - // Allocate the buffer - buffer = (REPARSE_DATA_BUFFER*)malloc(needed_buf_size); - if (!buffer) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - // Grab a pointer to the part of the buffer where filenames go - path_buf = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer); - path_buf_len = 0; - - // Copy the substitute (internal) target path - start = path_buf_len; - - wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX, - JUNCTION_PREFIX_LEN); - path_buf_len += JUNCTION_PREFIX_LEN; - - add_slash = 0; - for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) { - if (IS_SLASH(path[i])) { - add_slash = 1; - continue; - } - - if (add_slash) { - path_buf[path_buf_len++] = L'\\'; - add_slash = 0; - } - - path_buf[path_buf_len++] = path[i]; - } - path_buf[path_buf_len++] = L'\\'; - len = path_buf_len - start; - - // Set the info about the substitute name - buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR); - buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR); - - // Insert null terminator - path_buf[path_buf_len++] = L'\0'; - - // Copy the print name of the target path - start = path_buf_len; - add_slash = 0; - for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) { - if (IS_SLASH(path[i])) { - add_slash = 1; - continue; - } - - if (add_slash) { - path_buf[path_buf_len++] = L'\\'; - add_slash = 0; - } - - path_buf[path_buf_len++] = path[i]; - } - len = path_buf_len - start; - if (len == 2) { - path_buf[path_buf_len++] = L'\\'; - len++; - } - - // Set the info about the print name - buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR); - buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR); - - // Insert another null terminator - path_buf[path_buf_len++] = L'\0'; - - // Calculate how much buffer space was actually used - used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + - path_buf_len * sizeof(WCHAR); - used_data_size = used_buf_size - - FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer); - - // Put general info in the data buffer - buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - buffer->ReparseDataLength = used_data_size; - buffer->Reserved = 0; - - // Create a new directory - if (!CreateDirectoryW(new_path, NULL)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto error; - } - created = 1; - - // Open the directory - handle = CreateFileW(new_path, - GENERIC_ALL, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OPEN_REPARSE_POINT, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto error; - } - - // Create the actual reparse point - if (!DeviceIoControl(handle, - FSCTL_SET_REPARSE_POINT, - buffer, - used_buf_size, - NULL, - 0, - &bytes, - NULL)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto error; - } - - // Clean up - CloseHandle(handle); - free(buffer); - - SET_REQ_RESULT(req, 0); - return; - -error: - free(buffer); - - if (handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle); - } - - if (created) { - RemoveDirectoryW(new_path); - } -} - - -static void fs__symlink(uv_fs_t* req) { - WCHAR* pathw = req->pathw; - WCHAR* new_pathw = req->new_pathw; - int flags = req->file_flags; - int result; - - - if (flags & UV_FS_SYMLINK_JUNCTION) { - fs__create_junction(req, pathw, new_pathw); - } else if (pCreateSymbolicLinkW) { - result = pCreateSymbolicLinkW(new_pathw, - pathw, - flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1; - if (result == -1) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - SET_REQ_RESULT(req, result); - } - } else { - SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED); - } -} - - -static void fs__readlink(uv_fs_t* req) { - HANDLE handle; - - handle = CreateFileW(req->pathw, - 0, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__readlink_handle(handle, (char**) &req->ptr, NULL) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); - return; - } - - req->flags |= UV_FS_FREE_PTR; - SET_REQ_RESULT(req, 0); - - CloseHandle(handle); -} - - - -static void fs__chown(uv_fs_t* req) { - req->result = 0; -} - - -static void fs__fchown(uv_fs_t* req) { - req->result = 0; -} - - -static DWORD WINAPI uv_fs_thread_proc(void* parameter) { - uv_fs_t* req = (uv_fs_t*) parameter; - uv_loop_t* loop = req->loop; - - assert(req != NULL); - assert(req->type == UV_FS); - -#define XX(uc, lc) case UV_FS_##uc: fs__##lc(req); break; - switch (req->fs_type) { - XX(OPEN, open) - XX(CLOSE, close) - XX(READ, read) - XX(WRITE, write) - XX(SENDFILE, sendfile) - XX(STAT, stat) - XX(LSTAT, lstat) - XX(FSTAT, fstat) - XX(FTRUNCATE, ftruncate) - XX(UTIME, utime) - XX(FUTIME, futime) - XX(CHMOD, chmod) - XX(FCHMOD, fchmod) - XX(FSYNC, fsync) - XX(FDATASYNC, fdatasync) - XX(UNLINK, unlink) - XX(RMDIR, rmdir) - XX(MKDIR, mkdir) - XX(RENAME, rename) - XX(READDIR, readdir) - XX(LINK, link) - XX(SYMLINK, symlink) - XX(READLINK, readlink) - XX(CHOWN, chown) - XX(FCHOWN, fchown); - default: - assert(!"bad uv_fs_type"); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, - int mode, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_OPEN, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->file_flags = flags; - req->mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__open(req); - return req->result; - } -} - - -int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_CLOSE, cb); - req->fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__close(req); - return req->result; - } -} - - -int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf, - size_t length, int64_t offset, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_READ, cb); - - req->fd = fd; - req->buf = buf; - req->length = length; - req->offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__read(req); - return req->result; - } -} - - -int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file fd, const void* buf, - size_t length, int64_t offset, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_WRITE, cb); - - req->fd = fd; - req->buf = (void*) buf; - req->length = length; - req->offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__write(req); - return req->result; - } -} - - -int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_UNLINK, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__unlink(req); - return req->result; - } -} - - -int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_MKDIR, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__mkdir(req); - return req->result; - } -} - - -int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_RMDIR, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__rmdir(req); - return req->result; - } -} - - -int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_READDIR, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->file_flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__readdir(req); - return req->result; - } -} - - -int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, - const char* new_path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_LINK, cb); - - err = fs__capture_path(loop, req, path, new_path, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__link(req); - return req->result; - } -} - - -int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, - const char* new_path, int flags, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_SYMLINK, cb); - - err = fs__capture_path(loop, req, path, new_path, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->file_flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__symlink(req); - return req->result; - } -} - - -int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_READLINK, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__readlink(req); - return req->result; - } -} - - -int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, - uv_gid_t gid, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_CHOWN, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__chown(req); - return req->result; - } -} - - -int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid, - uv_gid_t gid, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FCHOWN, cb); - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fchown(req); - return req->result; - } -} - - -int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_STAT, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__stat(req); - return req->result; - } -} - - -int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_LSTAT, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__lstat(req); - return req->result; - } -} - - -int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FSTAT, cb); - req->fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fstat(req); - return req->result; - } -} - - -int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, - const char* new_path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_RENAME, cb); - - err = fs__capture_path(loop, req, path, new_path, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__rename(req); - return req->result; - } -} - - -int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FSYNC, cb); - req->fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fsync(req); - return req->result; - } -} - - -int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb); - req->fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fdatasync(req); - return req->result; - } -} - - -int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd, - int64_t offset, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb); - - req->fd = fd; - req->offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__ftruncate(req); - return req->result; - } -} - - - -int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out, - uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb); - - req->fd = fd_in; - req->fd_out = fd_out; - req->offset = in_offset; - req->length = length; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__sendfile(req); - return req->result; - } -} - - -int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_CHMOD, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__chmod(req); - return req->result; - } -} - - -int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode, - uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb); - - req->fd = fd; - req->mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fchmod(req); - return req->result; - } -} - - -int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, - double mtime, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_UTIME, cb); - - err = fs__capture_path(loop, req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->atime = atime; - req->mtime = mtime; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__utime(req); - return req->result; - } -} - - -int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime, - double mtime, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FUTIME, cb); - - req->fd = fd; - req->atime = atime; - req->mtime = mtime; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__futime(req); - return req->result; - } -} - - -void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req) { - assert(req->cb); - uv__req_unregister(loop, req); - req->cb(req); -} - - -void uv_fs_req_cleanup(uv_fs_t* req) { - if (req->flags & UV_FS_CLEANEDUP) - return; - - if (req->flags & UV_FS_FREE_PATHS) - free(req->pathw); - - if (req->flags & UV_FS_FREE_PTR) - free(req->ptr); - - req->path = NULL; - req->pathw = NULL; - req->new_pathw = NULL; - req->ptr = NULL; - - req->flags |= UV_FS_CLEANEDUP; -} - diff --git a/third-party/libuv/src/win/getaddrinfo.c b/third-party/libuv/src/win/getaddrinfo.c deleted file mode 100644 index fb4ab0a602..0000000000 --- a/third-party/libuv/src/win/getaddrinfo.c +++ /dev/null @@ -1,344 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <malloc.h> - -#include "uv.h" -#include "internal.h" -#include "req-inl.h" - - -/* - * MinGW is missing this - */ -#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR) - typedef struct addrinfoW { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - WCHAR* ai_canonname; - struct sockaddr* ai_addr; - struct addrinfoW* ai_next; - } ADDRINFOW, *PADDRINFOW; - - DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const WCHAR* node, - const WCHAR* service, - const ADDRINFOW* hints, - PADDRINFOW* result); - - DECLSPEC_IMPORT void WSAAPI FreeAddrInfoW(PADDRINFOW pAddrInfo); -#endif - - -/* adjust size value to be multiple of 4. Use to keep pointer aligned */ -/* Do we need different versions of this for different architectures? */ -#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2) - - -/* getaddrinfo worker thread implementation */ -static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) { - uv_getaddrinfo_t* req = (uv_getaddrinfo_t*) parameter; - uv_loop_t* loop = req->loop; - int ret; - - assert(req != NULL); - - /* call OS function on this thread */ - ret = GetAddrInfoW(req->node, - req->service, - req->hints, - &req->res); - req->retcode = ret; - - /* post getaddrinfo completed */ - POST_COMPLETION_FOR_REQ(loop, req); - - return 0; -} - - -/* - * Called from uv_run when complete. Call user specified callback - * then free returned addrinfo - * Returned addrinfo strings are converted from UTF-16 to UTF-8. - * - * To minimize allocation we calculate total size required, - * and copy all structs and referenced strings into the one block. - * Each size calculation is adjusted to avoid unaligned pointers. - */ -void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* req) { - int addrinfo_len = 0; - int name_len = 0; - size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); - struct addrinfoW* addrinfow_ptr; - struct addrinfo* addrinfo_ptr; - char* alloc_ptr = NULL; - char* cur_ptr = NULL; - int err = 0; - - /* release input parameter memory */ - if (req->alloc != NULL) { - free(req->alloc); - req->alloc = NULL; - } - - if (req->retcode == 0) { - /* convert addrinfoW to addrinfo */ - /* first calculate required length */ - addrinfow_ptr = req->res; - while (addrinfow_ptr != NULL) { - addrinfo_len += addrinfo_struct_len + - ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); - if (addrinfow_ptr->ai_canonname != NULL) { - name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0); - if (name_len == 0) { - /* FIXME(bnoordhuis) Retain GetLastError(). */ - err = UV_EAI_SYSTEM; - goto complete; - } - addrinfo_len += ALIGNED_SIZE(name_len); - } - addrinfow_ptr = addrinfow_ptr->ai_next; - } - - /* allocate memory for addrinfo results */ - alloc_ptr = (char*)malloc(addrinfo_len); - - /* do conversions */ - if (alloc_ptr != NULL) { - cur_ptr = alloc_ptr; - addrinfow_ptr = req->res; - - while (addrinfow_ptr != NULL) { - /* copy addrinfo struct data */ - assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len); - addrinfo_ptr = (struct addrinfo*)cur_ptr; - addrinfo_ptr->ai_family = addrinfow_ptr->ai_family; - addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype; - addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol; - addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags; - addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen; - addrinfo_ptr->ai_canonname = NULL; - addrinfo_ptr->ai_addr = NULL; - addrinfo_ptr->ai_next = NULL; - - cur_ptr += addrinfo_struct_len; - - /* copy sockaddr */ - if (addrinfo_ptr->ai_addrlen > 0) { - assert(cur_ptr + addrinfo_ptr->ai_addrlen <= - alloc_ptr + addrinfo_len); - memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen); - addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr; - cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen); - } - - /* convert canonical name to UTF-8 */ - if (addrinfow_ptr->ai_canonname != NULL) { - name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, - -1, - NULL, - 0); - assert(name_len > 0); - assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len); - name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, - -1, - cur_ptr, - name_len); - assert(name_len > 0); - addrinfo_ptr->ai_canonname = cur_ptr; - cur_ptr += ALIGNED_SIZE(name_len); - } - assert(cur_ptr <= alloc_ptr + addrinfo_len); - - /* set next ptr */ - addrinfow_ptr = addrinfow_ptr->ai_next; - if (addrinfow_ptr != NULL) { - addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr; - } - } - } else { - err = UV_EAI_MEMORY; - } - } else { - /* GetAddrInfo failed */ - err = uv__getaddrinfo_translate_error(req->retcode); - } - - /* return memory to system */ - if (req->res != NULL) { - FreeAddrInfoW(req->res); - req->res = NULL; - } - -complete: - uv__req_unregister(loop, req); - - /* finally do callback with converted result */ - req->getaddrinfo_cb(req, err, (struct addrinfo*)alloc_ptr); -} - - -void uv_freeaddrinfo(struct addrinfo* ai) { - char* alloc_ptr = (char*)ai; - - /* release copied result memory */ - if (alloc_ptr != NULL) { - free(alloc_ptr); - } -} - - -/* - * Entry point for getaddrinfo - * we convert the UTF-8 strings to UNICODE - * and save the UNICODE string pointers in the req - * We also copy hints so that caller does not need to keep memory until the - * callback. - * return 0 if a callback will be made - * return error code if validation fails - * - * To minimize allocation we calculate total size required, - * and copy all structs and referenced strings into the one block. - * Each size calculation is adjusted to avoid unaligned pointers. - */ -int uv_getaddrinfo(uv_loop_t* loop, - uv_getaddrinfo_t* req, - uv_getaddrinfo_cb getaddrinfo_cb, - const char* node, - const char* service, - const struct addrinfo* hints) { - int nodesize = 0; - int servicesize = 0; - int hintssize = 0; - char* alloc_ptr = NULL; - int err; - - if (req == NULL || getaddrinfo_cb == NULL || - (node == NULL && service == NULL)) { - err = WSAEINVAL; - goto error; - } - - uv_req_init(loop, (uv_req_t*)req); - - req->getaddrinfo_cb = getaddrinfo_cb; - req->res = NULL; - req->type = UV_GETADDRINFO; - req->loop = loop; - - /* calculate required memory size for all input values */ - if (node != NULL) { - nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(WCHAR)); - if (nodesize == 0) { - err = GetLastError(); - goto error; - } - } - - if (service != NULL) { - servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) * - sizeof(WCHAR)); - if (servicesize == 0) { - err = GetLastError(); - goto error; - } - } - if (hints != NULL) { - hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW)); - } - - /* allocate memory for inputs, and partition it as needed */ - alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize); - if (!alloc_ptr) { - err = WSAENOBUFS; - goto error; - } - - /* save alloc_ptr now so we can free if error */ - req->alloc = (void*)alloc_ptr; - - /* convert node string to UTF16 into allocated memory and save pointer in */ - /* the reques. */ - if (node != NULL) { - req->node = (WCHAR*)alloc_ptr; - if (uv_utf8_to_utf16(node, - (WCHAR*) alloc_ptr, - nodesize / sizeof(WCHAR)) == 0) { - err = GetLastError(); - goto error; - } - alloc_ptr += nodesize; - } else { - req->node = NULL; - } - - /* convert service string to UTF16 into allocated memory and save pointer */ - /* in the req. */ - if (service != NULL) { - req->service = (WCHAR*)alloc_ptr; - if (uv_utf8_to_utf16(service, - (WCHAR*) alloc_ptr, - servicesize / sizeof(WCHAR)) == 0) { - err = GetLastError(); - goto error; - } - alloc_ptr += servicesize; - } else { - req->service = NULL; - } - - /* copy hints to allocated memory and save pointer in req */ - if (hints != NULL) { - req->hints = (struct addrinfoW*)alloc_ptr; - req->hints->ai_family = hints->ai_family; - req->hints->ai_socktype = hints->ai_socktype; - req->hints->ai_protocol = hints->ai_protocol; - req->hints->ai_flags = hints->ai_flags; - req->hints->ai_addrlen = 0; - req->hints->ai_canonname = NULL; - req->hints->ai_addr = NULL; - req->hints->ai_next = NULL; - } else { - req->hints = NULL; - } - - /* Ask thread to run. Treat this as a long operation */ - if (QueueUserWorkItem(&getaddrinfo_thread_proc, - req, - WT_EXECUTELONGFUNCTION) == 0) { - err = GetLastError(); - goto error; - } - - uv__req_register(loop, req); - - return 0; - -error: - if (req != NULL && req->alloc != NULL) { - free(req->alloc); - } - return uv_translate_sys_error(err); -} diff --git a/third-party/libuv/src/win/handle-inl.h b/third-party/libuv/src/win/handle-inl.h deleted file mode 100644 index 5776eb7f76..0000000000 --- a/third-party/libuv/src/win/handle-inl.h +++ /dev/null @@ -1,179 +0,0 @@ -/* 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 - * 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. - */ - -#ifndef UV_WIN_HANDLE_INL_H_ -#define UV_WIN_HANDLE_INL_H_ - -#include <assert.h> -#include <io.h> - -#include "uv.h" -#include "internal.h" - - -#define DECREASE_ACTIVE_COUNT(loop, handle) \ - do { \ - if (--(handle)->activecnt == 0 && \ - !((handle)->flags & UV__HANDLE_CLOSING)) { \ - uv__handle_stop((handle)); \ - } \ - assert((handle)->activecnt >= 0); \ - } while (0) - - -#define INCREASE_ACTIVE_COUNT(loop, handle) \ - do { \ - if ((handle)->activecnt++ == 0) { \ - uv__handle_start((handle)); \ - } \ - assert((handle)->activecnt > 0); \ - } while (0) - - -#define DECREASE_PENDING_REQ_COUNT(handle) \ - do { \ - assert(handle->reqs_pending > 0); \ - handle->reqs_pending--; \ - \ - if (handle->flags & UV__HANDLE_CLOSING && \ - handle->reqs_pending == 0) { \ - uv_want_endgame(loop, (uv_handle_t*)handle); \ - } \ - } while (0) - - -#define uv__handle_closing(handle) \ - do { \ - assert(!((handle)->flags & UV__HANDLE_CLOSING)); \ - \ - if (!(((handle)->flags & UV__HANDLE_ACTIVE) && \ - ((handle)->flags & UV__HANDLE_REF))) \ - uv__active_handle_add((uv_handle_t*) (handle)); \ - \ - (handle)->flags |= UV__HANDLE_CLOSING; \ - (handle)->flags &= ~UV__HANDLE_ACTIVE; \ - } while (0) - - -#define uv__handle_close(handle) \ - do { \ - QUEUE_REMOVE(&(handle)->handle_queue); \ - uv__active_handle_rm((uv_handle_t*) (handle)); \ - \ - (handle)->flags |= UV_HANDLE_CLOSED; \ - \ - if ((handle)->close_cb) \ - (handle)->close_cb((uv_handle_t*) (handle)); \ - } while (0) - - -INLINE static void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) { - if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) { - handle->flags |= UV_HANDLE_ENDGAME_QUEUED; - - handle->endgame_next = loop->endgame_handles; - loop->endgame_handles = handle; - } -} - - -INLINE static void uv_process_endgames(uv_loop_t* loop) { - uv_handle_t* handle; - - while (loop->endgame_handles) { - handle = loop->endgame_handles; - loop->endgame_handles = handle->endgame_next; - - handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED; - - switch (handle->type) { - case UV_TCP: - uv_tcp_endgame(loop, (uv_tcp_t*) handle); - break; - - case UV_NAMED_PIPE: - uv_pipe_endgame(loop, (uv_pipe_t*) handle); - break; - - case UV_TTY: - uv_tty_endgame(loop, (uv_tty_t*) handle); - break; - - case UV_UDP: - uv_udp_endgame(loop, (uv_udp_t*) handle); - break; - - case UV_POLL: - uv_poll_endgame(loop, (uv_poll_t*) handle); - break; - - case UV_TIMER: - uv_timer_endgame(loop, (uv_timer_t*) handle); - break; - - case UV_PREPARE: - case UV_CHECK: - case UV_IDLE: - uv_loop_watcher_endgame(loop, handle); - break; - - case UV_ASYNC: - uv_async_endgame(loop, (uv_async_t*) handle); - break; - - case UV_SIGNAL: - uv_signal_endgame(loop, (uv_signal_t*) handle); - break; - - case UV_PROCESS: - uv_process_endgame(loop, (uv_process_t*) handle); - break; - - case UV_FS_EVENT: - uv_fs_event_endgame(loop, (uv_fs_event_t*) handle); - break; - - case UV_FS_POLL: - uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle); - break; - - default: - assert(0); - break; - } - } -} - -INLINE static HANDLE uv__get_osfhandle(int fd) -{ - /* _get_osfhandle() raises an assert in debug builds if the FD is invalid. */ - /* But it also correctly checks the FD and returns INVALID_HANDLE_VALUE */ - /* for invalid FDs in release builds (or if you let the assert continue). */ - /* So this wrapper function disables asserts when calling _get_osfhandle. */ - - HANDLE handle; - UV_BEGIN_DISABLE_CRT_ASSERT(); - handle = (HANDLE) _get_osfhandle(fd); - UV_END_DISABLE_CRT_ASSERT(); - return handle; -} - -#endif /* UV_WIN_HANDLE_INL_H_ */ diff --git a/third-party/libuv/src/win/handle.c b/third-party/libuv/src/win/handle.c deleted file mode 100644 index 72b49d9790..0000000000 --- a/third-party/libuv/src/win/handle.c +++ /dev/null @@ -1,154 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <io.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" - - -uv_handle_type uv_guess_handle(uv_file file) { - HANDLE handle; - DWORD mode; - - if (file < 0) { - return UV_UNKNOWN_HANDLE; - } - - handle = uv__get_osfhandle(file); - - switch (GetFileType(handle)) { - case FILE_TYPE_CHAR: - if (GetConsoleMode(handle, &mode)) { - return UV_TTY; - } else { - return UV_FILE; - } - - case FILE_TYPE_PIPE: - return UV_NAMED_PIPE; - - case FILE_TYPE_DISK: - return UV_FILE; - - default: - return UV_UNKNOWN_HANDLE; - } -} - - -int uv_is_active(const uv_handle_t* handle) { - return (handle->flags & UV__HANDLE_ACTIVE) && - !(handle->flags & UV__HANDLE_CLOSING); -} - - -void uv_close(uv_handle_t* handle, uv_close_cb cb) { - uv_loop_t* loop = handle->loop; - - if (handle->flags & UV__HANDLE_CLOSING) { - assert(0); - return; - } - - handle->close_cb = cb; - - /* Handle-specific close actions */ - switch (handle->type) { - case UV_TCP: - uv_tcp_close(loop, (uv_tcp_t*)handle); - return; - - case UV_NAMED_PIPE: - uv_pipe_close(loop, (uv_pipe_t*) handle); - return; - - case UV_TTY: - uv_tty_close((uv_tty_t*) handle); - return; - - case UV_UDP: - uv_udp_close(loop, (uv_udp_t*) handle); - return; - - case UV_POLL: - uv_poll_close(loop, (uv_poll_t*) handle); - return; - - case UV_TIMER: - uv_timer_stop((uv_timer_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_PREPARE: - uv_prepare_stop((uv_prepare_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_CHECK: - uv_check_stop((uv_check_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_IDLE: - uv_idle_stop((uv_idle_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_ASYNC: - uv_async_close(loop, (uv_async_t*) handle); - return; - - case UV_SIGNAL: - uv_signal_close(loop, (uv_signal_t*) handle); - return; - - case UV_PROCESS: - uv_process_close(loop, (uv_process_t*) handle); - return; - - case UV_FS_EVENT: - uv_fs_event_close(loop, (uv_fs_event_t*) handle); - return; - - case UV_FS_POLL: - uv__fs_poll_close((uv_fs_poll_t*) handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - default: - /* Not supported */ - abort(); - } -} - - -int uv_is_closing(const uv_handle_t* handle) { - return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED)); -} diff --git a/third-party/libuv/src/win/internal.h b/third-party/libuv/src/win/internal.h deleted file mode 100644 index cf6c85846c..0000000000 --- a/third-party/libuv/src/win/internal.h +++ /dev/null @@ -1,379 +0,0 @@ -/* 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 - * 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. - */ - -#ifndef UV_WIN_INTERNAL_H_ -#define UV_WIN_INTERNAL_H_ - -#include "uv.h" -#include "../uv-common.h" - -#include "tree.h" -#include "winapi.h" -#include "winsock.h" - -#ifdef _MSC_VER -# define INLINE __inline -#else -# define INLINE inline -#endif - - -#ifdef _DEBUG -extern __declspec( thread ) int uv__crt_assert_enabled; - -#define UV_BEGIN_DISABLE_CRT_ASSERT() \ - { \ - int uv__saved_crt_assert_enabled = uv__crt_assert_enabled; \ - uv__crt_assert_enabled = FALSE; - - -#define UV_END_DISABLE_CRT_ASSERT() \ - uv__crt_assert_enabled = uv__saved_crt_assert_enabled; \ - } - -#else -#define UV_BEGIN_DISABLE_CRT_ASSERT() -#define UV_END_DISABLE_CRT_ASSERT() -#endif - -/* - * Handles - * (also see handle-inl.h) - */ - -/* Used by all handles. */ -#define UV_HANDLE_CLOSED 0x00000002 -#define UV_HANDLE_ENDGAME_QUEUED 0x00000004 -#define UV_HANDLE_ACTIVE 0x00000010 - -/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */ -/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */ -/* uv-common.h: #define UV__HANDLE_REF 0x00000020 */ -/* uv-common.h: #define UV_HANDLE_INTERNAL 0x00000080 */ - -/* Used by streams and UDP handles. */ -#define UV_HANDLE_READING 0x00000100 -#define UV_HANDLE_BOUND 0x00000200 -#define UV_HANDLE_BIND_ERROR 0x00000400 -#define UV_HANDLE_LISTENING 0x00000800 -#define UV_HANDLE_CONNECTION 0x00001000 -#define UV_HANDLE_CONNECTED 0x00002000 -#define UV_HANDLE_READABLE 0x00008000 -#define UV_HANDLE_WRITABLE 0x00010000 -#define UV_HANDLE_READ_PENDING 0x00020000 -#define UV_HANDLE_SYNC_BYPASS_IOCP 0x00040000 -#define UV_HANDLE_ZERO_READ 0x00080000 -#define UV_HANDLE_EMULATE_IOCP 0x00100000 -#define UV_HANDLE_BLOCKING_WRITES 0x00200000 - -/* Only used by uv_tcp_t handles. */ -#define UV_HANDLE_IPV6 0x01000000 -#define UV_HANDLE_TCP_NODELAY 0x02000000 -#define UV_HANDLE_TCP_KEEPALIVE 0x04000000 -#define UV_HANDLE_TCP_SINGLE_ACCEPT 0x08000000 -#define UV_HANDLE_TCP_ACCEPT_STATE_CHANGING 0x10000000 -#define UV_HANDLE_TCP_SOCKET_CLOSED 0x20000000 -#define UV_HANDLE_SHARED_TCP_SOCKET 0x40000000 - -/* Only used by uv_pipe_t handles. */ -#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000 -#define UV_HANDLE_PIPESERVER 0x02000000 - -/* Only used by uv_tty_t handles. */ -#define UV_HANDLE_TTY_READABLE 0x01000000 -#define UV_HANDLE_TTY_RAW 0x02000000 -#define UV_HANDLE_TTY_SAVED_POSITION 0x04000000 -#define UV_HANDLE_TTY_SAVED_ATTRIBUTES 0x08000000 - -/* Only used by uv_poll_t handles. */ -#define UV_HANDLE_POLL_SLOW 0x02000000 - - -/* - * Requests: see req-inl.h - */ - - -/* - * Streams: see stream-inl.h - */ - - -/* - * TCP - */ -int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb); -int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client); -int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); - -void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req); -void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_write_t* req); -void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_req_t* req); -void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_connect_t* req); - -void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp); -void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle); - -int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info, - int tcp_connection); - -int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid, - LPWSAPROTOCOL_INFOW protocol_info); - - -/* - * UDP - */ -void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req); -void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, - uv_udp_send_t* req); - -void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle); -void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle); - - -/* - * Pipes - */ -int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access, - char* name, size_t nameSize); - -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); -int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client); -int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -int uv_pipe_read2_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, - uv_read2_cb read_cb); -int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); -int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, - uv_write_cb cb); - -void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* req); -void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_write_t* req); -void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* raw_req); -void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_connect_t* req); -void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_shutdown_t* req); - -void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle); -void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle); -void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle); - - -/* - * TTY - */ -void uv_console_init(); - -int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -int uv_tty_read_stop(uv_tty_t* handle); -int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); -void uv_tty_close(uv_tty_t* handle); - -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 */ -void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* raw_req); -/* TODO: remove me */ -void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, - uv_connect_t* req); - -void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle); - - -/* - * Poll watchers - */ -void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, - uv_req_t* req); - -int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle); -void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle); - - -/* - * Timers - */ -void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle); - -DWORD uv_get_poll_timeout(uv_loop_t* loop); -void uv__time_forward(uv_loop_t* loop, uint64_t msecs); -void uv_process_timers(uv_loop_t* loop); - - -/* - * Loop watchers - */ -void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle); - -void uv_prepare_invoke(uv_loop_t* loop); -void uv_check_invoke(uv_loop_t* loop); -void uv_idle_invoke(uv_loop_t* loop); - -void uv__once_init(); - - -/* - * Async watcher - */ -void uv_async_close(uv_loop_t* loop, uv_async_t* handle); -void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle); - -void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, - uv_req_t* req); - - -/* - * Signal watcher - */ -void uv_signals_init(); -int uv__signal_dispatch(int signum); - -void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle); -void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle); - -void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, - uv_req_t* req); - - -/* - * Spawn - */ -void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle); -void uv_process_close(uv_loop_t* loop, uv_process_t* handle); -void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle); - - -/* - * Error - */ -int uv_translate_sys_error(int sys_errno); - - -/* - * Getaddrinfo - */ -void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* req); - - -/* - * FS - */ -void uv_fs_init(); -void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req); - - -/* - * Threadpool - */ -void uv_process_work_req(uv_loop_t* loop, uv_work_t* req); - - -/* - * FS Event - */ -void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, - uv_fs_event_t* handle); -void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle); -void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle); - - -/* - * Stat poller. - */ -void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle); - - -/* - * Utilities. - */ -void uv__util_init(); - -int uv_parent_pid(); -void uv_fatal_error(const int errorno, const char* syscall); - - -/* - * Process stdio handles. - */ -int uv__stdio_create(uv_loop_t* loop, - const uv_process_options_t* options, - BYTE** buffer_ptr); -void uv__stdio_destroy(BYTE* buffer); -void uv__stdio_noinherit(BYTE* buffer); -int uv__stdio_verify(BYTE* buffer, WORD size); -WORD uv__stdio_size(BYTE* buffer); -HANDLE uv__stdio_handle(BYTE* buffer, int fd); - - -/* - * Winapi and ntapi utility functions - */ -void uv_winapi_init(); - - -/* - * Winsock utility functions - */ -void uv_winsock_init(); - -int uv_ntstatus_to_winsock_error(NTSTATUS status); - -BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target); -BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target); - -int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); -int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr, - int* addr_len, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); - -int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info, - OVERLAPPED* overlapped); - -/* Whether there are any non-IFS LSPs stacked on TCP */ -extern int uv_tcp_non_ifs_lsp_ipv4; -extern int uv_tcp_non_ifs_lsp_ipv6; - -/* Ip address used to bind to any port at any interface */ -extern struct sockaddr_in uv_addr_ip4_any_; -extern struct sockaddr_in6 uv_addr_ip6_any_; - -#endif /* UV_WIN_INTERNAL_H_ */ diff --git a/third-party/libuv/src/win/loop-watcher.c b/third-party/libuv/src/win/loop-watcher.c deleted file mode 100644 index 6dbc861edd..0000000000 --- a/third-party/libuv/src/win/loop-watcher.c +++ /dev/null @@ -1,124 +0,0 @@ -/* 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 - * 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 <assert.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" - - -void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - handle->flags |= UV_HANDLE_CLOSED; - uv__handle_close(handle); - } -} - - -#define UV_LOOP_WATCHER_DEFINE(name, NAME) \ - int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \ - uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME); \ - \ - return 0; \ - } \ - \ - \ - int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ - uv_loop_t* loop = handle->loop; \ - uv_##name##_t* old_head; \ - \ - assert(handle->type == UV_##NAME); \ - \ - if (handle->flags & UV_HANDLE_ACTIVE) \ - return 0; \ - \ - if (cb == NULL) \ - return UV_EINVAL; \ - \ - old_head = loop->name##_handles; \ - \ - handle->name##_next = old_head; \ - handle->name##_prev = NULL; \ - \ - if (old_head) { \ - old_head->name##_prev = handle; \ - } \ - \ - loop->name##_handles = handle; \ - \ - handle->name##_cb = cb; \ - handle->flags |= UV_HANDLE_ACTIVE; \ - uv__handle_start(handle); \ - \ - return 0; \ - } \ - \ - \ - int uv_##name##_stop(uv_##name##_t* handle) { \ - uv_loop_t* loop = handle->loop; \ - \ - assert(handle->type == UV_##NAME); \ - \ - if (!(handle->flags & UV_HANDLE_ACTIVE)) \ - return 0; \ - \ - /* Update loop head if needed */ \ - if (loop->name##_handles == handle) { \ - loop->name##_handles = handle->name##_next; \ - } \ - \ - /* Update the iterator-next pointer of needed */ \ - if (loop->next_##name##_handle == handle) { \ - loop->next_##name##_handle = handle->name##_next; \ - } \ - \ - if (handle->name##_prev) { \ - handle->name##_prev->name##_next = handle->name##_next; \ - } \ - if (handle->name##_next) { \ - handle->name##_next->name##_prev = handle->name##_prev; \ - } \ - \ - handle->flags &= ~UV_HANDLE_ACTIVE; \ - uv__handle_stop(handle); \ - \ - return 0; \ - } \ - \ - \ - void uv_##name##_invoke(uv_loop_t* loop) { \ - uv_##name##_t* handle; \ - \ - (loop)->next_##name##_handle = (loop)->name##_handles; \ - \ - while ((loop)->next_##name##_handle != NULL) { \ - handle = (loop)->next_##name##_handle; \ - (loop)->next_##name##_handle = handle->name##_next; \ - \ - handle->name##_cb(handle, 0); \ - } \ - } - -UV_LOOP_WATCHER_DEFINE(prepare, PREPARE) -UV_LOOP_WATCHER_DEFINE(check, CHECK) -UV_LOOP_WATCHER_DEFINE(idle, IDLE) diff --git a/third-party/libuv/src/win/pipe.c b/third-party/libuv/src/win/pipe.c deleted file mode 100644 index f3d3110d31..0000000000 --- a/third-party/libuv/src/win/pipe.c +++ /dev/null @@ -1,1747 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <io.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -/* A zero-size buffer for use by uv_pipe_read */ -static char uv_zero_[] = ""; - -/* Null uv_buf_t */ -static const uv_buf_t uv_null_buf_ = { 0, NULL }; - -/* The timeout that the pipe will wait for the remote end to write data */ -/* when the local ends wants to shut it down. */ -static const int64_t eof_timeout = 50; /* ms */ - -static const int default_pending_pipe_instances = 4; - -/* IPC protocol flags. */ -#define UV_IPC_RAW_DATA 0x0001 -#define UV_IPC_TCP_SERVER 0x0002 -#define UV_IPC_TCP_CONNECTION 0x0004 - -/* IPC frame header. */ -typedef struct { - int flags; - uint64_t raw_data_length; -} uv_ipc_frame_header_t; - -/* IPC frame, which contains an imported TCP socket stream. */ -typedef struct { - uv_ipc_frame_header_t header; - WSAPROTOCOL_INFOW socket_info; -} uv_ipc_frame_uv_stream; - -static void eof_timer_init(uv_pipe_t* pipe); -static void eof_timer_start(uv_pipe_t* pipe); -static void eof_timer_stop(uv_pipe_t* pipe); -static void eof_timer_cb(uv_timer_t* timer, int status); -static void eof_timer_destroy(uv_pipe_t* pipe); -static void eof_timer_close_cb(uv_handle_t* handle); - - -static void uv_unique_pipe_name(char* ptr, char* name, size_t size) { - _snprintf(name, size, "\\\\.\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId()); -} - - -int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { - uv_stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); - - handle->reqs_pending = 0; - handle->handle = INVALID_HANDLE_VALUE; - handle->name = NULL; - handle->ipc_pid = 0; - handle->remaining_ipc_rawdata_bytes = 0; - handle->pending_ipc_info.socket_info = NULL; - handle->pending_ipc_info.tcp_connection = 0; - handle->ipc = ipc; - handle->non_overlapped_writes_tail = NULL; - - uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req); - - return 0; -} - - -static void uv_pipe_connection_init(uv_pipe_t* handle) { - uv_connection_init((uv_stream_t*) handle); - handle->read_req.data = handle; - handle->eof_timer = NULL; -} - - -static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) { - HANDLE pipeHandle; - - /* - * Assume that we have a duplex pipe first, so attempt to - * connect with GENERIC_READ | GENERIC_WRITE. - */ - pipeHandle = CreateFileW(name, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - if (pipeHandle != INVALID_HANDLE_VALUE) { - *duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - return pipeHandle; - } - - /* - * If the pipe is not duplex CreateFileW fails with - * ERROR_ACCESS_DENIED. In that case try to connect - * as a read-only or write-only. - */ - if (GetLastError() == ERROR_ACCESS_DENIED) { - pipeHandle = CreateFileW(name, - GENERIC_READ | FILE_WRITE_ATTRIBUTES, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { - *duplex_flags = UV_HANDLE_READABLE; - return pipeHandle; - } - } - - if (GetLastError() == ERROR_ACCESS_DENIED) { - pipeHandle = CreateFileW(name, - GENERIC_WRITE | FILE_READ_ATTRIBUTES, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { - *duplex_flags = UV_HANDLE_WRITABLE; - return pipeHandle; - } - } - - return INVALID_HANDLE_VALUE; -} - - -int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access, - char* name, size_t nameSize) { - HANDLE pipeHandle; - int err; - char* ptr = (char*)handle; - - for (;;) { - uv_unique_pipe_name(ptr, name, nameSize); - - pipeHandle = CreateNamedPipeA(name, - access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { - /* No name collisions. We're done. */ - break; - } - - err = GetLastError(); - if (err != ERROR_PIPE_BUSY && err != ERROR_ACCESS_DENIED) { - goto error; - } - - /* Pipe name collision. Increment the pointer and try again. */ - ptr++; - } - - if (CreateIoCompletionPort(pipeHandle, - loop->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - err = GetLastError(); - goto error; - } - - uv_pipe_connection_init(handle); - handle->handle = pipeHandle; - - return 0; - - error: - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); - } - - return err; -} - - -static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle, - HANDLE pipeHandle, DWORD duplex_flags) { - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_MODE_INFORMATION mode_info; - DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT; - - if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) { - /* If this returns ERROR_INVALID_PARAMETER we probably opened something */ - /* that is not a pipe. */ - if (GetLastError() == ERROR_INVALID_PARAMETER) { - SetLastError(WSAENOTSOCK); - } - return -1; - } - - /* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */ - nt_status = pNtQueryInformationFile(pipeHandle, - &io_status, - &mode_info, - sizeof(mode_info), - FileModeInformation); - if (nt_status != STATUS_SUCCESS) { - return -1; - } - - if (mode_info.Mode & FILE_SYNCHRONOUS_IO_ALERT || - mode_info.Mode & FILE_SYNCHRONOUS_IO_NONALERT) { - /* Non-overlapped pipe. */ - handle->flags |= UV_HANDLE_NON_OVERLAPPED_PIPE; - } else { - /* Overlapped pipe. Try to associate with IOCP. */ - if (CreateIoCompletionPort(pipeHandle, - loop->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - handle->flags |= UV_HANDLE_EMULATE_IOCP; - } - } - - handle->handle = pipeHandle; - handle->flags |= duplex_flags; - - return 0; -} - - -static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) { - uv_loop_t* loop; - uv_pipe_t* handle; - uv_shutdown_t* req; - - req = (uv_shutdown_t*) parameter; - assert(req); - handle = (uv_pipe_t*) req->handle; - assert(handle); - loop = handle->loop; - assert(loop); - - FlushFileBuffers(handle->handle); - - /* Post completed */ - POST_COMPLETION_FOR_REQ(loop, req); - - return 0; -} - - -void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { - int err; - DWORD result; - uv_shutdown_t* req; - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_PIPE_LOCAL_INFORMATION pipe_info; - - if ((handle->flags & UV_HANDLE_CONNECTION) && - handle->shutdown_req != NULL && - handle->write_reqs_pending == 0) { - req = handle->shutdown_req; - - /* Clear the shutdown_req field so we don't go here again. */ - handle->shutdown_req = NULL; - - if (handle->flags & UV__HANDLE_CLOSING) { - UNREGISTER_HANDLE_REQ(loop, handle, req); - - /* Already closing. Cancel the shutdown. */ - if (req->cb) { - req->cb(req, UV_ECANCELED); - } - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - /* Try to avoid flushing the pipe buffer in the thread pool. */ - nt_status = pNtQueryInformationFile(handle->handle, - &io_status, - &pipe_info, - sizeof pipe_info, - FilePipeLocalInformation); - - if (nt_status != STATUS_SUCCESS) { - /* Failure */ - UNREGISTER_HANDLE_REQ(loop, handle, req); - - handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ - if (req->cb) { - err = pRtlNtStatusToDosError(nt_status); - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) { - /* Short-circuit, no need to call FlushFileBuffers. */ - uv_insert_pending_req(loop, (uv_req_t*) req); - return; - } - - /* Run FlushFileBuffers in the thread pool. */ - result = QueueUserWorkItem(pipe_shutdown_thread_proc, - req, - WT_EXECUTELONGFUNCTION); - if (result) { - return; - - } else { - /* Failure. */ - UNREGISTER_HANDLE_REQ(loop, handle, req); - - handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ - if (req->cb) { - err = GetLastError(); - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - } - - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (handle->flags & UV_HANDLE_CONNECTION) { - if (handle->pending_ipc_info.socket_info) { - free(handle->pending_ipc_info.socket_info); - handle->pending_ipc_info.socket_info = NULL; - } - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->read_req.wait_handle); - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - } - if (handle->read_req.event_handle) { - CloseHandle(handle->read_req.event_handle); - handle->read_req.event_handle = NULL; - } - } - } - - if (handle->flags & UV_HANDLE_PIPESERVER) { - assert(handle->accept_reqs); - free(handle->accept_reqs); - handle->accept_reqs = NULL; - } - - uv__handle_close(handle); - } -} - - -void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { - handle->pending_instances = count; - handle->flags |= UV_HANDLE_PIPESERVER; -} - - -/* Creates a pipe server. */ -int uv_pipe_bind(uv_pipe_t* handle, const char* name) { - uv_loop_t* loop = handle->loop; - int i, err, nameSize; - uv_pipe_accept_t* req; - - if (handle->flags & UV_HANDLE_BOUND) { - return UV_EINVAL; - } - - if (!name) { - return UV_EINVAL; - } - - if (!(handle->flags & UV_HANDLE_PIPESERVER)) { - handle->pending_instances = default_pending_pipe_instances; - } - - handle->accept_reqs = (uv_pipe_accept_t*) - malloc(sizeof(uv_pipe_accept_t) * handle->pending_instances); - if (!handle->accept_reqs) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - for (i = 0; i < handle->pending_instances; i++) { - req = &handle->accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; - req->data = handle; - req->pipeHandle = INVALID_HANDLE_VALUE; - req->next_pending = NULL; - } - - /* Convert name to UTF16. */ - nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR); - handle->name = (WCHAR*)malloc(nameSize); - if (!handle->name) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) { - return uv_translate_sys_error(GetLastError()); - } - - /* - * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE. - * If this fails then there's already a pipe server for the given pipe name. - */ - handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | - FILE_FLAG_FIRST_PIPE_INSTANCE, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); - - if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) { - err = GetLastError(); - if (err == ERROR_ACCESS_DENIED) { - err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */ - } else if (err == ERROR_PATH_NOT_FOUND || err == ERROR_INVALID_NAME) { - err = WSAEACCES; /* Translates to UV_EACCES. */ - } - goto error; - } - - if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle, 0)) { - err = GetLastError(); - goto error; - } - - handle->pending_accepts = NULL; - handle->flags |= UV_HANDLE_PIPESERVER; - handle->flags |= UV_HANDLE_BOUND; - - return 0; - -error: - if (handle->name) { - free(handle->name); - handle->name = NULL; - } - - if (handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->accept_reqs[0].pipeHandle); - handle->accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE; - } - - return uv_translate_sys_error(err); -} - - -static DWORD WINAPI pipe_connect_thread_proc(void* parameter) { - uv_loop_t* loop; - uv_pipe_t* handle; - uv_connect_t* req; - HANDLE pipeHandle = INVALID_HANDLE_VALUE; - DWORD duplex_flags; - - req = (uv_connect_t*) parameter; - assert(req); - handle = (uv_pipe_t*) req->handle; - assert(handle); - loop = handle->loop; - assert(loop); - - /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */ - /* We wait for the pipe to become available with WaitNamedPipe. */ - while (WaitNamedPipeW(handle->name, 30000)) { - /* The pipe is now available, try to connect. */ - pipeHandle = open_named_pipe(handle->name, &duplex_flags); - if (pipeHandle != INVALID_HANDLE_VALUE) { - break; - } - - SwitchToThread(); - } - - if (pipeHandle != INVALID_HANDLE_VALUE && - !uv_set_pipe_handle(loop, handle, pipeHandle, duplex_flags)) { - SET_REQ_SUCCESS(req); - } else { - SET_REQ_ERROR(req, GetLastError()); - } - - /* Post completed */ - POST_COMPLETION_FOR_REQ(loop, req); - - return 0; -} - - -void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, - const char* name, uv_connect_cb cb) { - uv_loop_t* loop = handle->loop; - int err, nameSize; - HANDLE pipeHandle = INVALID_HANDLE_VALUE; - DWORD duplex_flags; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - - /* Convert name to UTF16. */ - nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR); - handle->name = (WCHAR*)malloc(nameSize); - if (!handle->name) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) { - err = GetLastError(); - goto error; - } - - pipeHandle = open_named_pipe(handle->name, &duplex_flags); - if (pipeHandle == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_PIPE_BUSY) { - /* Wait for the server to make a pipe instance available. */ - if (!QueueUserWorkItem(&pipe_connect_thread_proc, - req, - WT_EXECUTELONGFUNCTION)) { - err = GetLastError(); - goto error; - } - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - - return; - } - - err = GetLastError(); - goto error; - } - - assert(pipeHandle != INVALID_HANDLE_VALUE); - - if (uv_set_pipe_handle(loop, - (uv_pipe_t*) req->handle, - pipeHandle, - duplex_flags)) { - err = GetLastError(); - goto error; - } - - SET_REQ_SUCCESS(req); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - return; - -error: - if (handle->name) { - free(handle->name); - handle->name = NULL; - } - - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); - } - - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, err); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - return; -} - - -/* Cleans up uv_pipe_t (server or connection) and all resources associated */ -/* with it. */ -void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) { - int i; - HANDLE pipeHandle; - - if (handle->name) { - free(handle->name); - handle->name = NULL; - } - - if (handle->flags & UV_HANDLE_PIPESERVER) { - for (i = 0; i < handle->pending_instances; i++) { - pipeHandle = handle->accept_reqs[i].pipeHandle; - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); - handle->accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE; - } - } - } - - if (handle->flags & UV_HANDLE_CONNECTION) { - handle->flags &= ~UV_HANDLE_WRITABLE; - eof_timer_destroy(handle); - } - - if ((handle->flags & UV_HANDLE_CONNECTION) - && handle->handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->handle); - handle->handle = INVALID_HANDLE_VALUE; - } -} - - -void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) { - if (handle->flags & UV_HANDLE_READING) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - } - - if (handle->flags & UV_HANDLE_LISTENING) { - handle->flags &= ~UV_HANDLE_LISTENING; - DECREASE_ACTIVE_COUNT(loop, handle); - } - - uv_pipe_cleanup(loop, handle); - - if (handle->reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - - handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); - uv__handle_closing(handle); -} - - -static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle, - uv_pipe_accept_t* req, BOOL firstInstance) { - assert(handle->flags & UV_HANDLE_LISTENING); - - if (!firstInstance) { - assert(req->pipeHandle == INVALID_HANDLE_VALUE); - - req->pipeHandle = CreateNamedPipeW(handle->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); - - if (req->pipeHandle == INVALID_HANDLE_VALUE) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - - if (uv_set_pipe_handle(loop, handle, req->pipeHandle, 0)) { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - } - - assert(req->pipeHandle != INVALID_HANDLE_VALUE); - - /* Prepare the overlapped structure. */ - memset(&(req->overlapped), 0, sizeof(req->overlapped)); - - if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) && - GetLastError() != ERROR_IO_PENDING) { - if (GetLastError() == ERROR_PIPE_CONNECTED) { - SET_REQ_SUCCESS(req); - } else { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - } - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - - handle->reqs_pending++; -} - - -int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) { - uv_loop_t* loop = server->loop; - uv_pipe_t* pipe_client; - uv_pipe_accept_t* req; - - if (server->ipc) { - if (!server->pending_ipc_info.socket_info) { - /* No valid pending sockets. */ - return WSAEWOULDBLOCK; - } - - return uv_tcp_import((uv_tcp_t*)client, server->pending_ipc_info.socket_info, - server->pending_ipc_info.tcp_connection); - } else { - pipe_client = (uv_pipe_t*)client; - - /* Find a connection instance that has been connected, but not yet */ - /* accepted. */ - req = server->pending_accepts; - - if (!req) { - /* No valid connections found, so we error out. */ - return WSAEWOULDBLOCK; - } - - /* Initialize the client handle and copy the pipeHandle to the client */ - uv_pipe_connection_init(pipe_client); - pipe_client->handle = req->pipeHandle; - pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - - /* Prepare the req to pick up a new connection */ - server->pending_accepts = req->next_pending; - req->next_pending = NULL; - req->pipeHandle = INVALID_HANDLE_VALUE; - - if (!(server->flags & UV__HANDLE_CLOSING)) { - uv_pipe_queue_accept(loop, server, req, FALSE); - } - } - - return 0; -} - - -/* Starts listening for connections for the given pipe. */ -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { - uv_loop_t* loop = handle->loop; - int i; - - if (handle->flags & UV_HANDLE_LISTENING) { - handle->connection_cb = cb; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - return WSAEINVAL; - } - - if (handle->flags & UV_HANDLE_READING) { - return WSAEISCONN; - } - - if (!(handle->flags & UV_HANDLE_PIPESERVER)) { - return ERROR_NOT_SUPPORTED; - } - - handle->flags |= UV_HANDLE_LISTENING; - INCREASE_ACTIVE_COUNT(loop, handle); - handle->connection_cb = cb; - - /* First pipe handle should have already been created in uv_pipe_bind */ - assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE); - - for (i = 0; i < handle->pending_instances; i++) { - uv_pipe_queue_accept(loop, handle, &handle->accept_reqs[i], i == 0); - } - - return 0; -} - - -static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) { - int result; - DWORD bytes; - uv_read_t* req = (uv_read_t*) parameter; - uv_pipe_t* handle = (uv_pipe_t*) req->data; - uv_loop_t* loop = handle->loop; - - assert(req != NULL); - assert(req->type == UV_READ); - assert(handle->type == UV_NAMED_PIPE); - - result = ReadFile(handle->handle, - &uv_zero_, - 0, - &bytes, - NULL); - - if (!result) { - SET_REQ_ERROR(req, GetLastError()); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -static DWORD WINAPI uv_pipe_writefile_thread_proc(void* parameter) { - int result; - DWORD bytes; - uv_write_t* req = (uv_write_t*) parameter; - uv_pipe_t* handle = (uv_pipe_t*) req->handle; - uv_loop_t* loop = handle->loop; - - assert(req != NULL); - assert(req->type == UV_WRITE); - assert(handle->type == UV_NAMED_PIPE); - assert(req->write_buffer.base); - - result = WriteFile(handle->handle, - req->write_buffer.base, - req->write_buffer.len, - &bytes, - NULL); - - if (!result) { - SET_REQ_ERROR(req, GetLastError()); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -static void CALLBACK post_completion_read_wait(void* context, BOOLEAN timed_out) { - uv_read_t* req; - uv_tcp_t* handle; - - req = (uv_read_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->data; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->overlapped.InternalHigh, - 0, - &req->overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void CALLBACK post_completion_write_wait(void* context, BOOLEAN timed_out) { - uv_write_t* req; - uv_tcp_t* handle; - - req = (uv_write_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->handle; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->overlapped.InternalHigh, - 0, - &req->overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) { - uv_read_t* req; - int result; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - assert(handle->handle != INVALID_HANDLE_VALUE); - - req = &handle->read_req; - - if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { - if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc, - req, - WT_EXECUTELONGFUNCTION)) { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - goto error; - } - } else { - memset(&req->overlapped, 0, sizeof(req->overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); - } - - /* Do 0-read */ - result = ReadFile(handle->handle, - &uv_zero_, - 0, - NULL, - &req->overlapped); - - if (!result && GetLastError() != ERROR_IO_PENDING) { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - goto error; - } - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (!req->event_handle) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } - if (req->wait_handle == INVALID_HANDLE_VALUE) { - if (!RegisterWaitForSingleObject(&req->wait_handle, - req->overlapped.hEvent, post_completion_read_wait, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - SET_REQ_ERROR(req, GetLastError()); - goto error; - } - } - } - } - - /* Start the eof timer if there is one */ - eof_timer_start(handle); - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - return; - -error: - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; -} - - -static int uv_pipe_read_start_impl(uv_pipe_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb, uv_read2_cb read2_cb) { - uv_loop_t* loop = handle->loop; - - handle->flags |= UV_HANDLE_READING; - INCREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb = read_cb; - handle->read2_cb = read2_cb; - handle->alloc_cb = alloc_cb; - - /* If reading was stopped and then started again, there could still be a */ - /* read request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) - uv_pipe_queue_read(loop, handle); - - return 0; -} - - -int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - return uv_pipe_read_start_impl(handle, alloc_cb, read_cb, NULL); -} - - -int uv_pipe_read2_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, - uv_read2_cb read_cb) { - return uv_pipe_read_start_impl(handle, alloc_cb, NULL, read_cb); -} - - -static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle, - uv_write_t* req) { - req->next_req = NULL; - if (handle->non_overlapped_writes_tail) { - req->next_req = - handle->non_overlapped_writes_tail->next_req; - handle->non_overlapped_writes_tail->next_req = (uv_req_t*)req; - handle->non_overlapped_writes_tail = req; - } else { - req->next_req = (uv_req_t*)req; - handle->non_overlapped_writes_tail = req; - } -} - - -static uv_write_t* uv_remove_non_overlapped_write_req(uv_pipe_t* handle) { - uv_write_t* req; - - if (handle->non_overlapped_writes_tail) { - req = (uv_write_t*)handle->non_overlapped_writes_tail->next_req; - - if (req == handle->non_overlapped_writes_tail) { - handle->non_overlapped_writes_tail = NULL; - } else { - handle->non_overlapped_writes_tail->next_req = - req->next_req; - } - - return req; - } else { - /* queue empty */ - return NULL; - } -} - - -static void uv_queue_non_overlapped_write(uv_pipe_t* handle) { - uv_write_t* req = uv_remove_non_overlapped_write_req(handle); - if (req) { - if (!QueueUserWorkItem(&uv_pipe_writefile_thread_proc, - req, - WT_EXECUTELONGFUNCTION)) { - uv_fatal_error(GetLastError(), "QueueUserWorkItem"); - } - } -} - - -static int uv_pipe_write_impl(uv_loop_t* loop, - uv_write_t* req, - uv_pipe_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - int err; - int result; - uv_tcp_t* tcp_send_handle; - uv_write_t* ipc_header_req; - uv_ipc_frame_uv_stream ipc_frame; - - if (nbufs != 1 && (nbufs != 0 || !send_handle)) { - return ERROR_NOT_SUPPORTED; - } - - /* Only TCP handles are supported for sharing. */ - if (send_handle && ((send_handle->type != UV_TCP) || - (!(send_handle->flags & UV_HANDLE_BOUND) && - !(send_handle->flags & UV_HANDLE_CONNECTION)))) { - return ERROR_NOT_SUPPORTED; - } - - assert(handle->handle != INVALID_HANDLE_VALUE); - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - req->ipc_header = 0; - req->event_handle = NULL; - req->wait_handle = INVALID_HANDLE_VALUE; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - - if (handle->ipc) { - assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); - ipc_frame.header.flags = 0; - - /* Use the IPC framing protocol. */ - if (send_handle) { - tcp_send_handle = (uv_tcp_t*)send_handle; - - err = uv_tcp_duplicate_socket(tcp_send_handle, handle->ipc_pid, - &ipc_frame.socket_info); - if (err) { - return err; - } - ipc_frame.header.flags |= UV_IPC_TCP_SERVER; - - if (tcp_send_handle->flags & UV_HANDLE_CONNECTION) { - ipc_frame.header.flags |= UV_IPC_TCP_CONNECTION; - } - } - - if (nbufs == 1) { - ipc_frame.header.flags |= UV_IPC_RAW_DATA; - ipc_frame.header.raw_data_length = bufs[0].len; - } - - /* - * Use the provided req if we're only doing a single write. - * If we're doing multiple writes, use ipc_header_write_req to do - * the first write, and then use the provided req for the second write. - */ - if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) { - ipc_header_req = req; - } else { - /* - * Try to use the preallocated write req if it's available. - * Otherwise allocate a new one. - */ - if (handle->ipc_header_write_req.type != UV_WRITE) { - ipc_header_req = (uv_write_t*)&handle->ipc_header_write_req; - } else { - ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t)); - if (!ipc_header_req) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - } - - uv_req_init(loop, (uv_req_t*) ipc_header_req); - ipc_header_req->type = UV_WRITE; - ipc_header_req->handle = (uv_stream_t*) handle; - ipc_header_req->cb = NULL; - ipc_header_req->ipc_header = 1; - } - - /* Write the header or the whole frame. */ - memset(&ipc_header_req->overlapped, 0, sizeof(ipc_header_req->overlapped)); - - /* Using overlapped IO, but wait for completion before returning. - This write is blocking because ipc_frame is on stack. */ - ipc_header_req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL); - if (!ipc_header_req->overlapped.hEvent) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - result = WriteFile(handle->handle, - &ipc_frame, - ipc_frame.header.flags & UV_IPC_TCP_SERVER ? - sizeof(ipc_frame) : sizeof(ipc_frame.header), - NULL, - &ipc_header_req->overlapped); - if (!result && GetLastError() != ERROR_IO_PENDING) { - err = GetLastError(); - CloseHandle(ipc_header_req->overlapped.hEvent); - return err; - } - - if (!result) { - /* Request not completed immediately. Wait for it.*/ - if (WaitForSingleObject(ipc_header_req->overlapped.hEvent, INFINITE) != - WAIT_OBJECT_0) { - err = GetLastError(); - CloseHandle(ipc_header_req->overlapped.hEvent); - return err; - } - } - ipc_header_req->queued_bytes = 0; - CloseHandle(ipc_header_req->overlapped.hEvent); - ipc_header_req->overlapped.hEvent = NULL; - - REGISTER_HANDLE_REQ(loop, handle, ipc_header_req); - handle->reqs_pending++; - handle->write_reqs_pending++; - - /* If we don't have any raw data to write - we're done. */ - if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) { - return 0; - } - } - - if ((handle->flags & - (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) == - (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) { - DWORD bytes; - result = WriteFile(handle->handle, - bufs[0].base, - bufs[0].len, - &bytes, - NULL); - - if (!result) { - return err; - } else { - /* Request completed immediately. */ - req->queued_bytes = 0; - } - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - handle->write_reqs_pending++; - POST_COMPLETION_FOR_REQ(loop, req); - return 0; - } else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { - req->write_buffer = bufs[0]; - uv_insert_non_overlapped_write_req(handle, req); - if (handle->write_reqs_pending == 0) { - uv_queue_non_overlapped_write(handle); - } - - /* Request queued by the kernel. */ - req->queued_bytes = uv_count_bufs(bufs, nbufs); - handle->write_queue_size += req->queued_bytes; - } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) { - /* Using overlapped IO, but wait for completion before returning */ - req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL); - if (!req->overlapped.hEvent) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - result = WriteFile(handle->handle, - bufs[0].base, - bufs[0].len, - NULL, - &req->overlapped); - - if (!result && GetLastError() != ERROR_IO_PENDING) { - err = GetLastError(); - CloseHandle(req->overlapped.hEvent); - return err; - } - - if (result) { - /* Request completed immediately. */ - req->queued_bytes = 0; - } else { - /* Request queued by the kernel. */ - if (WaitForSingleObject(ipc_header_req->overlapped.hEvent, INFINITE) != - WAIT_OBJECT_0) { - err = GetLastError(); - CloseHandle(ipc_header_req->overlapped.hEvent); - return uv_translate_sys_error(err); - } - } - CloseHandle(req->overlapped.hEvent); - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - handle->write_reqs_pending++; - POST_COMPLETION_FOR_REQ(loop, req); - return 0; - } else { - result = WriteFile(handle->handle, - bufs[0].base, - bufs[0].len, - NULL, - &req->overlapped); - - if (!result && GetLastError() != ERROR_IO_PENDING) { - return GetLastError(); - } - - if (result) { - /* Request completed immediately. */ - req->queued_bytes = 0; - } else { - /* Request queued by the kernel. */ - req->queued_bytes = uv_count_bufs(bufs, nbufs); - handle->write_queue_size += req->queued_bytes; - } - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - if (!RegisterWaitForSingleObject(&req->wait_handle, - req->overlapped.hEvent, post_completion_write_wait, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - return GetLastError(); - } - } - } - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - handle->write_reqs_pending++; - - return 0; -} - - -int uv_pipe_write(uv_loop_t* loop, - uv_write_t* req, - uv_pipe_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, NULL, cb); -} - - -int uv_pipe_write2(uv_loop_t* loop, - uv_write_t* req, - uv_pipe_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - if (!handle->ipc) { - return WSAEINVAL; - } - - return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, send_handle, cb); -} - - -static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle, - uv_buf_t buf) { - /* If there is an eof timer running, we don't need it any more, */ - /* so discard it. */ - eof_timer_destroy(handle); - - handle->flags &= ~UV_HANDLE_READABLE; - uv_read_stop((uv_stream_t*) handle); - - if (handle->read2_cb) { - handle->read2_cb(handle, UV_EOF, &uv_null_buf_, UV_UNKNOWN_HANDLE); - } else { - handle->read_cb((uv_stream_t*) handle, UV_EOF, &uv_null_buf_); - } -} - - -static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error, - uv_buf_t buf) { - /* If there is an eof timer running, we don't need it any more, */ - /* so discard it. */ - eof_timer_destroy(handle); - - uv_read_stop((uv_stream_t*) handle); - - if (handle->read2_cb) { - handle->read2_cb(handle, - uv_translate_sys_error(error), - &buf, - UV_UNKNOWN_HANDLE); - } else { - handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(error), &buf); - } -} - - -static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle, - int error, uv_buf_t buf) { - if (error == ERROR_BROKEN_PIPE) { - uv_pipe_read_eof(loop, handle, buf); - } else { - uv_pipe_read_error(loop, handle, error, buf); - } -} - - -void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* req) { - DWORD bytes, avail; - uv_buf_t buf; - uv_ipc_frame_uv_stream ipc_frame; - - assert(handle->type == UV_NAMED_PIPE); - - handle->flags &= ~UV_HANDLE_READ_PENDING; - eof_timer_stop(handle); - - if (!REQ_SUCCESS(req)) { - /* An error occurred doing the 0-read. */ - if (handle->flags & UV_HANDLE_READING) { - uv_pipe_read_error_or_eof(loop, - handle, - GET_REQ_ERROR(req), - uv_null_buf_); - } - } else { - /* Do non-blocking reads until the buffer is empty */ - while (handle->flags & UV_HANDLE_READING) { - if (!PeekNamedPipe(handle->handle, - NULL, - 0, - NULL, - &avail, - NULL)) { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); - break; - } - - if (avail == 0) { - /* There is nothing to read after all. */ - break; - } - - if (handle->ipc) { - /* Use the IPC framing protocol to read the incoming data. */ - if (handle->remaining_ipc_rawdata_bytes == 0) { - /* We're reading a new frame. First, read the header. */ - assert(avail >= sizeof(ipc_frame.header)); - - if (!ReadFile(handle->handle, - &ipc_frame.header, - sizeof(ipc_frame.header), - &bytes, - NULL)) { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), - uv_null_buf_); - break; - } - - assert(bytes == sizeof(ipc_frame.header)); - assert(ipc_frame.header.flags <= (UV_IPC_TCP_SERVER | UV_IPC_RAW_DATA | - UV_IPC_TCP_CONNECTION)); - - if (ipc_frame.header.flags & UV_IPC_TCP_SERVER) { - assert(avail - sizeof(ipc_frame.header) >= - sizeof(ipc_frame.socket_info)); - - /* Read the TCP socket info. */ - if (!ReadFile(handle->handle, - &ipc_frame.socket_info, - sizeof(ipc_frame) - sizeof(ipc_frame.header), - &bytes, - NULL)) { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), - uv_null_buf_); - break; - } - - assert(bytes == sizeof(ipc_frame) - sizeof(ipc_frame.header)); - - /* Store the pending socket info. */ - assert(!handle->pending_ipc_info.socket_info); - handle->pending_ipc_info.socket_info = - (WSAPROTOCOL_INFOW*)malloc(sizeof(*(handle->pending_ipc_info.socket_info))); - if (!handle->pending_ipc_info.socket_info) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - *(handle->pending_ipc_info.socket_info) = ipc_frame.socket_info; - handle->pending_ipc_info.tcp_connection = - ipc_frame.header.flags & UV_IPC_TCP_CONNECTION; - } - - if (ipc_frame.header.flags & UV_IPC_RAW_DATA) { - handle->remaining_ipc_rawdata_bytes = - ipc_frame.header.raw_data_length; - continue; - } - } else { - avail = min(avail, (DWORD)handle->remaining_ipc_rawdata_bytes); - } - } - - handle->alloc_cb((uv_handle_t*) handle, avail, &buf); - if (buf.len == 0) { - if (handle->read2_cb) { - handle->read2_cb(handle, UV_ENOBUFS, &buf, UV_UNKNOWN_HANDLE); - } else if (handle->read_cb) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); - } - break; - } - assert(buf.base != NULL); - - if (ReadFile(handle->handle, - buf.base, - buf.len, - &bytes, - NULL)) { - /* Successful read */ - if (handle->ipc) { - assert(handle->remaining_ipc_rawdata_bytes >= bytes); - handle->remaining_ipc_rawdata_bytes = - handle->remaining_ipc_rawdata_bytes - bytes; - if (handle->read2_cb) { - handle->read2_cb(handle, bytes, &buf, - handle->pending_ipc_info.socket_info ? UV_TCP : UV_UNKNOWN_HANDLE); - } else if (handle->read_cb) { - handle->read_cb((uv_stream_t*)handle, bytes, &buf); - } - - if (handle->pending_ipc_info.socket_info) { - free(handle->pending_ipc_info.socket_info); - handle->pending_ipc_info.socket_info = NULL; - } - } else { - handle->read_cb((uv_stream_t*)handle, bytes, &buf); - } - - /* Read again only if bytes == buf.len */ - if (bytes <= buf.len) { - break; - } - } else { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); - break; - } - } - - /* Post another 0-read if still reading and not closing. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_pipe_queue_read(loop, handle); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_write_t* req) { - int err; - - assert(handle->type == UV_NAMED_PIPE); - - assert(handle->write_queue_size >= req->queued_bytes); - handle->write_queue_size -= req->queued_bytes; - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - req->wait_handle = INVALID_HANDLE_VALUE; - } - if (req->event_handle) { - CloseHandle(req->event_handle); - req->event_handle = NULL; - } - } - - if (req->ipc_header) { - if (req == &handle->ipc_header_write_req) { - req->type = UV_UNKNOWN_REQ; - } else { - free(req); - } - } else { - if (req->cb) { - err = GET_REQ_ERROR(req); - req->cb(req, uv_translate_sys_error(err)); - } - } - - handle->write_reqs_pending--; - - if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE && - handle->non_overlapped_writes_tail) { - assert(handle->write_reqs_pending > 0); - uv_queue_non_overlapped_write(handle); - } - - if (handle->shutdown_req != NULL && - handle->write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* raw_req) { - uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req; - - assert(handle->type == UV_NAMED_PIPE); - - if (handle->flags & UV__HANDLE_CLOSING) { - /* The req->pipeHandle should be freed already in uv_pipe_cleanup(). */ - assert(req->pipeHandle == INVALID_HANDLE_VALUE); - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (REQ_SUCCESS(req)) { - assert(req->pipeHandle != INVALID_HANDLE_VALUE); - req->next_pending = handle->pending_accepts; - handle->pending_accepts = req; - - if (handle->connection_cb) { - handle->connection_cb((uv_stream_t*)handle, 0); - } - } else { - if (req->pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - } - if (!(handle->flags & UV__HANDLE_CLOSING)) { - uv_pipe_queue_accept(loop, handle, req, FALSE); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_connect_t* req) { - int err; - - assert(handle->type == UV_NAMED_PIPE); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (req->cb) { - err = 0; - if (REQ_SUCCESS(req)) { - uv_pipe_connection_init(handle); - } else { - err = GET_REQ_ERROR(req); - } - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_shutdown_t* req) { - assert(handle->type == UV_NAMED_PIPE); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (handle->flags & UV_HANDLE_READABLE) { - /* Initialize and optionally start the eof timer. Only do this if the */ - /* pipe is readable and we haven't seen EOF come in ourselves. */ - eof_timer_init(handle); - - /* If reading start the timer right now. */ - /* Otherwise uv_pipe_queue_read will start it. */ - if (handle->flags & UV_HANDLE_READ_PENDING) { - eof_timer_start(handle); - } - - } else { - /* This pipe is not readable. We can just close it to let the other end */ - /* know that we're done writing. */ - CloseHandle(handle->handle); - handle->handle = INVALID_HANDLE_VALUE; - } - - if (req->cb) { - req->cb(req, 0); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -static void eof_timer_init(uv_pipe_t* pipe) { - int r; - - assert(pipe->eof_timer == NULL); - assert(pipe->flags & UV_HANDLE_CONNECTION); - - pipe->eof_timer = (uv_timer_t*) malloc(sizeof *pipe->eof_timer); - - r = uv_timer_init(pipe->loop, pipe->eof_timer); - assert(r == 0); /* timers can't fail */ - pipe->eof_timer->data = pipe; - uv_unref((uv_handle_t*) pipe->eof_timer); -} - - -static void eof_timer_start(uv_pipe_t* pipe) { - assert(pipe->flags & UV_HANDLE_CONNECTION); - - if (pipe->eof_timer != NULL) { - uv_timer_start(pipe->eof_timer, eof_timer_cb, eof_timeout, 0); - } -} - - -static void eof_timer_stop(uv_pipe_t* pipe) { - assert(pipe->flags & UV_HANDLE_CONNECTION); - - if (pipe->eof_timer != NULL) { - uv_timer_stop(pipe->eof_timer); - } -} - - -static void eof_timer_cb(uv_timer_t* timer, int status) { - uv_pipe_t* pipe = (uv_pipe_t*) timer->data; - uv_loop_t* loop = timer->loop; - - assert(status == 0); /* timers can't fail */ - assert(pipe->type == UV_NAMED_PIPE); - - /* This should always be true, since we start the timer only */ - /* in uv_pipe_queue_read after successfully calling ReadFile, */ - /* or in uv_process_pipe_shutdown_req if a read is pending, */ - /* and we always immediately stop the timer in */ - /* uv_process_pipe_read_req. */ - assert(pipe->flags & UV_HANDLE_READ_PENDING); - - /* If there are many packets coming off the iocp then the timer callback */ - /* may be called before the read request is coming off the queue. */ - /* Therefore we check here if the read request has completed but will */ - /* be processed later. */ - if ((pipe->flags & UV_HANDLE_READ_PENDING) && - HasOverlappedIoCompleted(&pipe->read_req.overlapped)) { - return; - } - - /* Force both ends off the pipe. */ - CloseHandle(pipe->handle); - pipe->handle = INVALID_HANDLE_VALUE; - - /* Stop reading, so the pending read that is going to fail will */ - /* not be reported to the user. */ - uv_read_stop((uv_stream_t*) pipe); - - /* Report the eof and update flags. This will get reported even if the */ - /* user stopped reading in the meantime. TODO: is that okay? */ - uv_pipe_read_eof(loop, pipe, uv_null_buf_); -} - - -static void eof_timer_destroy(uv_pipe_t* pipe) { - assert(pipe->flags && UV_HANDLE_CONNECTION); - - if (pipe->eof_timer) { - uv_close((uv_handle_t*) pipe->eof_timer, eof_timer_close_cb); - pipe->eof_timer = NULL; - } -} - - -static void eof_timer_close_cb(uv_handle_t* handle) { - assert(handle->type == UV_TIMER); - free(handle); -} - - -int uv_pipe_open(uv_pipe_t* pipe, uv_file file) { - HANDLE os_handle = uv__get_osfhandle(file); - - if (os_handle == INVALID_HANDLE_VALUE || - uv_set_pipe_handle(pipe->loop, pipe, os_handle, 0) == -1) { - return UV_EINVAL; - } - - uv_pipe_connection_init(pipe); - pipe->handle = os_handle; - pipe->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - - if (pipe->ipc) { - assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); - pipe->ipc_pid = uv_parent_pid(); - assert(pipe->ipc_pid != -1); - } - return 0; -} diff --git a/third-party/libuv/src/win/poll.c b/third-party/libuv/src/win/poll.c deleted file mode 100644 index 75351afd75..0000000000 --- a/third-party/libuv/src/win/poll.c +++ /dev/null @@ -1,617 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <io.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -static const GUID uv_msafd_provider_ids[UV_MSAFD_PROVIDER_COUNT] = { - {0xe70f1aa0, 0xab8b, 0x11cf, - {0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}, - {0xf9eab0c0, 0x26d4, 0x11d0, - {0xbb, 0xbf, 0x00, 0xaa, 0x00, 0x6c, 0x34, 0xe4}}, - {0x9fc48064, 0x7298, 0x43e4, - {0xb7, 0xbd, 0x18, 0x1f, 0x20, 0x89, 0x79, 0x2a}} -}; - -typedef struct uv_single_fd_set_s { - unsigned int fd_count; - SOCKET fd_array[1]; -} uv_single_fd_set_t; - - -static OVERLAPPED overlapped_dummy_; -static uv_once_t overlapped_dummy_init_guard_ = UV_ONCE_INIT; - - -static void uv__init_overlapped_dummy(void) { - HANDLE event; - - event = CreateEvent(NULL, TRUE, TRUE, NULL); - if (event == NULL) - uv_fatal_error(GetLastError(), "CreateEvent"); - - memset(&overlapped_dummy_, 0, sizeof overlapped_dummy_); - overlapped_dummy_.hEvent = (HANDLE) ((uintptr_t) event | 1); -} - - -static OVERLAPPED* uv__get_overlapped_dummy() { - uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy); - return &overlapped_dummy_; -} - - -static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { - uv_req_t* req; - AFD_POLL_INFO* afd_poll_info; - DWORD result; - - /* Find a yet unsubmitted req to submit. */ - if (handle->submitted_events_1 == 0) { - req = &handle->poll_req_1; - afd_poll_info = &handle->afd_poll_info_1; - handle->submitted_events_1 = handle->events; - handle->mask_events_1 = 0; - handle->mask_events_2 = handle->events; - } else if (handle->submitted_events_2 == 0) { - req = &handle->poll_req_2; - afd_poll_info = &handle->afd_poll_info_2; - handle->submitted_events_2 = handle->events; - handle->mask_events_1 = handle->events; - handle->mask_events_2 = 0; - } else { - assert(0); - } - - /* Setting Exclusive to TRUE makes the other poll request return if there */ - /* is any. */ - afd_poll_info->Exclusive = TRUE; - afd_poll_info->NumberOfHandles = 1; - afd_poll_info->Timeout.QuadPart = INT64_MAX; - afd_poll_info->Handles[0].Handle = (HANDLE) handle->socket; - afd_poll_info->Handles[0].Status = 0; - afd_poll_info->Handles[0].Events = 0; - - if (handle->events & UV_READABLE) { - afd_poll_info->Handles[0].Events |= AFD_POLL_RECEIVE | - AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT; - } - if (handle->events & UV_WRITABLE) { - afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL; - } - - memset(&req->overlapped, 0, sizeof req->overlapped); - - result = uv_msafd_poll((SOCKET) handle->peer_socket, - afd_poll_info, - &req->overlapped); - if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) { - /* Queue this req, reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, req); - } -} - - -static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) { - AFD_POLL_INFO afd_poll_info; - DWORD result; - - afd_poll_info.Exclusive = TRUE; - afd_poll_info.NumberOfHandles = 1; - afd_poll_info.Timeout.QuadPart = INT64_MAX; - afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket; - afd_poll_info.Handles[0].Status = 0; - afd_poll_info.Handles[0].Events = AFD_POLL_ALL; - - result = uv_msafd_poll(handle->socket, - &afd_poll_info, - uv__get_overlapped_dummy()); - - if (result == SOCKET_ERROR) { - DWORD error = WSAGetLastError(); - if (error != WSA_IO_PENDING) { - return WSAGetLastError(); - } - } - - return 0; -} - - -static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, - uv_req_t* req) { - unsigned char mask_events; - AFD_POLL_INFO* afd_poll_info; - - if (req == &handle->poll_req_1) { - afd_poll_info = &handle->afd_poll_info_1; - handle->submitted_events_1 = 0; - mask_events = handle->mask_events_1; - } else if (req == &handle->poll_req_2) { - afd_poll_info = &handle->afd_poll_info_2; - handle->submitted_events_2 = 0; - mask_events = handle->mask_events_2; - } else { - assert(0); - } - - /* Report an error unless the select was just interrupted. */ - if (!REQ_SUCCESS(req)) { - DWORD error = GET_REQ_SOCK_ERROR(req); - if (error != WSAEINTR && handle->events != 0) { - handle->events = 0; /* Stop the watcher */ - handle->poll_cb(handle, uv_translate_sys_error(error), 0); - } - - } else if (afd_poll_info->NumberOfHandles >= 1) { - unsigned char events = 0; - - if ((afd_poll_info->Handles[0].Events & (AFD_POLL_RECEIVE | - AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT)) != 0) { - events |= UV_READABLE; - } - if ((afd_poll_info->Handles[0].Events & (AFD_POLL_SEND | - AFD_POLL_CONNECT_FAIL)) != 0) { - events |= UV_WRITABLE; - } - - events &= handle->events & ~mask_events; - - if (afd_poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) { - /* Stop polling. */ - handle->events = 0; - uv__handle_stop(handle); - } - - if (events != 0) { - handle->poll_cb(handle, 0, events); - } - } - - if ((handle->events & ~(handle->submitted_events_1 | - handle->submitted_events_2)) != 0) { - uv__fast_poll_submit_poll_req(loop, handle); - } else if ((handle->flags & UV__HANDLE_CLOSING) && - handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) { - assert(handle->type == UV_POLL); - assert(!(handle->flags & UV__HANDLE_CLOSING)); - assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0); - - handle->events = events; - - if (handle->events != 0) { - uv__handle_start(handle); - } else { - uv__handle_stop(handle); - } - - if ((handle->events & ~(handle->submitted_events_1 | - handle->submitted_events_2)) != 0) { - uv__fast_poll_submit_poll_req(handle->loop, handle); - } - - return 0; -} - - -static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) { - handle->events = 0; - uv__handle_closing(handle); - - if (handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - return 0; - } else { - /* Cancel outstanding poll requests by executing another, unique poll */ - /* request that forces the outstanding ones to return. */ - return uv__fast_poll_cancel_poll_req(loop, handle); - } -} - - -static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp, - WSAPROTOCOL_INFOW* protocol_info) { - SOCKET sock = 0; - - sock = WSASocketW(protocol_info->iAddressFamily, - protocol_info->iSocketType, - protocol_info->iProtocol, - protocol_info, - 0, - WSA_FLAG_OVERLAPPED); - if (sock == INVALID_SOCKET) { - return INVALID_SOCKET; - } - - if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) { - goto error; - }; - - if (CreateIoCompletionPort((HANDLE) sock, - iocp, - (ULONG_PTR) sock, - 0) == NULL) { - goto error; - } - - return sock; - - error: - closesocket(sock); - return INVALID_SOCKET; -} - - -static SOCKET uv__fast_poll_get_peer_socket(uv_loop_t* loop, - WSAPROTOCOL_INFOW* protocol_info) { - int index, i; - SOCKET peer_socket; - - index = -1; - for (i = 0; i < ARRAY_SIZE(uv_msafd_provider_ids); i++) { - if (memcmp((void*) &protocol_info->ProviderId, - (void*) &uv_msafd_provider_ids[i], - sizeof protocol_info->ProviderId) == 0) { - index = i; - } - } - - /* Check if the protocol uses an msafd socket. */ - if (index < 0) { - return INVALID_SOCKET; - } - - /* If we didn't (try) to create a peer socket yet, try to make one. Don't */ - /* try again if the peer socket creation failed earlier for the same */ - /* protocol. */ - peer_socket = loop->poll_peer_sockets[index]; - if (peer_socket == 0) { - peer_socket = uv__fast_poll_create_peer_socket(loop->iocp, protocol_info); - loop->poll_peer_sockets[index] = peer_socket; - } - - return peer_socket; -} - - -static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) { - uv_req_t* req = (uv_req_t*) arg; - uv_poll_t* handle = (uv_poll_t*) req->data; - unsigned char reported_events; - int r; - uv_single_fd_set_t rfds, wfds, efds; - struct timeval timeout; - - assert(handle->type == UV_POLL); - assert(req->type == UV_POLL_REQ); - - if (handle->events & UV_READABLE) { - rfds.fd_count = 1; - rfds.fd_array[0] = handle->socket; - } else { - rfds.fd_count = 0; - } - - if (handle->events & UV_WRITABLE) { - wfds.fd_count = 1; - wfds.fd_array[0] = handle->socket; - efds.fd_count = 1; - efds.fd_array[0] = handle->socket; - } else { - wfds.fd_count = 0; - efds.fd_count = 0; - } - - /* Make the select() time out after 3 minutes. If select() hangs because */ - /* the user closed the socket, we will at least not hang indefinitely. */ - timeout.tv_sec = 3 * 60; - timeout.tv_usec = 0; - - r = select(1, (fd_set*) &rfds, (fd_set*) &wfds, (fd_set*) &efds, &timeout); - if (r == SOCKET_ERROR) { - /* Queue this req, reporting an error. */ - SET_REQ_ERROR(&handle->poll_req_1, WSAGetLastError()); - POST_COMPLETION_FOR_REQ(handle->loop, req); - return 0; - } - - reported_events = 0; - - if (r > 0) { - if (rfds.fd_count > 0) { - assert(rfds.fd_count == 1); - assert(rfds.fd_array[0] == handle->socket); - reported_events |= UV_READABLE; - } - - if (wfds.fd_count > 0) { - assert(wfds.fd_count == 1); - assert(wfds.fd_array[0] == handle->socket); - reported_events |= UV_WRITABLE; - } else if (efds.fd_count > 0) { - assert(efds.fd_count == 1); - assert(efds.fd_array[0] == handle->socket); - reported_events |= UV_WRITABLE; - } - } - - SET_REQ_SUCCESS(req); - req->overlapped.InternalHigh = (DWORD) reported_events; - POST_COMPLETION_FOR_REQ(handle->loop, req); - - return 0; -} - - -static void uv__slow_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { - uv_req_t* req; - - /* Find a yet unsubmitted req to submit. */ - if (handle->submitted_events_1 == 0) { - req = &handle->poll_req_1; - handle->submitted_events_1 = handle->events; - handle->mask_events_1 = 0; - handle->mask_events_2 = handle->events; - } else if (handle->submitted_events_2 == 0) { - req = &handle->poll_req_2; - handle->submitted_events_2 = handle->events; - handle->mask_events_1 = handle->events; - handle->mask_events_2 = 0; - } else { - assert(0); - } - - if (!QueueUserWorkItem(uv__slow_poll_thread_proc, - (void*) req, - WT_EXECUTELONGFUNCTION)) { - /* Make this req pending, reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, req); - } -} - - - -static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, - uv_req_t* req) { - unsigned char mask_events; - int err; - - if (req == &handle->poll_req_1) { - handle->submitted_events_1 = 0; - mask_events = handle->mask_events_1; - } else if (req == &handle->poll_req_2) { - handle->submitted_events_2 = 0; - mask_events = handle->mask_events_2; - } else { - assert(0); - } - - if (!REQ_SUCCESS(req)) { - /* Error. */ - if (handle->events != 0) { - err = GET_REQ_ERROR(req); - handle->events = 0; /* Stop the watcher */ - handle->poll_cb(handle, uv_translate_sys_error(err), 0); - } - } else { - /* Got some events. */ - int events = req->overlapped.InternalHigh & handle->events & ~mask_events; - if (events != 0) { - handle->poll_cb(handle, 0, events); - } - } - - if ((handle->events & ~(handle->submitted_events_1 | - handle->submitted_events_2)) != 0) { - uv__slow_poll_submit_poll_req(loop, handle); - } else if ((handle->flags & UV__HANDLE_CLOSING) && - handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) { - assert(handle->type == UV_POLL); - assert(!(handle->flags & UV__HANDLE_CLOSING)); - assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0); - - handle->events = events; - - if (handle->events != 0) { - uv__handle_start(handle); - } else { - uv__handle_stop(handle); - } - - if ((handle->events & - ~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) { - uv__slow_poll_submit_poll_req(handle->loop, handle); - } - - return 0; -} - - -static int uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) { - handle->events = 0; - uv__handle_closing(handle); - - if (handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - - return 0; -} - - -int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { - return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd)); -} - - -int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, - uv_os_sock_t socket) { - WSAPROTOCOL_INFOW protocol_info; - int len; - SOCKET peer_socket, base_socket; - DWORD bytes; - - /* Try to obtain a base handle for the socket. This increases this chances */ - /* that we find an AFD handle and are able to use the fast poll mechanism. */ - /* This will always fail on windows XP/2k3, since they don't support the */ - /* SIO_BASE_HANDLE ioctl. */ -#ifndef NDEBUG - base_socket = INVALID_SOCKET; -#endif - - if (WSAIoctl(socket, - SIO_BASE_HANDLE, - NULL, - 0, - &base_socket, - sizeof base_socket, - &bytes, - NULL, - NULL) == 0) { - assert(base_socket != 0 && base_socket != INVALID_SOCKET); - socket = base_socket; - } - - uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); - handle->socket = socket; - handle->events = 0; - - /* Obtain protocol information about the socket. */ - len = sizeof protocol_info; - if (getsockopt(socket, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &len) != 0) { - return WSAGetLastError(); - } - - /* Get the peer socket that is needed to enable fast poll. If the returned */ - /* value is NULL, the protocol is not implemented by MSAFD and we'll have */ - /* to use slow mode. */ - peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info); - - if (peer_socket != INVALID_SOCKET) { - /* Initialize fast poll specific fields. */ - handle->peer_socket = peer_socket; - } else { - /* Initialize slow poll specific fields. */ - handle->flags |= UV_HANDLE_POLL_SLOW; - } - - /* Intialize 2 poll reqs. */ - handle->submitted_events_1 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1)); - handle->poll_req_1.type = UV_POLL_REQ; - handle->poll_req_1.data = handle; - - handle->submitted_events_2 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2)); - handle->poll_req_2.type = UV_POLL_REQ; - handle->poll_req_2.data = handle; - - return 0; -} - - -int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) { - int err; - - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - err = uv__fast_poll_set(handle->loop, handle, events); - } else { - err = uv__slow_poll_set(handle->loop, handle, events); - } - - if (err) { - return uv_translate_sys_error(err); - } - - handle->poll_cb = cb; - - return 0; -} - - -int uv_poll_stop(uv_poll_t* handle) { - int err; - - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - err = uv__fast_poll_set(handle->loop, handle, 0); - } else { - err = uv__slow_poll_set(handle->loop, handle, 0); - } - - return uv_translate_sys_error(err); -} - - -void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, uv_req_t* req) { - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - uv__fast_poll_process_poll_req(loop, handle, req); - } else { - uv__slow_poll_process_poll_req(loop, handle, req); - } -} - - -int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) { - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - return uv__fast_poll_close(loop, handle); - } else { - return uv__slow_poll_close(loop, handle); - } -} - - -void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) { - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - assert(handle->submitted_events_1 == 0); - assert(handle->submitted_events_2 == 0); - - uv__handle_close(handle); -} diff --git a/third-party/libuv/src/win/process-stdio.c b/third-party/libuv/src/win/process-stdio.c deleted file mode 100644 index 5757764bfd..0000000000 --- a/third-party/libuv/src/win/process-stdio.c +++ /dev/null @@ -1,510 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <io.h> -#include <stdio.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" - - -/* - * The `child_stdio_buffer` buffer has the following layout: - * int number_of_fds - * unsigned char crt_flags[number_of_fds] - * HANDLE os_handle[number_of_fds] - */ -#define CHILD_STDIO_SIZE(count) \ - (sizeof(int) + \ - sizeof(unsigned char) * (count) + \ - sizeof(uintptr_t) * (count)) - -#define CHILD_STDIO_COUNT(buffer) \ - *((unsigned int*) (buffer)) - -#define CHILD_STDIO_CRT_FLAGS(buffer, fd) \ - *((unsigned char*) (buffer) + sizeof(int) + fd) - -#define CHILD_STDIO_HANDLE(buffer, fd) \ - *((HANDLE*) ((unsigned char*) (buffer) + \ - sizeof(int) + \ - sizeof(unsigned char) * \ - CHILD_STDIO_COUNT((buffer)) + \ - sizeof(HANDLE) * (fd))) - - -/* CRT file descriptor mode flags */ -#define FOPEN 0x01 -#define FEOFLAG 0x02 -#define FCRLF 0x04 -#define FPIPE 0x08 -#define FNOINHERIT 0x10 -#define FAPPEND 0x20 -#define FDEV 0x40 -#define FTEXT 0x80 - - -/* - * Clear the HANDLE_FLAG_INHERIT flag from all HANDLEs that were inherited - * the parent process. Don't check for errors - the stdio handles may not be - * valid, or may be closed already. There is no guarantee that this function - * does a perfect job. - */ -void uv_disable_stdio_inheritance(void) { - HANDLE handle; - STARTUPINFOW si; - - /* Make the windows stdio handles non-inheritable. */ - handle = GetStdHandle(STD_INPUT_HANDLE); - if (handle != NULL && handle != INVALID_HANDLE_VALUE) - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - - handle = GetStdHandle(STD_OUTPUT_HANDLE); - if (handle != NULL && handle != INVALID_HANDLE_VALUE) - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - - handle = GetStdHandle(STD_ERROR_HANDLE); - if (handle != NULL && handle != INVALID_HANDLE_VALUE) - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - - /* Make inherited CRT FDs non-inheritable. */ - GetStartupInfoW(&si); - if (uv__stdio_verify(si.lpReserved2, si.cbReserved2)) - uv__stdio_noinherit(si.lpReserved2); -} - - -static int uv__create_stdio_pipe_pair(uv_loop_t* loop, - uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) { - char pipe_name[64]; - SECURITY_ATTRIBUTES sa; - DWORD server_access = 0; - DWORD client_access = 0; - HANDLE child_pipe = INVALID_HANDLE_VALUE; - int err; - - if (flags & UV_READABLE_PIPE) { - /* The server needs inbound access too, otherwise CreateNamedPipe() */ - /* won't give us the FILE_READ_ATTRIBUTES permission. We need that to */ - /* probe the state of the write buffer when we're trying to shutdown */ - /* the pipe. */ - server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND; - client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES; - } - if (flags & UV_WRITABLE_PIPE) { - server_access |= PIPE_ACCESS_INBOUND; - client_access |= GENERIC_WRITE | FILE_READ_ATTRIBUTES; - } - - /* Create server pipe handle. */ - err = uv_stdio_pipe_server(loop, - server_pipe, - server_access, - pipe_name, - sizeof(pipe_name)); - if (err) - goto error; - - /* Create child pipe handle. */ - sa.nLength = sizeof sa; - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - child_pipe = CreateFileA(pipe_name, - client_access, - 0, - &sa, - OPEN_EXISTING, - server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0, - NULL); - if (child_pipe == INVALID_HANDLE_VALUE) { - err = GetLastError(); - goto error; - } - -#ifndef NDEBUG - /* Validate that the pipe was opened in the right mode. */ - { - DWORD mode; - BOOL r = GetNamedPipeHandleState(child_pipe, - &mode, - NULL, - NULL, - NULL, - NULL, - 0); - assert(r == TRUE); - assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT)); - } -#endif - - /* Do a blocking ConnectNamedPipe. This should not block because we have */ - /* both ends of the pipe created. */ - if (!ConnectNamedPipe(server_pipe->handle, NULL)) { - if (GetLastError() != ERROR_PIPE_CONNECTED) { - err = GetLastError(); - goto error; - } - } - - /* The server end is now readable and/or writable. */ - if (flags & UV_READABLE_PIPE) - server_pipe->flags |= UV_HANDLE_WRITABLE; - if (flags & UV_WRITABLE_PIPE) - server_pipe->flags |= UV_HANDLE_READABLE; - - *child_pipe_ptr = child_pipe; - return 0; - - error: - if (server_pipe->handle != INVALID_HANDLE_VALUE) { - uv_pipe_cleanup(loop, server_pipe); - } - - if (child_pipe != INVALID_HANDLE_VALUE) { - CloseHandle(child_pipe); - } - - return err; -} - - -static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) { - HANDLE current_process; - - - /* _get_osfhandle will sometimes return -2 in case of an error. This seems */ - /* to happen when fd <= 2 and the process' corresponding stdio handle is */ - /* set to NULL. Unfortunately DuplicateHandle will happily duplicate */ - /* (HANDLE) -2, so this situation goes unnoticed until someone tries to */ - /* use the duplicate. Therefore we filter out known-invalid handles here. */ - if (handle == INVALID_HANDLE_VALUE || - handle == NULL || - handle == (HANDLE) -2) { - *dup = INVALID_HANDLE_VALUE; - return ERROR_INVALID_HANDLE; - } - - current_process = GetCurrentProcess(); - - if (!DuplicateHandle(current_process, - handle, - current_process, - dup, - 0, - TRUE, - DUPLICATE_SAME_ACCESS)) { - *dup = INVALID_HANDLE_VALUE; - return GetLastError(); - } - - return 0; -} - - -static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) { - HANDLE handle; - - if (fd == -1) { - *dup = INVALID_HANDLE_VALUE; - return ERROR_INVALID_HANDLE; - } - - handle = uv__get_osfhandle(fd); - return uv__duplicate_handle(loop, handle, dup); -} - - -int uv__create_nul_handle(HANDLE* handle_ptr, - DWORD access) { - HANDLE handle; - SECURITY_ATTRIBUTES sa; - - sa.nLength = sizeof sa; - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - handle = CreateFileW(L"NUL", - access, - FILE_SHARE_READ | FILE_SHARE_WRITE, - &sa, - OPEN_EXISTING, - 0, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - return GetLastError(); - } - - *handle_ptr = handle; - return 0; -} - - -int uv__stdio_create(uv_loop_t* loop, - const uv_process_options_t* options, - BYTE** buffer_ptr) { - BYTE* buffer; - int count, i; - int err; - - count = options->stdio_count; - - if (count < 0 || count > 255) { - /* Only support FDs 0-255 */ - return ERROR_NOT_SUPPORTED; - } else if (count < 3) { - /* There should always be at least 3 stdio handles. */ - count = 3; - } - - /* Allocate the child stdio buffer */ - buffer = (BYTE*) malloc(CHILD_STDIO_SIZE(count)); - if (buffer == NULL) { - return ERROR_OUTOFMEMORY; - } - - /* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */ - /* clean up on failure. */ - CHILD_STDIO_COUNT(buffer) = count; - for (i = 0; i < count; i++) { - CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; - CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; - } - - for (i = 0; i < count; i++) { - uv_stdio_container_t fdopt; - if (i < options->stdio_count) { - fdopt = options->stdio[i]; - } else { - fdopt.flags = UV_IGNORE; - } - - switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | - UV_INHERIT_STREAM)) { - case UV_IGNORE: - /* Starting a process with no stdin/stout/stderr can confuse it. */ - /* So no matter what the user specified, we make sure the first */ - /* three FDs are always open in their typical modes, e.g. stdin */ - /* be readable and stdout/err should be writable. For FDs > 2, don't */ - /* do anything - all handles in the stdio buffer are initialized with */ - /* INVALID_HANDLE_VALUE, which should be okay. */ - if (i <= 2) { - DWORD access = (i == 0) ? FILE_GENERIC_READ : - FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES; - - err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i), - access); - if (err) - goto error; - - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; - } - break; - - case UV_CREATE_PIPE: { - /* Create a pair of two connected pipe ends; one end is turned into */ - /* an uv_pipe_t for use by the parent. The other one is given to */ - /* the child. */ - uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream; - HANDLE child_pipe; - - /* Create a new, connected pipe pair. stdio[i].stream should point */ - /* to an uninitialized, but not connected pipe handle. */ - assert(fdopt.data.stream->type == UV_NAMED_PIPE); - assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION)); - assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER)); - - err = uv__create_stdio_pipe_pair(loop, - parent_pipe, - &child_pipe, - fdopt.flags); - if (err) - goto error; - - CHILD_STDIO_HANDLE(buffer, i) = child_pipe; - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE; - break; - } - - case UV_INHERIT_FD: { - /* Inherit a raw FD. */ - HANDLE child_handle; - - /* Make an inheritable duplicate of the handle. */ - err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle); - if (err) { - /* If fdopt.data.fd is not valid and fd fd <= 2, then ignore the */ - /* error. */ - if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) { - CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; - CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; - break; - } - goto error; - } - - /* Figure out what the type is. */ - switch (GetFileType(child_handle)) { - case FILE_TYPE_DISK: - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN; - break; - - case FILE_TYPE_PIPE: - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE; - - case FILE_TYPE_CHAR: - case FILE_TYPE_REMOTE: - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; - break; - - case FILE_TYPE_UNKNOWN: - if (GetLastError() != 0) { - err = GetLastError(); - CloseHandle(child_handle); - goto error; - } - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; - break; - - default: - assert(0); - } - - CHILD_STDIO_HANDLE(buffer, i) = child_handle; - break; - } - - case UV_INHERIT_STREAM: { - /* Use an existing stream as the stdio handle for the child. */ - HANDLE stream_handle, child_handle; - unsigned char crt_flags; - uv_stream_t* stream = fdopt.data.stream; - - /* Leech the handle out of the stream. */ - if (stream->type == UV_TTY) { - stream_handle = ((uv_tty_t*) stream)->handle; - crt_flags = FOPEN | FDEV; - } else if (stream->type == UV_NAMED_PIPE && - stream->flags & UV_HANDLE_CONNECTED) { - stream_handle = ((uv_pipe_t*) stream)->handle; - crt_flags = FOPEN | FPIPE; - } else { - stream_handle = INVALID_HANDLE_VALUE; - crt_flags = 0; - } - - if (stream_handle == NULL || - stream_handle == INVALID_HANDLE_VALUE) { - /* The handle is already closed, or not yet created, or the */ - /* stream type is not supported. */ - err = ERROR_NOT_SUPPORTED; - goto error; - } - - /* Make an inheritable copy of the handle. */ - if (uv__duplicate_handle(loop, - stream_handle, - &child_handle) < 0) { - goto error; - } - - CHILD_STDIO_HANDLE(buffer, i) = child_handle; - CHILD_STDIO_CRT_FLAGS(buffer, i) = crt_flags; - break; - } - - default: - assert(0); - } - } - - *buffer_ptr = buffer; - return 0; - - error: - uv__stdio_destroy(buffer); - return err; -} - - -void uv__stdio_destroy(BYTE* buffer) { - int i, count; - - count = CHILD_STDIO_COUNT(buffer); - for (i = 0; i < count; i++) { - HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); - if (handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle); - } - } - - free(buffer); -} - - -void uv__stdio_noinherit(BYTE* buffer) { - int i, count; - - count = CHILD_STDIO_COUNT(buffer); - for (i = 0; i < count; i++) { - HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); - if (handle != INVALID_HANDLE_VALUE) { - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - } - } -} - - -int uv__stdio_verify(BYTE* buffer, WORD size) { - unsigned int count; - - /* Check the buffer pointer. */ - if (buffer == NULL) - return 0; - - /* Verify that the buffer is at least big enough to hold the count. */ - if (size < CHILD_STDIO_SIZE(0)) - return 0; - - /* Verify if the count is within range. */ - count = CHILD_STDIO_COUNT(buffer); - if (count > 256) - return 0; - - /* Verify that the buffer size is big enough to hold info for N FDs. */ - if (size < CHILD_STDIO_SIZE(count)) - return 0; - - return 1; -} - - -WORD uv__stdio_size(BYTE* buffer) { - return (WORD) CHILD_STDIO_SIZE(CHILD_STDIO_COUNT((buffer))); -} - - -HANDLE uv__stdio_handle(BYTE* buffer, int fd) { - return CHILD_STDIO_HANDLE(buffer, fd); -} diff --git a/third-party/libuv/src/win/process.c b/third-party/libuv/src/win/process.c deleted file mode 100644 index 813e522f75..0000000000 --- a/third-party/libuv/src/win/process.c +++ /dev/null @@ -1,1120 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <io.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <limits.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -#define SIGKILL 9 - - -typedef struct env_var { - const char* narrow; - const WCHAR* wide; - size_t len; /* including null or '=' */ - DWORD value_len; - int supplied; -} env_var_t; - -#define E_V(str) { str "=", L##str, sizeof(str), 0, 0 } - - -static HANDLE uv_global_job_handle_; -static uv_once_t uv_global_job_handle_init_guard_ = UV_ONCE_INIT; - - -static void uv__init_global_job_handle(void) { - /* Create a job object and set it up to kill all contained processes when - * it's closed. Since this handle is made non-inheritable and we're not - * giving it to anyone, we're the only process holding a reference to it. - * That means that if this process exits it is closed and all the processes - * it contains are killed. All processes created with uv_spawn that are not - * spawned with the UV_PROCESS_DETACHED flag are assigned to this job. - * - * We're setting the JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag so only the - * processes that we explicitly add are affected, and *their* subprocesses - * are not. This ensures that our child processes are not limited in their - * ability to use job control on Windows versions that don't deal with - * nested jobs (prior to Windows 8 / Server 2012). It also lets our child - * processes created detached processes without explicitly breaking away - * from job control (which uv_spawn doesn't, either). - */ - SECURITY_ATTRIBUTES attr; - JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; - - memset(&attr, 0, sizeof attr); - attr.bInheritHandle = FALSE; - - memset(&info, 0, sizeof info); - info.BasicLimitInformation.LimitFlags = - JOB_OBJECT_LIMIT_BREAKAWAY_OK | - JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK | - JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | - JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; - - uv_global_job_handle_ = CreateJobObjectW(&attr, NULL); - if (uv_global_job_handle_ == NULL) - uv_fatal_error(GetLastError(), "CreateJobObjectW"); - - if (!SetInformationJobObject(uv_global_job_handle_, - JobObjectExtendedLimitInformation, - &info, - sizeof info)) - uv_fatal_error(GetLastError(), "SetInformationJobObject"); -} - - -static int uv_utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) { - int ws_len, r; - WCHAR* ws; - - ws_len = MultiByteToWideChar(CP_UTF8, - 0, - s, - -1, - NULL, - 0); - if (ws_len <= 0) { - return GetLastError(); - } - - ws = (WCHAR*) malloc(ws_len * sizeof(WCHAR)); - if (ws == NULL) { - return ERROR_OUTOFMEMORY; - } - - r = MultiByteToWideChar(CP_UTF8, - 0, - s, - -1, - ws, - ws_len); - assert(r == ws_len); - - *ws_ptr = ws; - return 0; -} - - -static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_PROCESS); - handle->exit_cb = NULL; - handle->pid = 0; - handle->exit_signal = 0; - handle->wait_handle = INVALID_HANDLE_VALUE; - handle->process_handle = INVALID_HANDLE_VALUE; - handle->child_stdio_buffer = NULL; - handle->exit_cb_pending = 0; - - uv_req_init(loop, (uv_req_t*)&handle->exit_req); - handle->exit_req.type = UV_PROCESS_EXIT; - handle->exit_req.data = handle; -} - - -/* - * Path search functions - */ - -/* - * Helper function for search_path - */ -static WCHAR* search_path_join_test(const WCHAR* dir, - size_t dir_len, - const WCHAR* name, - size_t name_len, - const WCHAR* ext, - size_t ext_len, - const WCHAR* cwd, - size_t cwd_len) { - WCHAR *result, *result_pos; - DWORD attrs; - - if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) { - /* It's a full path without drive letter, use cwd's drive letter only */ - cwd_len = 2; - } else if (dir_len >= 2 && dir[1] == L':' && - (dir_len < 3 || (dir[2] != L'/' && dir[2] != L'\\'))) { - /* It's a relative path with drive letter (ext.g. D:../some/file) - * Replace drive letter in dir by full cwd if it points to the same drive, - * otherwise use the dir only. - */ - if (cwd_len < 2 || _wcsnicmp(cwd, dir, 2) != 0) { - cwd_len = 0; - } else { - dir += 2; - dir_len -= 2; - } - } else if (dir_len > 2 && dir[1] == L':') { - /* It's an absolute path with drive letter - * Don't use the cwd at all - */ - cwd_len = 0; - } - - /* Allocate buffer for output */ - result = result_pos = (WCHAR*)malloc(sizeof(WCHAR) * - (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1)); - - /* Copy cwd */ - wcsncpy(result_pos, cwd, cwd_len); - result_pos += cwd_len; - - /* Add a path separator if cwd didn't end with one */ - if (cwd_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) { - result_pos[0] = L'\\'; - result_pos++; - } - - /* Copy dir */ - wcsncpy(result_pos, dir, dir_len); - result_pos += dir_len; - - /* Add a separator if the dir didn't end with one */ - if (dir_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) { - result_pos[0] = L'\\'; - result_pos++; - } - - /* Copy filename */ - wcsncpy(result_pos, name, name_len); - result_pos += name_len; - - if (ext_len) { - /* Add a dot if the filename didn't end with one */ - if (name_len && result_pos[-1] != '.') { - result_pos[0] = L'.'; - result_pos++; - } - - /* Copy extension */ - wcsncpy(result_pos, ext, ext_len); - result_pos += ext_len; - } - - /* Null terminator */ - result_pos[0] = L'\0'; - - attrs = GetFileAttributesW(result); - - if (attrs != INVALID_FILE_ATTRIBUTES && - !(attrs & FILE_ATTRIBUTE_DIRECTORY)) { - return result; - } - - free(result); - return NULL; -} - - -/* - * Helper function for search_path - */ -static WCHAR* path_search_walk_ext(const WCHAR *dir, - size_t dir_len, - const WCHAR *name, - size_t name_len, - WCHAR *cwd, - size_t cwd_len, - int name_has_ext) { - WCHAR* result; - - /* If the name itself has a nonempty extension, try this extension first */ - if (name_has_ext) { - result = search_path_join_test(dir, dir_len, - name, name_len, - L"", 0, - cwd, cwd_len); - if (result != NULL) { - return result; - } - } - - /* Try .com extension */ - result = search_path_join_test(dir, dir_len, - name, name_len, - L"com", 3, - cwd, cwd_len); - if (result != NULL) { - return result; - } - - /* Try .exe extension */ - result = search_path_join_test(dir, dir_len, - name, name_len, - L"exe", 3, - cwd, cwd_len); - if (result != NULL) { - return result; - } - - return NULL; -} - - -/* - * search_path searches the system path for an executable filename - - * the windows API doesn't provide this as a standalone function nor as an - * option to CreateProcess. - * - * It tries to return an absolute filename. - * - * Furthermore, it tries to follow the semantics that cmd.exe, with this - * exception that PATHEXT environment variable isn't used. Since CreateProcess - * can start only .com and .exe files, only those extensions are tried. This - * behavior equals that of msvcrt's spawn functions. - * - * - Do not search the path if the filename already contains a path (either - * relative or absolute). - * - * - If there's really only a filename, check the current directory for file, - * then search all path directories. - * - * - If filename specified has *any* extension, search for the file with the - * specified extension first. - * - * - If the literal filename is not found in a directory, try *appending* - * (not replacing) .com first and then .exe. - * - * - The path variable may contain relative paths; relative paths are relative - * to the cwd. - * - * - Directories in path may or may not end with a trailing backslash. - * - * - CMD does not trim leading/trailing whitespace from path/pathex entries - * nor from the environment variables as a whole. - * - * - When cmd.exe cannot read a directory, it will just skip it and go on - * searching. However, unlike posix-y systems, it will happily try to run a - * file that is not readable/executable; if the spawn fails it will not - * continue searching. - * - * TODO: correctly interpret UNC paths - */ -static WCHAR* search_path(const WCHAR *file, - WCHAR *cwd, - const WCHAR *path) { - int file_has_dir; - WCHAR* result = NULL; - WCHAR *file_name_start; - WCHAR *dot; - const WCHAR *dir_start, *dir_end, *dir_path; - size_t dir_len; - int name_has_ext; - - size_t file_len = wcslen(file); - size_t cwd_len = wcslen(cwd); - - /* If the caller supplies an empty filename, - * we're not gonna return c:\windows\.exe -- GFY! - */ - if (file_len == 0 - || (file_len == 1 && file[0] == L'.')) { - return NULL; - } - - /* Find the start of the filename so we can split the directory from the */ - /* name. */ - for (file_name_start = (WCHAR*)file + file_len; - file_name_start > file - && file_name_start[-1] != L'\\' - && file_name_start[-1] != L'/' - && file_name_start[-1] != L':'; - file_name_start--); - - file_has_dir = file_name_start != file; - - /* Check if the filename includes an extension */ - dot = wcschr(file_name_start, L'.'); - name_has_ext = (dot != NULL && dot[1] != L'\0'); - - if (file_has_dir) { - /* The file has a path inside, don't use path */ - result = path_search_walk_ext( - file, file_name_start - file, - file_name_start, file_len - (file_name_start - file), - cwd, cwd_len, - name_has_ext); - - } else { - dir_end = path; - - /* The file is really only a name; look in cwd first, then scan path */ - result = path_search_walk_ext(L"", 0, - file, file_len, - cwd, cwd_len, - name_has_ext); - - while (result == NULL) { - if (*dir_end == L'\0') { - break; - } - - /* Skip the separator that dir_end now points to */ - if (dir_end != path) { - dir_end++; - } - - /* Next slice starts just after where the previous one ended */ - dir_start = dir_end; - - /* Slice until the next ; or \0 is found */ - dir_end = wcschr(dir_start, L';'); - if (dir_end == NULL) { - dir_end = wcschr(dir_start, L'\0'); - } - - /* If the slice is zero-length, don't bother */ - if (dir_end - dir_start == 0) { - continue; - } - - dir_path = dir_start; - dir_len = dir_end - dir_start; - - /* Adjust if the path is quoted. */ - if (dir_path[0] == '"' || dir_path[0] == '\'') { - ++dir_path; - --dir_len; - } - - if (dir_path[dir_len - 1] == '"' || dir_path[dir_len - 1] == '\'') { - --dir_len; - } - - result = path_search_walk_ext(dir_path, dir_len, - file, file_len, - cwd, cwd_len, - name_has_ext); - } - } - - return result; -} - - -/* - * Quotes command line arguments - * Returns a pointer to the end (next char to be written) of the buffer - */ -WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) { - size_t len = wcslen(source); - size_t i; - int quote_hit; - WCHAR* start; - - /* - * Check if the string must be quoted; - * if unnecessary, don't do it, it may only confuse older programs. - */ - if (len == 0) { - return target; - } - - if (NULL == wcspbrk(source, L" \t\"")) { - /* No quotation needed */ - wcsncpy(target, source, len); - target += len; - return target; - } - - if (NULL == wcspbrk(source, L"\"\\")) { - /* - * No embedded double quotes or backlashes, so I can just wrap - * quote marks around the whole thing. - */ - *(target++) = L'"'; - wcsncpy(target, source, len); - target += len; - *(target++) = L'"'; - return target; - } - - /* - * Expected input/output: - * input : hello"world - * output: "hello\"world" - * input : hello""world - * output: "hello\"\"world" - * input : hello\world - * output: hello\world - * input : hello\\world - * output: hello\\world - * input : hello\"world - * output: "hello\\\"world" - * input : hello\\"world - * output: "hello\\\\\"world" - * input : hello world\ - * output: "hello world\" - */ - - *(target++) = L'"'; - start = target; - quote_hit = 1; - - for (i = len; i > 0; --i) { - *(target++) = source[i - 1]; - - if (quote_hit && source[i - 1] == L'\\') { - *(target++) = L'\\'; - } else if(source[i - 1] == L'"') { - quote_hit = 1; - *(target++) = L'\\'; - } else { - quote_hit = 0; - } - } - target[0] = L'\0'; - wcsrev(start); - *(target++) = L'"'; - return target; -} - - -int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { - char** arg; - WCHAR* dst = NULL; - WCHAR* temp_buffer = NULL; - size_t dst_len = 0; - size_t temp_buffer_len = 0; - WCHAR* pos; - int arg_count = 0; - int err = 0; - - /* Count the required size. */ - for (arg = args; *arg; arg++) { - DWORD arg_len; - - arg_len = MultiByteToWideChar(CP_UTF8, - 0, - *arg, - -1, - NULL, - 0); - if (arg_len == 0) { - return GetLastError(); - } - - dst_len += arg_len; - - if (arg_len > temp_buffer_len) - temp_buffer_len = arg_len; - - arg_count++; - } - - /* Adjust for potential quotes. Also assume the worst-case scenario */ - /* that every character needs escaping, so we need twice as much space. */ - dst_len = dst_len * 2 + arg_count * 2; - - /* Allocate buffer for the final command line. */ - dst = (WCHAR*) malloc(dst_len * sizeof(WCHAR)); - if (dst == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - /* Allocate temporary working buffer. */ - temp_buffer = (WCHAR*) malloc(temp_buffer_len * sizeof(WCHAR)); - if (temp_buffer == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - pos = dst; - for (arg = args; *arg; arg++) { - DWORD arg_len; - - /* Convert argument to wide char. */ - arg_len = MultiByteToWideChar(CP_UTF8, - 0, - *arg, - -1, - temp_buffer, - (int) (dst + dst_len - pos)); - if (arg_len == 0) { - err = GetLastError(); - goto error; - } - - if (verbatim_arguments) { - /* Copy verbatim. */ - wcscpy(pos, temp_buffer); - pos += arg_len - 1; - } else { - /* Quote/escape, if needed. */ - pos = quote_cmd_arg(temp_buffer, pos); - } - - *pos++ = *(arg + 1) ? L' ' : L'\0'; - } - - free(temp_buffer); - - *dst_ptr = dst; - return 0; - -error: - free(dst); - free(temp_buffer); - return err; -} - - -/* - * If we learn that people are passing in huge environment blocks - * then we should probably qsort() the array and then bsearch() - * to see if it contains this variable. But there are ownership - * issues associated with that solution; this is the caller's - * char**, and modifying it is rude. - */ -static void check_required_vars_contains_var(env_var_t* required, int count, - const char* var) { - int i; - for (i = 0; i < count; ++i) { - if (_strnicmp(required[i].narrow, var, required[i].len) == 0) { - required[i].supplied = 1; - return; - } - } -} - - -/* - * The way windows takes environment variables is different than what C does; - * Windows wants a contiguous block of null-terminated strings, terminated - * with an additional null. - * - * Windows has a few "essential" environment variables. winsock will fail - * to initialize if SYSTEMROOT is not defined; some APIs make reference to - * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that - * these get defined if the input environment block does not contain any - * values for them. - */ -int make_program_env(char* env_block[], WCHAR** dst_ptr) { - WCHAR* dst; - WCHAR* ptr; - char** env; - size_t env_len = 1; /* room for closing null */ - int len; - int i; - DWORD var_size; - - env_var_t required_vars[] = { - E_V("SYSTEMROOT"), - E_V("SYSTEMDRIVE"), - E_V("TEMP"), - }; - - for (env = env_block; *env; env++) { - int len; - check_required_vars_contains_var(required_vars, - ARRAY_SIZE(required_vars), - *env); - - len = MultiByteToWideChar(CP_UTF8, - 0, - *env, - -1, - NULL, - 0); - if (len <= 0) { - return GetLastError(); - } - - env_len += len; - } - - for (i = 0; i < ARRAY_SIZE(required_vars); ++i) { - if (!required_vars[i].supplied) { - env_len += required_vars[i].len; - var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0); - if (var_size == 0) { - return GetLastError(); - } - required_vars[i].value_len = var_size; - env_len += var_size; - } - } - - dst = malloc(env_len * sizeof(WCHAR)); - if (!dst) { - return ERROR_OUTOFMEMORY; - } - - ptr = dst; - - for (env = env_block; *env; env++, ptr += len) { - len = MultiByteToWideChar(CP_UTF8, - 0, - *env, - -1, - ptr, - (int) (env_len - (ptr - dst))); - if (len <= 0) { - free(dst); - return GetLastError(); - } - } - - for (i = 0; i < ARRAY_SIZE(required_vars); ++i) { - if (!required_vars[i].supplied) { - wcscpy(ptr, required_vars[i].wide); - ptr += required_vars[i].len - 1; - *ptr++ = L'='; - var_size = GetEnvironmentVariableW(required_vars[i].wide, - ptr, - required_vars[i].value_len); - if (var_size == 0) { - uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); - } - ptr += required_vars[i].value_len; - } - } - - /* Terminate with an extra NULL. */ - *ptr = L'\0'; - - *dst_ptr = dst; - return 0; -} - - -/* - * Called on Windows thread-pool thread to indicate that - * a child process has exited. - */ -static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) { - uv_process_t* process = (uv_process_t*) data; - uv_loop_t* loop = process->loop; - - assert(didTimeout == FALSE); - assert(process); - assert(!process->exit_cb_pending); - - process->exit_cb_pending = 1; - - /* Post completed */ - POST_COMPLETION_FOR_REQ(loop, &process->exit_req); -} - - -/* Called on main thread after a child process has exited. */ -void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) { - int64_t exit_code; - DWORD status; - - assert(handle->exit_cb_pending); - handle->exit_cb_pending = 0; - - /* If we're closing, don't call the exit callback. Just schedule a close */ - /* callback now. */ - if (handle->flags & UV__HANDLE_CLOSING) { - uv_want_endgame(loop, (uv_handle_t*) handle); - return; - } - - /* Unregister from process notification. */ - if (handle->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->wait_handle); - handle->wait_handle = INVALID_HANDLE_VALUE; - } - - /* Set the handle to inactive: no callbacks will be made after the exit */ - /* callback.*/ - uv__handle_stop(handle); - - if (GetExitCodeProcess(handle->process_handle, &status)) { - exit_code = status; - } else { - /* Unable to to obtain the exit code. This should never happen. */ - exit_code = uv_translate_sys_error(GetLastError()); - } - - /* Fire the exit callback. */ - if (handle->exit_cb) { - handle->exit_cb(handle, exit_code, handle->exit_signal); - } -} - - -void uv_process_close(uv_loop_t* loop, uv_process_t* handle) { - uv__handle_closing(handle); - - if (handle->wait_handle != INVALID_HANDLE_VALUE) { - /* This blocks until either the wait was cancelled, or the callback has */ - /* completed. */ - BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE); - if (!r) { - /* This should never happen, and if it happens, we can't recover... */ - uv_fatal_error(GetLastError(), "UnregisterWaitEx"); - } - - handle->wait_handle = INVALID_HANDLE_VALUE; - } - - if (!handle->exit_cb_pending) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } -} - - -void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) { - assert(!handle->exit_cb_pending); - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - /* Clean-up the process handle. */ - CloseHandle(handle->process_handle); - - uv__handle_close(handle); -} - - -int uv_spawn(uv_loop_t* loop, - uv_process_t* process, - const uv_process_options_t* options) { - int i; - int err = 0; - WCHAR* path = NULL; - BOOL result; - WCHAR* application_path = NULL, *application = NULL, *arguments = NULL, - *env = NULL, *cwd = NULL; - STARTUPINFOW startup; - PROCESS_INFORMATION info; - DWORD process_flags; - - if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) { - return UV_ENOTSUP; - } - - if (options->file == NULL || - options->args == NULL) { - return UV_EINVAL; - } - - assert(options->file != NULL); - assert(!(options->flags & ~(UV_PROCESS_DETACHED | - UV_PROCESS_SETGID | - UV_PROCESS_SETUID | - UV_PROCESS_WINDOWS_HIDE | - UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); - - uv_process_init(loop, process); - process->exit_cb = options->exit_cb; - - err = uv_utf8_to_utf16_alloc(options->file, &application); - if (err) - goto done; - - err = make_program_args( - options->args, - options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS, - &arguments); - if (err) - goto done; - - if (options->env) { - err = make_program_env(options->env, &env); - if (err) - goto done; - } - - if (options->cwd) { - /* Explicit cwd */ - err = uv_utf8_to_utf16_alloc(options->cwd, &cwd); - if (err) - goto done; - - } else { - /* Inherit cwd */ - DWORD cwd_len, r; - - cwd_len = GetCurrentDirectoryW(0, NULL); - if (!cwd_len) { - err = GetLastError(); - goto done; - } - - cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR)); - if (cwd == NULL) { - err = ERROR_OUTOFMEMORY; - goto done; - } - - r = GetCurrentDirectoryW(cwd_len, cwd); - if (r == 0 || r >= cwd_len) { - err = GetLastError(); - goto done; - } - } - - /* Get PATH environment variable. */ - { - DWORD path_len, r; - - path_len = GetEnvironmentVariableW(L"PATH", NULL, 0); - if (path_len == 0) { - err = GetLastError(); - goto done; - } - - path = (WCHAR*) malloc(path_len * sizeof(WCHAR)); - if (path == NULL) { - err = ERROR_OUTOFMEMORY; - goto done; - } - - r = GetEnvironmentVariableW(L"PATH", path, path_len); - if (r == 0 || r >= path_len) { - err = GetLastError(); - goto done; - } - } - - err = uv__stdio_create(loop, options, &process->child_stdio_buffer); - if (err) - goto done; - - application_path = search_path(application, - cwd, - path); - if (application_path == NULL) { - /* Not found. */ - err = ERROR_FILE_NOT_FOUND; - goto done; - } - - startup.cb = sizeof(startup); - startup.lpReserved = NULL; - startup.lpDesktop = NULL; - startup.lpTitle = NULL; - startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - - startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer); - startup.lpReserved2 = (BYTE*) process->child_stdio_buffer; - - startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0); - startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1); - startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2); - - if (options->flags & UV_PROCESS_WINDOWS_HIDE) { - /* Use SW_HIDE to avoid any potential process window. */ - startup.wShowWindow = SW_HIDE; - } else { - startup.wShowWindow = SW_SHOWDEFAULT; - } - - process_flags = CREATE_UNICODE_ENVIRONMENT; - - if (options->flags & UV_PROCESS_DETACHED) { - /* Note that we're not setting the CREATE_BREAKAWAY_FROM_JOB flag. That - * means that libuv might not let you create a fully deamonized process - * when run under job control. However the type of job control that libuv - * itself creates doesn't trickle down to subprocesses so they can still - * daemonize. - * - * A reason to not do this is that CREATE_BREAKAWAY_FROM_JOB makes the - * CreateProcess call fail if we're under job control that doesn't allow - * breakaway. - */ - process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP; - } - - if (!CreateProcessW(application_path, - arguments, - NULL, - NULL, - 1, - process_flags, - env, - cwd, - &startup, - &info)) { - /* CreateProcessW failed. */ - err = GetLastError(); - goto done; - } - - /* Spawn succeeded */ - /* Beyond this point, failure is reported asynchronously. */ - - process->process_handle = info.hProcess; - process->pid = info.dwProcessId; - - /* If the process isn't spawned as detached, assign to the global job */ - /* object so windows will kill it when the parent process dies. */ - if (!(options->flags & UV_PROCESS_DETACHED)) { - uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle); - - if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) { - /* AssignProcessToJobObject might fail if this process is under job - * control and the job doesn't have the - * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version - * that doesn't support nested jobs. - * - * When that happens we just swallow the error and continue without - * establishing a kill-child-on-parent-exit relationship, otherwise - * there would be no way for libuv applications run under job control - * to spawn processes at all. - */ - DWORD err = GetLastError(); - if (err != ERROR_ACCESS_DENIED) - uv_fatal_error(err, "AssignProcessToJobObject"); - } - } - - /* Set IPC pid to all IPC pipes. */ - for (i = 0; i < options->stdio_count; i++) { - const uv_stdio_container_t* fdopt = &options->stdio[i]; - if (fdopt->flags & UV_CREATE_PIPE && - fdopt->data.stream->type == UV_NAMED_PIPE && - ((uv_pipe_t*) fdopt->data.stream)->ipc) { - ((uv_pipe_t*) fdopt->data.stream)->ipc_pid = info.dwProcessId; - } - } - - /* Setup notifications for when the child process exits. */ - result = RegisterWaitForSingleObject(&process->wait_handle, - process->process_handle, exit_wait_callback, (void*)process, INFINITE, - WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); - if (!result) { - uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject"); - } - - CloseHandle(info.hThread); - - assert(!err); - - /* Make the handle active. It will remain active until the exit callback */ - /* iis made or the handle is closed, whichever happens first. */ - uv__handle_start(process); - - /* Cleanup, whether we succeeded or failed. */ - done: - free(application); - free(application_path); - free(arguments); - free(cwd); - free(env); - free(path); - - if (process->child_stdio_buffer != NULL) { - /* Clean up child stdio handles. */ - uv__stdio_destroy(process->child_stdio_buffer); - process->child_stdio_buffer = NULL; - } - - return uv_translate_sys_error(err); -} - - -static int uv__kill(HANDLE process_handle, int signum) { - switch (signum) { - case SIGTERM: - case SIGKILL: - case SIGINT: { - /* Unconditionally terminate the process. On Windows, killed processes */ - /* normally return 1. */ - DWORD status; - int err; - - if (TerminateProcess(process_handle, 1)) - return 0; - - /* If the process already exited before TerminateProcess was called, */ - /* TerminateProcess will fail with ERROR_ACESS_DENIED. */ - err = GetLastError(); - if (err == ERROR_ACCESS_DENIED && - GetExitCodeProcess(process_handle, &status) && - status != STILL_ACTIVE) { - return UV_ESRCH; - } - - return uv_translate_sys_error(err); - } - - case 0: { - /* Health check: is the process still alive? */ - DWORD status; - - if (!GetExitCodeProcess(process_handle, &status)) - return uv_translate_sys_error(GetLastError()); - - if (status != STILL_ACTIVE) - return UV_ESRCH; - - return 0; - } - - default: - /* Unsupported signal. */ - return UV_ENOSYS; - } -} - - -int uv_process_kill(uv_process_t* process, int signum) { - int err; - - if (process->process_handle == INVALID_HANDLE_VALUE) { - return UV_EINVAL; - } - - err = uv__kill(process->process_handle, signum); - if (err) { - return err; /* err is already translated. */ - } - - process->exit_signal = signum; - - return 0; -} - - -int uv_kill(int pid, int signum) { - int err; - HANDLE process_handle = OpenProcess(PROCESS_TERMINATE | - PROCESS_QUERY_INFORMATION, FALSE, pid); - - if (process_handle == NULL) { - err = GetLastError(); - if (err == ERROR_INVALID_PARAMETER) { - return UV_ESRCH; - } else { - return uv_translate_sys_error(err); - } - } - - err = uv__kill(process_handle, signum); - CloseHandle(process_handle); - - return err; /* err is already translated. */ -} diff --git a/third-party/libuv/src/win/req-inl.h b/third-party/libuv/src/win/req-inl.h deleted file mode 100644 index 353fe90b6d..0000000000 --- a/third-party/libuv/src/win/req-inl.h +++ /dev/null @@ -1,224 +0,0 @@ -/* 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 - * 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. - */ - -#ifndef UV_WIN_REQ_INL_H_ -#define UV_WIN_REQ_INL_H_ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" - - -#define SET_REQ_STATUS(req, status) \ - (req)->overlapped.Internal = (ULONG_PTR) (status) - -#define SET_REQ_ERROR(req, error) \ - SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error))) - -#define SET_REQ_SUCCESS(req) \ - SET_REQ_STATUS((req), STATUS_SUCCESS) - -#define GET_REQ_STATUS(req) \ - ((NTSTATUS) (req)->overlapped.Internal) - -#define REQ_SUCCESS(req) \ - (NT_SUCCESS(GET_REQ_STATUS((req)))) - -#define GET_REQ_ERROR(req) \ - (pRtlNtStatusToDosError(GET_REQ_STATUS((req)))) - -#define GET_REQ_SOCK_ERROR(req) \ - (uv_ntstatus_to_winsock_error(GET_REQ_STATUS((req)))) - - -#define REGISTER_HANDLE_REQ(loop, handle, req) \ - do { \ - INCREASE_ACTIVE_COUNT((loop), (handle)); \ - uv__req_register((loop), (req)); \ - } while (0) - -#define UNREGISTER_HANDLE_REQ(loop, handle, req) \ - do { \ - DECREASE_ACTIVE_COUNT((loop), (handle)); \ - uv__req_unregister((loop), (req)); \ - } while (0) - - -#define UV_SUCCEEDED_WITHOUT_IOCP(result) \ - ((result) && (handle->flags & UV_HANDLE_SYNC_BYPASS_IOCP)) - -#define UV_SUCCEEDED_WITH_IOCP(result) \ - ((result) || (GetLastError() == ERROR_IO_PENDING)) - - -#define POST_COMPLETION_FOR_REQ(loop, req) \ - if (!PostQueuedCompletionStatus((loop)->iocp, \ - 0, \ - 0, \ - &((req)->overlapped))) { \ - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \ - } - - -INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) { - req->type = UV_UNKNOWN_REQ; - SET_REQ_SUCCESS(req); -} - - -INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { - return CONTAINING_RECORD(overlapped, uv_req_t, overlapped); -} - - -INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) { - req->next_req = NULL; - if (loop->pending_reqs_tail) { - req->next_req = loop->pending_reqs_tail->next_req; - loop->pending_reqs_tail->next_req = req; - loop->pending_reqs_tail = req; - } else { - req->next_req = req; - loop->pending_reqs_tail = req; - } -} - - -#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \ - do { \ - switch (((uv_handle_t*) (req)->handle_at)->type) { \ - case UV_TCP: \ - uv_process_tcp_##method##_req(loop, \ - (uv_tcp_t*) ((req)->handle_at), \ - req); \ - break; \ - \ - case UV_NAMED_PIPE: \ - uv_process_pipe_##method##_req(loop, \ - (uv_pipe_t*) ((req)->handle_at), \ - req); \ - break; \ - \ - case UV_TTY: \ - uv_process_tty_##method##_req(loop, \ - (uv_tty_t*) ((req)->handle_at), \ - req); \ - break; \ - \ - default: \ - assert(0); \ - } \ - } while (0) - - -INLINE static void uv_process_reqs(uv_loop_t* loop) { - uv_req_t* req; - uv_req_t* first; - uv_req_t* next; - - if (loop->pending_reqs_tail == NULL) { - return; - } - - first = loop->pending_reqs_tail->next_req; - next = first; - loop->pending_reqs_tail = NULL; - - while (next != NULL) { - req = next; - next = req->next_req != first ? req->next_req : NULL; - - switch (req->type) { - case UV_READ: - DELEGATE_STREAM_REQ(loop, req, read, data); - break; - - case UV_WRITE: - DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle); - break; - - case UV_ACCEPT: - DELEGATE_STREAM_REQ(loop, req, accept, data); - break; - - case UV_CONNECT: - DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle); - break; - - case UV_SHUTDOWN: - /* Tcp shutdown requests don't come here. */ - assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE); - uv_process_pipe_shutdown_req( - loop, - (uv_pipe_t*) ((uv_shutdown_t*) req)->handle, - (uv_shutdown_t*) req); - break; - - case UV_UDP_RECV: - uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req); - break; - - case UV_UDP_SEND: - uv_process_udp_send_req(loop, - ((uv_udp_send_t*) req)->handle, - (uv_udp_send_t*) req); - break; - - case UV_WAKEUP: - uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req); - break; - - case UV_SIGNAL_REQ: - uv_process_signal_req(loop, (uv_signal_t*) req->data, req); - break; - - case UV_POLL_REQ: - uv_process_poll_req(loop, (uv_poll_t*) req->data, req); - break; - - case UV_GETADDRINFO: - uv_process_getaddrinfo_req(loop, (uv_getaddrinfo_t*) req); - break; - - case UV_PROCESS_EXIT: - uv_process_proc_exit(loop, (uv_process_t*) req->data); - break; - - case UV_FS: - uv_process_fs_req(loop, (uv_fs_t*) req); - break; - - case UV_WORK: - uv_process_work_req(loop, (uv_work_t*) req); - break; - - case UV_FS_EVENT_REQ: - uv_process_fs_event_req(loop, req, (uv_fs_event_t*) req->data); - break; - - default: - assert(0); - } - } -} - -#endif /* UV_WIN_REQ_INL_H_ */ diff --git a/third-party/libuv/src/win/req.c b/third-party/libuv/src/win/req.c deleted file mode 100644 index 111cc5e289..0000000000 --- a/third-party/libuv/src/win/req.c +++ /dev/null @@ -1,25 +0,0 @@ -/* 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 - * 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 <assert.h> - -#include "uv.h" -#include "internal.h" diff --git a/third-party/libuv/src/win/signal.c b/third-party/libuv/src/win/signal.c deleted file mode 100644 index 9dc5fccc29..0000000000 --- a/third-party/libuv/src/win/signal.c +++ /dev/null @@ -1,352 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <signal.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -RB_HEAD(uv_signal_tree_s, uv_signal_s); - -static struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree); -static ssize_t volatile uv__signal_control_handler_refs = 0; -static CRITICAL_SECTION uv__signal_lock; - - -void uv_signals_init() { - InitializeCriticalSection(&uv__signal_lock); -} - - -static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { - /* Compare signums first so all watchers with the same signnum end up */ - /* adjacent. */ - if (w1->signum < w2->signum) return -1; - if (w1->signum > w2->signum) return 1; - - /* Sort by loop pointer, so we can easily look up the first item after */ - /* { .signum = x, .loop = NULL } */ - if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1; - if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1; - - if ((uintptr_t) w1 < (uintptr_t) w2) return -1; - if ((uintptr_t) w1 > (uintptr_t) w2) return 1; - - return 0; -} - - -RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare); - - -/* - * Dispatches signal {signum} to all active uv_signal_t watchers in all loops. - * Returns 1 if the signal was dispatched to any watcher, or 0 if there were - * no active signal watchers observing this signal. - */ -int uv__signal_dispatch(int signum) { - uv_signal_t lookup; - uv_signal_t* handle; - int dispatched = 0; - - EnterCriticalSection(&uv__signal_lock); - - lookup.signum = signum; - lookup.loop = NULL; - - for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup); - handle != NULL && handle->signum == signum; - handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) { - unsigned long previous = InterlockedExchange(&handle->pending_signum, signum); - - if (!previous) { - POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req); - } - - dispatched = 1; - } - - LeaveCriticalSection(&uv__signal_lock); - - return dispatched; -} - - -static BOOL WINAPI uv__signal_control_handler(DWORD type) { - switch (type) { - case CTRL_C_EVENT: - return uv__signal_dispatch(SIGINT); - - case CTRL_BREAK_EVENT: - return uv__signal_dispatch(SIGBREAK); - - case CTRL_CLOSE_EVENT: - if (uv__signal_dispatch(SIGHUP)) { - /* Windows will terminate the process after the control handler */ - /* returns. After that it will just terminate our process. Therefore */ - /* block the signal handler so the main loop has some time to pick */ - /* up the signal and do something for a few seconds. */ - Sleep(INFINITE); - return TRUE; - } - return FALSE; - - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - /* These signals are only sent to services. Services have their own */ - /* notification mechanism, so there's no point in handling these. */ - - default: - /* We don't handle these. */ - return FALSE; - } -} - - -static int uv__signal_register_control_handler() { - /* When this function is called, the uv__signal_lock must be held. */ - - /* If the console control handler has already been hooked, just add a */ - /* reference. */ - if (uv__signal_control_handler_refs > 0) - return 0; - - if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE)) - return GetLastError(); - - uv__signal_control_handler_refs++; - - return 0; -} - - -static void uv__signal_unregister_control_handler() { - /* When this function is called, the uv__signal_lock must be held. */ - BOOL r; - - /* Don't unregister if the number of console control handlers exceeds one. */ - /* Just remove a reference in that case. */ - if (uv__signal_control_handler_refs > 1) { - uv__signal_control_handler_refs--; - return; - } - - assert(uv__signal_control_handler_refs == 1); - - r = SetConsoleCtrlHandler(uv__signal_control_handler, FALSE); - /* This should never fail; if it does it is probably a bug in libuv. */ - assert(r); - - uv__signal_control_handler_refs--; -} - - -static int uv__signal_register(int signum) { - switch (signum) { - case SIGINT: - case SIGBREAK: - case SIGHUP: - return uv__signal_register_control_handler(); - - case SIGWINCH: - /* SIGWINCH is generated in tty.c. No need to register anything. */ - return 0; - - case SIGILL: - case SIGABRT_COMPAT: - case SIGFPE: - case SIGSEGV: - case SIGTERM: - case SIGABRT: - /* Signal is never raised. */ - return 0; - - default: - /* Invalid signal. */ - return ERROR_INVALID_PARAMETER; - } -} - - -static void uv__signal_unregister(int signum) { - switch (signum) { - case SIGINT: - case SIGBREAK: - case SIGHUP: - uv__signal_unregister_control_handler(); - return; - - case SIGWINCH: - /* SIGWINCH is generated in tty.c. No need to unregister anything. */ - return; - - case SIGILL: - case SIGABRT_COMPAT: - case SIGFPE: - case SIGSEGV: - case SIGTERM: - case SIGABRT: - /* Nothing is registered for this signal. */ - return; - - default: - /* Libuv bug. */ - assert(0 && "Invalid signum"); - return; - } -} - - -int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { - uv_req_t* req; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); - handle->pending_signum = 0; - handle->signum = 0; - handle->signal_cb = NULL; - - req = &handle->signal_req; - uv_req_init(loop, req); - req->type = UV_SIGNAL_REQ; - req->data = handle; - - return 0; -} - - -int uv_signal_stop(uv_signal_t* handle) { - uv_signal_t* removed_handle; - - /* If the watcher wasn't started, this is a no-op. */ - if (handle->signum == 0) - return 0; - - EnterCriticalSection(&uv__signal_lock); - - uv__signal_unregister(handle->signum); - - removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle); - assert(removed_handle == handle); - - LeaveCriticalSection(&uv__signal_lock); - - handle->signum = 0; - uv__handle_stop(handle); - - return 0; -} - - -int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { - int err; - - /* If the user supplies signum == 0, then return an error already. If the */ - /* signum is otherwise invalid then uv__signal_register will find out */ - /* eventually. */ - if (signum == 0) { - return UV_EINVAL; - } - - /* Short circuit: if the signal watcher is already watching {signum} don't */ - /* go through the process of deregistering and registering the handler. */ - /* Additionally, this avoids pending signals getting lost in the (small) */ - /* time frame that handle->signum == 0. */ - if (signum == handle->signum) { - handle->signal_cb = signal_cb; - return 0; - } - - /* If the signal handler was already active, stop it first. */ - if (handle->signum != 0) { - int r = uv_signal_stop(handle); - /* uv_signal_stop is infallible. */ - assert(r == 0); - } - - EnterCriticalSection(&uv__signal_lock); - - err = uv__signal_register(signum); - if (err) { - /* Uh-oh, didn't work. */ - LeaveCriticalSection(&uv__signal_lock); - return uv_translate_sys_error(err); - } - - handle->signum = signum; - RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle); - - LeaveCriticalSection(&uv__signal_lock); - - handle->signal_cb = signal_cb; - uv__handle_start(handle); - - return 0; -} - - -void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, - uv_req_t* req) { - unsigned long dispatched_signum; - - assert(handle->type == UV_SIGNAL); - assert(req->type == UV_SIGNAL_REQ); - - dispatched_signum = InterlockedExchange(&handle->pending_signum, 0); - assert(dispatched_signum != 0); - - /* Check if the pending signal equals the signum that we are watching for. */ - /* These can get out of sync when the handler is stopped and restarted */ - /* while the signal_req is pending. */ - if (dispatched_signum == handle->signum) - handle->signal_cb(handle, dispatched_signum); - - if (handle->flags & UV__HANDLE_CLOSING) { - /* When it is closing, it must be stopped at this point. */ - assert(handle->signum == 0); - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) { - uv_signal_stop(handle); - uv__handle_closing(handle); - - if (handle->pending_signum == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) { - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - assert(handle->signum == 0); - assert(handle->pending_signum == 0); - - handle->flags |= UV_HANDLE_CLOSED; - - uv__handle_close(handle); -} diff --git a/third-party/libuv/src/win/stream-inl.h b/third-party/libuv/src/win/stream-inl.h deleted file mode 100644 index e4bf086368..0000000000 --- a/third-party/libuv/src/win/stream-inl.h +++ /dev/null @@ -1,67 +0,0 @@ -/* 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 - * 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. - */ - -#ifndef UV_WIN_STREAM_INL_H_ -#define UV_WIN_STREAM_INL_H_ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -INLINE static void uv_stream_init(uv_loop_t* loop, - uv_stream_t* handle, - uv_handle_type type) { - uv__handle_init(loop, (uv_handle_t*) handle, type); - handle->write_queue_size = 0; - handle->activecnt = 0; -} - - -INLINE static void uv_connection_init(uv_stream_t* handle) { - handle->flags |= UV_HANDLE_CONNECTION; - handle->write_reqs_pending = 0; - - uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req)); - handle->read_req.event_handle = NULL; - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - handle->read_req.type = UV_READ; - handle->read_req.data = handle; - - handle->shutdown_req = NULL; -} - - -INLINE static size_t uv_count_bufs(const uv_buf_t bufs[], unsigned int nbufs) { - unsigned int i; - size_t bytes; - - bytes = 0; - for (i = 0; i < nbufs; i++) - bytes += (size_t) bufs[i].len; - - return bytes; -} - -#endif /* UV_WIN_STREAM_INL_H_ */ diff --git a/third-party/libuv/src/win/stream.c b/third-party/libuv/src/win/stream.c deleted file mode 100644 index 2eaa74e766..0000000000 --- a/third-party/libuv/src/win/stream.c +++ /dev/null @@ -1,253 +0,0 @@ -/* 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 - * 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 <assert.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { - int err; - - err = ERROR_INVALID_PARAMETER; - switch (stream->type) { - case UV_TCP: - err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb); - break; - case UV_NAMED_PIPE: - err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_accept(uv_stream_t* server, uv_stream_t* client) { - int err; - - err = ERROR_INVALID_PARAMETER; - switch (server->type) { - case UV_TCP: - err = uv_tcp_accept((uv_tcp_t*)server, (uv_tcp_t*)client); - break; - case UV_NAMED_PIPE: - err = uv_pipe_accept((uv_pipe_t*)server, client); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - int err; - - if (handle->flags & UV_HANDLE_READING) { - return UV_EALREADY; - } - - if (!(handle->flags & UV_HANDLE_READABLE)) { - return UV_ENOTCONN; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_TCP: - err = uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb); - break; - case UV_NAMED_PIPE: - err = uv_pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb); - break; - case UV_TTY: - err = uv_tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_read2_start(uv_stream_t* handle, uv_alloc_cb alloc_cb, - uv_read2_cb read_cb) { - int err; - - if (handle->flags & UV_HANDLE_READING) { - return UV_EALREADY; - } - - if (!(handle->flags & UV_HANDLE_READABLE)) { - return UV_ENOTCONN; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_NAMED_PIPE: - err = uv_pipe_read2_start((uv_pipe_t*)handle, alloc_cb, read_cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_read_stop(uv_stream_t* handle) { - int err; - - if (!(handle->flags & UV_HANDLE_READING)) - return 0; - - err = 0; - if (handle->type == UV_TTY) { - err = uv_tty_read_stop((uv_tty_t*) handle); - } else { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(handle->loop, handle); - } - - return uv_translate_sys_error(err); -} - - -int uv_write(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - uv_loop_t* loop = handle->loop; - int err; - - if (!(handle->flags & UV_HANDLE_WRITABLE)) { - return UV_EPIPE; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_TCP: - err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb); - break; - case UV_NAMED_PIPE: - err = uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, nbufs, cb); - break; - case UV_TTY: - err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_write2(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - uv_loop_t* loop = handle->loop; - int err; - - if (!(handle->flags & UV_HANDLE_WRITABLE)) { - return UV_EPIPE; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_NAMED_PIPE: - err = uv_pipe_write2(loop, - req, - (uv_pipe_t*) handle, - bufs, - nbufs, - send_handle, - cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_try_write(uv_stream_t* stream, - const uv_buf_t bufs[], - unsigned int nbufs) { - /* NOTE: Won't work with overlapped writes */ - return UV_ENOSYS; -} - - -int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { - uv_loop_t* loop = handle->loop; - - if (!(handle->flags & UV_HANDLE_WRITABLE)) { - return UV_EPIPE; - } - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_SHUTDOWN; - req->handle = handle; - req->cb = cb; - - handle->flags &= ~UV_HANDLE_WRITABLE; - handle->shutdown_req = req; - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - - uv_want_endgame(loop, (uv_handle_t*)handle); - - return 0; -} - - -int uv_is_readable(const uv_stream_t* handle) { - return !!(handle->flags & UV_HANDLE_READABLE); -} - - -int uv_is_writable(const uv_stream_t* handle) { - return !!(handle->flags & UV_HANDLE_WRITABLE); -} - - -int uv_stream_set_blocking(uv_stream_t* handle, int blocking) { - if (blocking != 0) - handle->flags |= UV_HANDLE_BLOCKING_WRITES; - else - handle->flags &= ~UV_HANDLE_BLOCKING_WRITES; - - return 0; -} diff --git a/third-party/libuv/src/win/tcp.c b/third-party/libuv/src/win/tcp.c deleted file mode 100644 index 8fa2146a06..0000000000 --- a/third-party/libuv/src/win/tcp.c +++ /dev/null @@ -1,1417 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -/* - * Threshold of active tcp streams for which to preallocate tcp read buffers. - * (Due to node slab allocator performing poorly under this pattern, - * the optimization is temporarily disabled (threshold=0). This will be - * revisited once node allocator is improved.) - */ -const unsigned int uv_active_tcp_streams_threshold = 0; - -/* - * Number of simultaneous pending AcceptEx calls. - */ -const unsigned int uv_simultaneous_server_accepts = 32; - -/* A zero-size buffer for use by uv_tcp_read */ -static char uv_zero_[] = ""; - -static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) { - if (setsockopt(socket, - IPPROTO_TCP, - TCP_NODELAY, - (const char*)&enable, - sizeof enable) == -1) { - return WSAGetLastError(); - } - return 0; -} - - -static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) { - if (setsockopt(socket, - SOL_SOCKET, - SO_KEEPALIVE, - (const char*)&enable, - sizeof enable) == -1) { - return WSAGetLastError(); - } - - if (enable && setsockopt(socket, - IPPROTO_TCP, - TCP_KEEPALIVE, - (const char*)&delay, - sizeof delay) == -1) { - return WSAGetLastError(); - } - - return 0; -} - - -static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle, - SOCKET socket, int family, int imported) { - DWORD yes = 1; - int non_ifs_lsp; - int err; - - assert(handle->socket == INVALID_SOCKET); - - /* Set the socket to nonblocking mode */ - if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - /* Associate it with the I/O completion port. */ - /* Use uv_handle_t pointer as completion key. */ - if (CreateIoCompletionPort((HANDLE)socket, - loop->iocp, - (ULONG_PTR)socket, - 0) == NULL) { - if (imported) { - handle->flags |= UV_HANDLE_EMULATE_IOCP; - } else { - return GetLastError(); - } - } - - if (family == AF_INET6) { - non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6; - } else { - non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4; - } - - if (pSetFileCompletionNotificationModes && - !(handle->flags & UV_HANDLE_EMULATE_IOCP) && !non_ifs_lsp) { - if (pSetFileCompletionNotificationModes((HANDLE) socket, - FILE_SKIP_SET_EVENT_ON_HANDLE | - FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { - handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; - } else if (GetLastError() != ERROR_INVALID_FUNCTION) { - return GetLastError(); - } - } - - if (handle->flags & UV_HANDLE_TCP_NODELAY) { - err = uv__tcp_nodelay(handle, socket, 1); - if (err) - return err; - } - - /* TODO: Use stored delay. */ - if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) { - err = uv__tcp_keepalive(handle, socket, 1, 60); - if (err) - return err; - } - - handle->socket = socket; - - if (family == AF_INET6) { - handle->flags |= UV_HANDLE_IPV6; - } else { - assert(!(handle->flags & UV_HANDLE_IPV6)); - } - - return 0; -} - - -int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) { - uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP); - - handle->accept_reqs = NULL; - handle->pending_accepts = NULL; - handle->socket = INVALID_SOCKET; - handle->reqs_pending = 0; - handle->func_acceptex = NULL; - handle->func_connectex = NULL; - handle->processed_accepts = 0; - - return 0; -} - - -void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { - int err; - unsigned int i; - uv_tcp_accept_t* req; - - if (handle->flags & UV_HANDLE_CONNECTION && - handle->shutdown_req != NULL && - handle->write_reqs_pending == 0) { - - UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req); - - err = 0; - if (handle->flags & UV__HANDLE_CLOSING) { - err = ERROR_OPERATION_ABORTED; - } else if (shutdown(handle->socket, SD_SEND) == SOCKET_ERROR) { - err = WSAGetLastError(); - } - - if (handle->shutdown_req->cb) { - handle->shutdown_req->cb(handle->shutdown_req, - uv_translate_sys_error(err)); - } - - handle->shutdown_req = NULL; - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) { - closesocket(handle->socket); - handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; - } - - if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->accept_reqs) { - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - for (i = 0; i < uv_simultaneous_server_accepts; i++) { - req = &handle->accept_reqs[i]; - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - req->wait_handle = INVALID_HANDLE_VALUE; - } - if (req->event_handle) { - CloseHandle(req->event_handle); - req->event_handle = NULL; - } - } - } - - free(handle->accept_reqs); - handle->accept_reqs = NULL; - } - - if (handle->flags & UV_HANDLE_CONNECTION && - handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->read_req.wait_handle); - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - } - if (handle->read_req.event_handle) { - CloseHandle(handle->read_req.event_handle); - handle->read_req.event_handle = NULL; - } - } - - uv__handle_close(handle); - loop->active_tcp_streams--; - } -} - - -static int uv_tcp_try_bind(uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - DWORD err; - int r; - - if (handle->socket == INVALID_SOCKET) { - SOCKET sock = socket(addr->sa_family, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) { - return WSAGetLastError(); - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) { - err = GetLastError(); - closesocket(sock); - return err; - } - - err = uv_tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0); - if (err) { - closesocket(sock); - return err; - } - } - -#ifdef IPV6_V6ONLY - if (addr->sa_family == AF_INET6) { - int on; - - on = (flags & UV_TCP_IPV6ONLY) != 0; - - /* TODO: how to handle errors? This may fail if there is no ipv4 stack */ - /* available, or when run on XP/2003 which have no support for dualstack */ - /* sockets. For now we're silently ignoring the error. */ - setsockopt(handle->socket, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof on); - } -#endif - - r = bind(handle->socket, addr, addrlen); - - if (r == SOCKET_ERROR) { - err = WSAGetLastError(); - if (err == WSAEADDRINUSE) { - /* Some errors are not to be reported until connect() or listen() */ - handle->bind_error = err; - handle->flags |= UV_HANDLE_BIND_ERROR; - } else { - return err; - } - } - - handle->flags |= UV_HANDLE_BOUND; - - return 0; -} - - -static void CALLBACK post_completion(void* context, BOOLEAN timed_out) { - uv_req_t* req; - uv_tcp_t* handle; - - req = (uv_req_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->data; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->overlapped.InternalHigh, - 0, - &req->overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) { - uv_write_t* req; - uv_tcp_t* handle; - - req = (uv_write_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->handle; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->overlapped.InternalHigh, - 0, - &req->overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { - uv_loop_t* loop = handle->loop; - BOOL success; - DWORD bytes; - SOCKET accept_socket; - short family; - - assert(handle->flags & UV_HANDLE_LISTENING); - assert(req->accept_socket == INVALID_SOCKET); - - /* choose family and extension function */ - if (handle->flags & UV_HANDLE_IPV6) { - family = AF_INET6; - } else { - family = AF_INET; - } - - /* Open a socket for the accepted connection. */ - accept_socket = socket(family, SOCK_STREAM, 0); - if (accept_socket == INVALID_SOCKET) { - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - return; - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - closesocket(accept_socket); - return; - } - - /* Prepare the overlapped structure. */ - memset(&(req->overlapped), 0, sizeof(req->overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); - } - - success = handle->func_acceptex(handle->socket, - accept_socket, - (void*)req->accept_buffer, - 0, - sizeof(struct sockaddr_storage), - sizeof(struct sockaddr_storage), - &bytes, - &req->overlapped); - - if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { - /* Process the req without IOCP. */ - req->accept_socket = accept_socket; - handle->reqs_pending++; - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(success)) { - /* The req will be processed with IOCP. */ - req->accept_socket = accept_socket; - handle->reqs_pending++; - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - req->wait_handle == INVALID_HANDLE_VALUE && - !RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_completion, (void*) 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. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - /* Destroy the preallocated client socket. */ - closesocket(accept_socket); - /* Destroy the event handle */ - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - CloseHandle(req->overlapped.hEvent); - req->event_handle = NULL; - } - } -} - - -static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { - uv_read_t* req; - uv_buf_t buf; - int result; - DWORD bytes, flags; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - req = &handle->read_req; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - - /* - * Preallocate a read buffer if the number of active streams is below - * the threshold. - */ - if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) { - handle->flags &= ~UV_HANDLE_ZERO_READ; - handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->read_buffer); - if (handle->read_buffer.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->read_buffer); - return; - } - assert(handle->read_buffer.base != NULL); - buf = handle->read_buffer; - } else { - handle->flags |= UV_HANDLE_ZERO_READ; - buf.base = (char*) &uv_zero_; - buf.len = 0; - } - - /* Prepare the overlapped structure. */ - memset(&(req->overlapped), 0, sizeof(req->overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - assert(req->event_handle); - req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); - } - - flags = 0; - result = WSARecv(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - &req->overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Process the req without IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - req->overlapped.InternalHigh = bytes; - handle->reqs_pending++; - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* The req will be processed with IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - req->wait_handle == INVALID_HANDLE_VALUE && - !RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_completion, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - } -} - - -int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { - uv_loop_t* loop = handle->loop; - unsigned int i, simultaneous_accepts; - uv_tcp_accept_t* req; - int err; - - assert(backlog > 0); - - if (handle->flags & UV_HANDLE_LISTENING) { - handle->connection_cb = cb; - } - - if (handle->flags & UV_HANDLE_READING) { - return WSAEISCONN; - } - - if (handle->flags & UV_HANDLE_BIND_ERROR) { - return handle->bind_error; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - err = uv_tcp_try_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - 0); - if (err) - return err; - } - - if (!handle->func_acceptex) { - if (!uv_get_acceptex_function(handle->socket, &handle->func_acceptex)) { - return WSAEAFNOSUPPORT; - } - } - - if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) && - listen(handle->socket, backlog) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - handle->flags |= UV_HANDLE_LISTENING; - handle->connection_cb = cb; - INCREASE_ACTIVE_COUNT(loop, handle); - - simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1 - : uv_simultaneous_server_accepts; - - if(!handle->accept_reqs) { - handle->accept_reqs = (uv_tcp_accept_t*) - malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t)); - if (!handle->accept_reqs) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - for (i = 0; i < simultaneous_accepts; i++) { - req = &handle->accept_reqs[i]; - uv_req_init(loop, (uv_req_t*)req); - req->type = UV_ACCEPT; - req->accept_socket = INVALID_SOCKET; - req->data = handle; - - req->wait_handle = INVALID_HANDLE_VALUE; - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } else { - req->event_handle = NULL; - } - - uv_tcp_queue_accept(handle, req); - } - - /* Initialize other unused requests too, because uv_tcp_endgame */ - /* doesn't know how how many requests were intialized, so it will */ - /* try to clean up {uv_simultaneous_server_accepts} requests. */ - for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { - req = &handle->accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; - req->accept_socket = INVALID_SOCKET; - req->data = handle; - req->wait_handle = INVALID_HANDLE_VALUE; - } - } - - return 0; -} - - -int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) { - uv_loop_t* loop = server->loop; - int err = 0; - int family; - - uv_tcp_accept_t* req = server->pending_accepts; - - if (!req) { - /* No valid connections found, so we error out. */ - return WSAEWOULDBLOCK; - } - - if (req->accept_socket == INVALID_SOCKET) { - return WSAENOTCONN; - } - - if (server->flags & UV_HANDLE_IPV6) { - family = AF_INET6; - } else { - family = AF_INET; - } - - err = uv_tcp_set_socket(client->loop, - client, - req->accept_socket, - family, - 0); - if (err) { - closesocket(req->accept_socket); - } else { - uv_connection_init((uv_stream_t*) client); - /* AcceptEx() implicitly binds the accepted socket. */ - client->flags |= UV_HANDLE_BOUND | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - } - - /* Prepare the req to pick up a new connection */ - server->pending_accepts = req->next_pending; - req->next_pending = NULL; - req->accept_socket = INVALID_SOCKET; - - if (!(server->flags & UV__HANDLE_CLOSING)) { - /* Check if we're in a middle of changing the number of pending accepts. */ - if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) { - uv_tcp_queue_accept(server, req); - } else { - /* We better be switching to a single pending accept. */ - assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT); - - server->processed_accepts++; - - if (server->processed_accepts >= uv_simultaneous_server_accepts) { - server->processed_accepts = 0; - /* - * All previously queued accept requests are now processed. - * We now switch to queueing just a single accept. - */ - uv_tcp_queue_accept(server, &server->accept_reqs[0]); - server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING; - server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; - } - } - } - - loop->active_tcp_streams++; - - return err; -} - - -int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - uv_loop_t* loop = handle->loop; - - handle->flags |= UV_HANDLE_READING; - handle->read_cb = read_cb; - handle->alloc_cb = alloc_cb; - INCREASE_ACTIVE_COUNT(loop, handle); - - /* If reading was stopped and then started again, there could still be a */ - /* read request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) { - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - !handle->read_req.event_handle) { - handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!handle->read_req.event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } - uv_tcp_queue_read(loop, handle); - } - - return 0; -} - - -static int uv_tcp_try_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb) { - uv_loop_t* loop = handle->loop; - const struct sockaddr* bind_addr; - BOOL success; - DWORD bytes; - int err; - - if (handle->flags & UV_HANDLE_BIND_ERROR) { - return handle->bind_error; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - if (addrlen == sizeof(uv_addr_ip4_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; - } else if (addrlen == sizeof(uv_addr_ip6_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; - } else { - abort(); - } - err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0); - if (err) - return err; - } - - if (!handle->func_connectex) { - if (!uv_get_connectex_function(handle->socket, &handle->func_connectex)) { - return WSAEAFNOSUPPORT; - } - } - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - - success = handle->func_connectex(handle->socket, - addr, - addrlen, - NULL, - 0, - &bytes, - &req->overlapped); - - if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { - /* Process the req without IOCP. */ - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(success)) { - /* The req will be processed with IOCP. */ - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - } else { - return WSAGetLastError(); - } - - return 0; -} - - -int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, - int* namelen) { - int result; - - if (!(handle->flags & UV_HANDLE_BOUND)) { - return UV_EINVAL; - } - - if (handle->flags & UV_HANDLE_BIND_ERROR) { - return uv_translate_sys_error(handle->bind_error); - } - - result = getsockname(handle->socket, name, namelen); - if (result != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name, - int* namelen) { - int result; - - if (!(handle->flags & UV_HANDLE_BOUND)) { - return UV_EINVAL; - } - - if (handle->flags & UV_HANDLE_BIND_ERROR) { - return uv_translate_sys_error(handle->bind_error); - } - - result = getpeername(handle->socket, name, namelen); - if (result != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_tcp_write(uv_loop_t* loop, - uv_write_t* req, - uv_tcp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - int result; - DWORD bytes; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - - /* Prepare the overlapped structure. */ - memset(&(req->overlapped), 0, sizeof(req->overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); - req->wait_handle = INVALID_HANDLE_VALUE; - } - - result = WSASend(handle->socket, - (WSABUF*) bufs, - nbufs, - &bytes, - 0, - &req->overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Request completed immediately. */ - req->queued_bytes = 0; - handle->reqs_pending++; - handle->write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*) req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* Request queued by the kernel. */ - req->queued_bytes = uv_count_bufs(bufs, nbufs); - handle->reqs_pending++; - handle->write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - handle->write_queue_size += req->queued_bytes; - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - !RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_write_completion, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - } else { - /* Send failed due to an error. */ - return WSAGetLastError(); - } - - return 0; -} - - -void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_req_t* req) { - DWORD bytes, flags, err; - uv_buf_t buf; - - assert(handle->type == UV_TCP); - - handle->flags &= ~UV_HANDLE_READ_PENDING; - - if (!REQ_SUCCESS(req)) { - /* An error occurred doing the read. */ - if ((handle->flags & UV_HANDLE_READING) || - !(handle->flags & UV_HANDLE_ZERO_READ)) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - buf = (handle->flags & UV_HANDLE_ZERO_READ) ? - uv_buf_init(NULL, 0) : handle->read_buffer; - - err = GET_REQ_SOCK_ERROR(req); - - if (err == WSAECONNABORTED) { - /* - * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix. - */ - err = WSAECONNRESET; - } - - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(err), - &buf); - } - } else { - if (!(handle->flags & UV_HANDLE_ZERO_READ)) { - /* The read was done with a non-zero buffer length. */ - if (req->overlapped.InternalHigh > 0) { - /* Successful read */ - handle->read_cb((uv_stream_t*)handle, - req->overlapped.InternalHigh, - &handle->read_buffer); - /* Read again only if bytes == buf.len */ - if (req->overlapped.InternalHigh < handle->read_buffer.len) { - goto done; - } - } else { - /* Connection closed */ - if (handle->flags & UV_HANDLE_READING) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - } - handle->flags &= ~UV_HANDLE_READABLE; - - buf.base = 0; - buf.len = 0; - handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->read_buffer); - goto done; - } - } - - /* Do nonblocking reads until the buffer is empty */ - while (handle->flags & UV_HANDLE_READING) { - handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); - if (buf.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); - break; - } - assert(buf.base != NULL); - - flags = 0; - if (WSARecv(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - NULL, - NULL) != SOCKET_ERROR) { - if (bytes > 0) { - /* Successful read */ - handle->read_cb((uv_stream_t*)handle, bytes, &buf); - /* Read again only if bytes == buf.len */ - if (bytes < buf.len) { - break; - } - } else { - /* Connection closed */ - handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE); - DECREASE_ACTIVE_COUNT(loop, handle); - - handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf); - break; - } - } else { - err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - /* Read buffer was completely empty, report a 0-byte read. */ - handle->read_cb((uv_stream_t*)handle, 0, &buf); - } else { - /* Ouch! serious error. */ - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - - if (err == WSAECONNABORTED) { - /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with */ - /* Unix. */ - err = WSAECONNRESET; - } - - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(err), - &buf); - } - break; - } - } - -done: - /* Post another read if still reading and not closing. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_tcp_queue_read(loop, handle); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_write_t* req) { - int err; - - assert(handle->type == UV_TCP); - - assert(handle->write_queue_size >= req->queued_bytes); - handle->write_queue_size -= req->queued_bytes; - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - } - if (req->event_handle) { - CloseHandle(req->event_handle); - } - } - - if (req->cb) { - err = GET_REQ_SOCK_ERROR(req); - req->cb(req, uv_translate_sys_error(err)); - } - - handle->write_reqs_pending--; - if (handle->shutdown_req != NULL && - handle->write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_req_t* raw_req) { - uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req; - int err; - - assert(handle->type == UV_TCP); - - /* If handle->accepted_socket is not a valid socket, then */ - /* uv_queue_accept must have failed. This is a serious error. We stop */ - /* accepting connections and report this error to the connection */ - /* callback. */ - if (req->accept_socket == INVALID_SOCKET) { - if (handle->flags & UV_HANDLE_LISTENING) { - handle->flags &= ~UV_HANDLE_LISTENING; - DECREASE_ACTIVE_COUNT(loop, handle); - if (handle->connection_cb) { - err = GET_REQ_SOCK_ERROR(req); - handle->connection_cb((uv_stream_t*)handle, - uv_translate_sys_error(err)); - } - } - } else if (REQ_SUCCESS(req) && - setsockopt(req->accept_socket, - SOL_SOCKET, - SO_UPDATE_ACCEPT_CONTEXT, - (char*)&handle->socket, - sizeof(handle->socket)) == 0) { - req->next_pending = handle->pending_accepts; - handle->pending_accepts = req; - - /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */ - if (handle->connection_cb) { - handle->connection_cb((uv_stream_t*)handle, 0); - } - } else { - /* Error related to accepted socket is ignored because the server */ - /* socket may still be healthy. If the server socket is broken */ - /* uv_queue_accept will detect it. */ - closesocket(req->accept_socket); - req->accept_socket = INVALID_SOCKET; - if (handle->flags & UV_HANDLE_LISTENING) { - uv_tcp_queue_accept(handle, req); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_connect_t* req) { - int err; - - assert(handle->type == UV_TCP); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - err = 0; - if (REQ_SUCCESS(req)) { - 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++; - } else { - err = WSAGetLastError(); - } - } else { - err = GET_REQ_SOCK_ERROR(req); - } - req->cb(req, uv_translate_sys_error(err)); - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info, - int tcp_connection) { - int err; - - SOCKET socket = WSASocketW(AF_INET, - SOCK_STREAM, - IPPROTO_IP, - socket_protocol_info, - 0, - WSA_FLAG_OVERLAPPED); - - if (socket == INVALID_SOCKET) { - return WSAGetLastError(); - } - - if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) { - err = GetLastError(); - closesocket(socket); - return err; - } - - err = uv_tcp_set_socket(tcp->loop, - tcp, - socket, - socket_protocol_info->iAddressFamily, - 1); - if (err) { - closesocket(socket); - return err; - } - - if (tcp_connection) { - uv_connection_init((uv_stream_t*)tcp); - tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - } - - tcp->flags |= UV_HANDLE_BOUND; - tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET; - - tcp->loop->active_tcp_streams++; - return 0; -} - - -int uv_tcp_nodelay(uv_tcp_t* handle, int enable) { - int err; - - if (handle->socket != INVALID_SOCKET) { - err = uv__tcp_nodelay(handle, handle->socket, enable); - if (err) - return err; - } - - if (enable) { - handle->flags |= UV_HANDLE_TCP_NODELAY; - } else { - handle->flags &= ~UV_HANDLE_TCP_NODELAY; - } - - return 0; -} - - -int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { - int err; - - if (handle->socket != INVALID_SOCKET) { - err = uv__tcp_keepalive(handle, handle->socket, enable, delay); - if (err) - return err; - } - - if (enable) { - handle->flags |= UV_HANDLE_TCP_KEEPALIVE; - } else { - handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE; - } - - /* TODO: Store delay if handle->socket isn't created yet. */ - - return 0; -} - - -int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid, - LPWSAPROTOCOL_INFOW protocol_info) { - if (!(handle->flags & UV_HANDLE_CONNECTION)) { - /* - * We're about to share the socket with another process. Because - * this is a listening socket, we assume that the other process will - * be accepting connections on it. So, before sharing the socket - * with another process, we call listen here in the parent process. - */ - - if (!(handle->flags & UV_HANDLE_LISTENING)) { - if (!(handle->flags & UV_HANDLE_BOUND)) { - return ERROR_INVALID_PARAMETER; - } - - /* Report any deferred bind errors now. */ - if (handle->flags & UV_HANDLE_BIND_ERROR) { - return handle->bind_error; - } - - if (listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) { - return WSAGetLastError(); - } - } - } - - if (WSADuplicateSocketW(handle->socket, pid, protocol_info)) { - return WSAGetLastError(); - } - - handle->flags |= UV_HANDLE_SHARED_TCP_SOCKET; - - return 0; -} - - -int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { - if (handle->flags & UV_HANDLE_CONNECTION) { - return UV_EINVAL; - } - - /* Check if we're already in the desired mode. */ - if ((enable && !(handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) || - (!enable && handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) { - return 0; - } - - /* Don't allow switching from single pending accept to many. */ - if (enable) { - return UV_ENOTSUP; - } - - /* Check if we're in a middle of changing the number of pending accepts. */ - if (handle->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING) { - return 0; - } - - handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; - - /* Flip the changing flag if we have already queued multiple accepts. */ - if (handle->flags & UV_HANDLE_LISTENING) { - handle->flags |= UV_HANDLE_TCP_ACCEPT_STATE_CHANGING; - } - - return 0; -} - - -static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) { - SOCKET socket = tcp->socket; - int non_ifs_lsp; - - /* Check if we have any non-IFS LSPs stacked on top of TCP */ - non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 : - uv_tcp_non_ifs_lsp_ipv4; - - /* If there are non-ifs LSPs then try to obtain a base handle for the */ - /* socket. This will always fail on Windows XP/3k. */ - if (non_ifs_lsp) { - DWORD bytes; - if (WSAIoctl(socket, - SIO_BASE_HANDLE, - NULL, - 0, - &socket, - sizeof socket, - &bytes, - NULL, - NULL) != 0) { - /* Failed. We can't do CancelIo. */ - return -1; - } - } - - assert(socket != 0 && socket != INVALID_SOCKET); - - if (!CancelIo((HANDLE) socket)) { - return GetLastError(); - } - - /* It worked. */ - return 0; -} - - -void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) { - int close_socket = 1; - - if (tcp->flags & UV_HANDLE_READ_PENDING) { - /* In order for winsock to do a graceful close there must not be any */ - /* any pending reads, or the socket must be shut down for writing */ - if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) { - /* Just do shutdown on non-shared sockets, which ensures graceful close. */ - shutdown(tcp->socket, SD_SEND); - - } else if (uv_tcp_try_cancel_io(tcp) == 0) { - /* In case of a shared socket, we try to cancel all outstanding I/O, */ - /* If that works, don't close the socket yet - wait for the read req to */ - /* return and close the socket in uv_tcp_endgame. */ - close_socket = 0; - - } else { - /* When cancelling isn't possible - which could happen when an LSP is */ - /* present on an old Windows version, we will have to close the socket */ - /* with a read pending. That is not nice because trailing sent bytes */ - /* may not make it to the other side. */ - } - - } else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) && - tcp->accept_reqs != NULL) { - /* Under normal circumstances closesocket() will ensure that all pending */ - /* accept reqs are canceled. However, when the socket is shared the */ - /* presence of another reference to the socket in another process will */ - /* keep the accept reqs going, so we have to ensure that these are */ - /* canceled. */ - if (uv_tcp_try_cancel_io(tcp) != 0) { - /* When cancellation is not possible, there is another option: we can */ - /* close the incoming sockets, which will also cancel the accept */ - /* operations. However this is not cool because we might inadvertedly */ - /* close a socket that just accepted a new connection, which will */ - /* cause the connection to be aborted. */ - unsigned int i; - for (i = 0; i < uv_simultaneous_server_accepts; i++) { - uv_tcp_accept_t* req = &tcp->accept_reqs[i]; - if (req->accept_socket != INVALID_SOCKET && - !HasOverlappedIoCompleted(&req->overlapped)) { - closesocket(req->accept_socket); - req->accept_socket = INVALID_SOCKET; - } - } - } - } - - if (tcp->flags & UV_HANDLE_READING) { - tcp->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, tcp); - } - - if (tcp->flags & UV_HANDLE_LISTENING) { - tcp->flags &= ~UV_HANDLE_LISTENING; - DECREASE_ACTIVE_COUNT(loop, tcp); - } - - if (close_socket) { - closesocket(tcp->socket); - tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; - } - - tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); - uv__handle_closing(tcp); - - if (tcp->reqs_pending == 0) { - uv_want_endgame(tcp->loop, (uv_handle_t*)tcp); - } -} - - -int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { - WSAPROTOCOL_INFOW protocol_info; - int opt_len; - int err; - - /* Detect the address family of the socket. */ - opt_len = (int) sizeof protocol_info; - if (getsockopt(sock, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) { - return uv_translate_sys_error(GetLastError()); - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) { - return uv_translate_sys_error(GetLastError()); - } - - err = uv_tcp_set_socket(handle->loop, - handle, - sock, - protocol_info.iAddressFamily, - 1); - if (err) { - return uv_translate_sys_error(err); - } - - return 0; -} - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__tcp_bind(uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - - err = uv_tcp_try_bind(handle, addr, addrlen, flags); - if (err) - return uv_translate_sys_error(err); - - return 0; -} - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb) { - int err; - - err = uv_tcp_try_connect(req, handle, addr, addrlen, cb); - if (err) - return uv_translate_sys_error(err); - - return 0; -} diff --git a/third-party/libuv/src/win/thread.c b/third-party/libuv/src/win/thread.c deleted file mode 100644 index 5178f8f9ab..0000000000 --- a/third-party/libuv/src/win/thread.c +++ /dev/null @@ -1,716 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <limits.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" - - -#define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != NULL) -#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL) - -#ifdef _MSC_VER /* msvc */ -# define inline __inline -# define NOINLINE __declspec (noinline) -#else /* gcc */ -# define inline inline -# define NOINLINE __attribute__ ((noinline)) -#endif - - -inline static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock); -inline static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock); -inline static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock); -inline static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock); -inline static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock); -inline static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock); -inline static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock); -inline static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock); - -inline static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock); -inline static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock); -inline static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock); -inline static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock); -inline static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock); -inline static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock); -inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock); -inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock); - - -inline static int uv_cond_fallback_init(uv_cond_t* cond); -inline static void uv_cond_fallback_destroy(uv_cond_t* cond); -inline static void uv_cond_fallback_signal(uv_cond_t* cond); -inline static void uv_cond_fallback_broadcast(uv_cond_t* cond); -inline static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex); -inline static int uv_cond_fallback_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout); - -inline static int uv_cond_condvar_init(uv_cond_t* cond); -inline static void uv_cond_condvar_destroy(uv_cond_t* cond); -inline static void uv_cond_condvar_signal(uv_cond_t* cond); -inline static void uv_cond_condvar_broadcast(uv_cond_t* cond); -inline static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex); -inline static int uv_cond_condvar_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout); - - -static NOINLINE void uv__once_inner(uv_once_t* guard, - void (*callback)(void)) { - DWORD result; - HANDLE existing_event, created_event; - - created_event = CreateEvent(NULL, 1, 0, NULL); - if (created_event == 0) { - /* Could fail in a low-memory situation? */ - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - existing_event = InterlockedCompareExchangePointer(&guard->event, - created_event, - NULL); - - if (existing_event == NULL) { - /* We won the race */ - callback(); - - result = SetEvent(created_event); - assert(result); - guard->ran = 1; - - } else { - /* We lost the race. Destroy the event we created and wait for the */ - /* existing one todv become signaled. */ - CloseHandle(created_event); - result = WaitForSingleObject(existing_event, INFINITE); - assert(result == WAIT_OBJECT_0); - } -} - - -void uv_once(uv_once_t* guard, void (*callback)(void)) { - /* Fast case - avoid WaitForSingleObject. */ - if (guard->ran) { - return; - } - - uv__once_inner(guard, callback); -} - - -int uv_thread_join(uv_thread_t *tid) { - if (WaitForSingleObject(*tid, INFINITE)) - return uv_translate_sys_error(GetLastError()); - else { - CloseHandle(*tid); - *tid = 0; - return 0; - } -} - - -int uv_mutex_init(uv_mutex_t* mutex) { - InitializeCriticalSection(mutex); - return 0; -} - - -void uv_mutex_destroy(uv_mutex_t* mutex) { - DeleteCriticalSection(mutex); -} - - -void uv_mutex_lock(uv_mutex_t* mutex) { - EnterCriticalSection(mutex); -} - - -int uv_mutex_trylock(uv_mutex_t* mutex) { - if (TryEnterCriticalSection(mutex)) - return 0; - else - return UV_EAGAIN; -} - - -void uv_mutex_unlock(uv_mutex_t* mutex) { - LeaveCriticalSection(mutex); -} - - -int uv_rwlock_init(uv_rwlock_t* rwlock) { - uv__once_init(); - - if (HAVE_SRWLOCK_API()) - return uv__rwlock_srwlock_init(rwlock); - else - return uv__rwlock_fallback_init(rwlock); -} - - -void uv_rwlock_destroy(uv_rwlock_t* rwlock) { - if (HAVE_SRWLOCK_API()) - uv__rwlock_srwlock_destroy(rwlock); - else - uv__rwlock_fallback_destroy(rwlock); -} - - -void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { - if (HAVE_SRWLOCK_API()) - uv__rwlock_srwlock_rdlock(rwlock); - else - uv__rwlock_fallback_rdlock(rwlock); -} - - -int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { - if (HAVE_SRWLOCK_API()) - return uv__rwlock_srwlock_tryrdlock(rwlock); - else - return uv__rwlock_fallback_tryrdlock(rwlock); -} - - -void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { - if (HAVE_SRWLOCK_API()) - uv__rwlock_srwlock_rdunlock(rwlock); - else - uv__rwlock_fallback_rdunlock(rwlock); -} - - -void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { - if (HAVE_SRWLOCK_API()) - uv__rwlock_srwlock_wrlock(rwlock); - else - uv__rwlock_fallback_wrlock(rwlock); -} - - -int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { - if (HAVE_SRWLOCK_API()) - return uv__rwlock_srwlock_trywrlock(rwlock); - else - return uv__rwlock_fallback_trywrlock(rwlock); -} - - -void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { - if (HAVE_SRWLOCK_API()) - uv__rwlock_srwlock_wrunlock(rwlock); - else - uv__rwlock_fallback_wrunlock(rwlock); -} - - -int uv_sem_init(uv_sem_t* sem, unsigned int value) { - *sem = CreateSemaphore(NULL, value, INT_MAX, NULL); - if (*sem == NULL) - return uv_translate_sys_error(GetLastError()); - else - return 0; -} - - -void uv_sem_destroy(uv_sem_t* sem) { - if (!CloseHandle(*sem)) - abort(); -} - - -void uv_sem_post(uv_sem_t* sem) { - if (!ReleaseSemaphore(*sem, 1, NULL)) - abort(); -} - - -void uv_sem_wait(uv_sem_t* sem) { - if (WaitForSingleObject(*sem, INFINITE) != WAIT_OBJECT_0) - abort(); -} - - -int uv_sem_trywait(uv_sem_t* sem) { - DWORD r = WaitForSingleObject(*sem, 0); - - if (r == WAIT_OBJECT_0) - return 0; - - if (r == WAIT_TIMEOUT) - return UV_EAGAIN; - - abort(); - return -1; /* Satisfy the compiler. */ -} - - -inline static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock) { - pInitializeSRWLock(&rwlock->srwlock_); - return 0; -} - - -inline static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock) { - (void) rwlock; -} - - -inline static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock) { - pAcquireSRWLockShared(&rwlock->srwlock_); -} - - -inline static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock) { - if (pTryAcquireSRWLockShared(&rwlock->srwlock_)) - return 0; - else - return UV_EBUSY; /* TODO(bnoordhuis) EAGAIN when owned by this thread. */ -} - - -inline static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock) { - pReleaseSRWLockShared(&rwlock->srwlock_); -} - - -inline static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock) { - pAcquireSRWLockExclusive(&rwlock->srwlock_); -} - - -inline static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock) { - if (pTryAcquireSRWLockExclusive(&rwlock->srwlock_)) - return 0; - else - return UV_EBUSY; /* TODO(bnoordhuis) EAGAIN when owned by this thread. */ -} - - -inline static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock) { - pReleaseSRWLockExclusive(&rwlock->srwlock_); -} - - -inline static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock) { - int err; - - err = uv_mutex_init(&rwlock->fallback_.read_mutex_); - if (err) - return err; - - err = uv_mutex_init(&rwlock->fallback_.write_mutex_); - if (err) { - uv_mutex_destroy(&rwlock->fallback_.read_mutex_); - return err; - } - - rwlock->fallback_.num_readers_ = 0; - - return 0; -} - - -inline static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock) { - uv_mutex_destroy(&rwlock->fallback_.read_mutex_); - uv_mutex_destroy(&rwlock->fallback_.write_mutex_); -} - - -inline static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock) { - uv_mutex_lock(&rwlock->fallback_.read_mutex_); - - if (++rwlock->fallback_.num_readers_ == 1) - uv_mutex_lock(&rwlock->fallback_.write_mutex_); - - uv_mutex_unlock(&rwlock->fallback_.read_mutex_); -} - - -inline static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock) { - int err; - - err = uv_mutex_trylock(&rwlock->fallback_.read_mutex_); - if (err) - goto out; - - err = 0; - if (rwlock->fallback_.num_readers_ == 0) - err = uv_mutex_trylock(&rwlock->fallback_.write_mutex_); - - if (err == 0) - rwlock->fallback_.num_readers_++; - - uv_mutex_unlock(&rwlock->fallback_.read_mutex_); - -out: - return err; -} - - -inline static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock) { - uv_mutex_lock(&rwlock->fallback_.read_mutex_); - - if (--rwlock->fallback_.num_readers_ == 0) - uv_mutex_unlock(&rwlock->fallback_.write_mutex_); - - uv_mutex_unlock(&rwlock->fallback_.read_mutex_); -} - - -inline static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock) { - uv_mutex_lock(&rwlock->fallback_.write_mutex_); -} - - -inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock) { - return uv_mutex_trylock(&rwlock->fallback_.write_mutex_); -} - - -inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock) { - uv_mutex_unlock(&rwlock->fallback_.write_mutex_); -} - - - -/* This condition variable implementation is based on the SetEvent solution - * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html - * We could not use the SignalObjectAndWait solution (section 3.4) because - * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and - * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs. - */ - -inline static int uv_cond_fallback_init(uv_cond_t* cond) { - int err; - - /* Initialize the count to 0. */ - cond->fallback.waiters_count = 0; - - InitializeCriticalSection(&cond->fallback.waiters_count_lock); - - /* Create an auto-reset event. */ - cond->fallback.signal_event = CreateEvent(NULL, /* no security */ - FALSE, /* auto-reset event */ - FALSE, /* non-signaled initially */ - NULL); /* unnamed */ - if (!cond->fallback.signal_event) { - err = GetLastError(); - goto error2; - } - - /* Create a manual-reset event. */ - cond->fallback.broadcast_event = CreateEvent(NULL, /* no security */ - TRUE, /* manual-reset */ - FALSE, /* non-signaled */ - NULL); /* unnamed */ - if (!cond->fallback.broadcast_event) { - err = GetLastError(); - goto error; - } - - return 0; - -error: - CloseHandle(cond->fallback.signal_event); -error2: - DeleteCriticalSection(&cond->fallback.waiters_count_lock); - return uv_translate_sys_error(err); -} - - -inline static int uv_cond_condvar_init(uv_cond_t* cond) { - pInitializeConditionVariable(&cond->cond_var); - return 0; -} - - -int uv_cond_init(uv_cond_t* cond) { - uv__once_init(); - - if (HAVE_CONDVAR_API()) - return uv_cond_condvar_init(cond); - else - return uv_cond_fallback_init(cond); -} - - -inline static void uv_cond_fallback_destroy(uv_cond_t* cond) { - if (!CloseHandle(cond->fallback.broadcast_event)) - abort(); - if (!CloseHandle(cond->fallback.signal_event)) - abort(); - DeleteCriticalSection(&cond->fallback.waiters_count_lock); -} - - -inline static void uv_cond_condvar_destroy(uv_cond_t* cond) { - /* nothing to do */ -} - - -void uv_cond_destroy(uv_cond_t* cond) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_destroy(cond); - else - uv_cond_fallback_destroy(cond); -} - - -inline static void uv_cond_fallback_signal(uv_cond_t* cond) { - int have_waiters; - - /* Avoid race conditions. */ - EnterCriticalSection(&cond->fallback.waiters_count_lock); - have_waiters = cond->fallback.waiters_count > 0; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - if (have_waiters) - SetEvent(cond->fallback.signal_event); -} - - -inline static void uv_cond_condvar_signal(uv_cond_t* cond) { - pWakeConditionVariable(&cond->cond_var); -} - - -void uv_cond_signal(uv_cond_t* cond) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_signal(cond); - else - uv_cond_fallback_signal(cond); -} - - -inline static void uv_cond_fallback_broadcast(uv_cond_t* cond) { - int have_waiters; - - /* Avoid race conditions. */ - EnterCriticalSection(&cond->fallback.waiters_count_lock); - have_waiters = cond->fallback.waiters_count > 0; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - if (have_waiters) - SetEvent(cond->fallback.broadcast_event); -} - - -inline static void uv_cond_condvar_broadcast(uv_cond_t* cond) { - pWakeAllConditionVariable(&cond->cond_var); -} - - -void uv_cond_broadcast(uv_cond_t* cond) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_broadcast(cond); - else - uv_cond_fallback_broadcast(cond); -} - - -inline int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex, - DWORD dwMilliseconds) { - DWORD result; - int last_waiter; - HANDLE handles[2] = { - cond->fallback.signal_event, - cond->fallback.broadcast_event - }; - - /* Avoid race conditions. */ - EnterCriticalSection(&cond->fallback.waiters_count_lock); - cond->fallback.waiters_count++; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - /* It's ok to release the <mutex> here since Win32 manual-reset events */ - /* maintain state when used with <SetEvent>. This avoids the "lost wakeup" */ - /* bug. */ - uv_mutex_unlock(mutex); - - /* Wait for either event to become signaled due to <uv_cond_signal> being */ - /* called or <uv_cond_broadcast> being called. */ - result = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds); - - EnterCriticalSection(&cond->fallback.waiters_count_lock); - cond->fallback.waiters_count--; - last_waiter = result == WAIT_OBJECT_0 + 1 - && cond->fallback.waiters_count == 0; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - /* Some thread called <pthread_cond_broadcast>. */ - if (last_waiter) { - /* We're the last waiter to be notified or to stop waiting, so reset the */ - /* the manual-reset event. */ - ResetEvent(cond->fallback.broadcast_event); - } - - /* Reacquire the <mutex>. */ - uv_mutex_lock(mutex); - - if (result == WAIT_OBJECT_0 || result == WAIT_OBJECT_0 + 1) - return 0; - - if (result == WAIT_TIMEOUT) - return UV_ETIMEDOUT; - - abort(); - return -1; /* Satisfy the compiler. */ -} - - -inline static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (uv_cond_wait_helper(cond, mutex, INFINITE)) - abort(); -} - - -inline static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE)) - abort(); -} - - -void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_wait(cond, mutex); - else - uv_cond_fallback_wait(cond, mutex); -} - - -inline static int uv_cond_fallback_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout) { - return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6)); -} - - -inline static int uv_cond_condvar_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout) { - if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6))) - return 0; - if (GetLastError() != ERROR_TIMEOUT) - abort(); - return UV_ETIMEDOUT; -} - - -int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, - uint64_t timeout) { - if (HAVE_CONDVAR_API()) - return uv_cond_condvar_timedwait(cond, mutex, timeout); - else - return uv_cond_fallback_timedwait(cond, mutex, timeout); -} - - -int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { - int err; - - barrier->n = count; - barrier->count = 0; - - err = uv_mutex_init(&barrier->mutex); - if (err) - return err; - - err = uv_sem_init(&barrier->turnstile1, 0); - if (err) - goto error2; - - err = uv_sem_init(&barrier->turnstile2, 1); - if (err) - goto error; - - return 0; - -error: - uv_sem_destroy(&barrier->turnstile1); -error2: - uv_mutex_destroy(&barrier->mutex); - return err; - -} - - -void uv_barrier_destroy(uv_barrier_t* barrier) { - uv_sem_destroy(&barrier->turnstile2); - uv_sem_destroy(&barrier->turnstile1); - uv_mutex_destroy(&barrier->mutex); -} - - -void uv_barrier_wait(uv_barrier_t* barrier) { - uv_mutex_lock(&barrier->mutex); - if (++barrier->count == barrier->n) { - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile1); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile1); - - uv_mutex_lock(&barrier->mutex); - if (--barrier->count == 0) { - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile2); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile2); -} - - -int uv_key_create(uv_key_t* key) { - key->tls_index = TlsAlloc(); - if (key->tls_index == TLS_OUT_OF_INDEXES) - return UV_ENOMEM; - return 0; -} - - -void uv_key_delete(uv_key_t* key) { - if (TlsFree(key->tls_index) == FALSE) - abort(); - key->tls_index = TLS_OUT_OF_INDEXES; -} - - -void* uv_key_get(uv_key_t* key) { - void* value; - - value = TlsGetValue(key->tls_index); - if (value == NULL) - if (GetLastError() != ERROR_SUCCESS) - abort(); - - return value; -} - - -void uv_key_set(uv_key_t* key, void* value) { - if (TlsSetValue(key->tls_index, value) == FALSE) - abort(); -} diff --git a/third-party/libuv/src/win/threadpool.c b/third-party/libuv/src/win/threadpool.c deleted file mode 100644 index 9539844c66..0000000000 --- a/third-party/libuv/src/win/threadpool.c +++ /dev/null @@ -1,81 +0,0 @@ -/* 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 - * 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 <assert.h> - -#include "uv.h" -#include "internal.h" -#include "req-inl.h" - - -static void uv_work_req_init(uv_loop_t* loop, uv_work_t* req, - uv_work_cb work_cb, uv_after_work_cb after_work_cb) { - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WORK; - req->loop = loop; - req->work_cb = work_cb; - req->after_work_cb = after_work_cb; - memset(&req->overlapped, 0, sizeof(req->overlapped)); -} - - -static DWORD WINAPI uv_work_thread_proc(void* parameter) { - uv_work_t* req = (uv_work_t*)parameter; - uv_loop_t* loop = req->loop; - - assert(req != NULL); - assert(req->type == UV_WORK); - assert(req->work_cb); - - req->work_cb(req); - - POST_COMPLETION_FOR_REQ(loop, req); - - return 0; -} - - -int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb, - uv_after_work_cb after_work_cb) { - if (work_cb == NULL) - return UV_EINVAL; - - uv_work_req_init(loop, req, work_cb, after_work_cb); - - if (!QueueUserWorkItem(&uv_work_thread_proc, req, WT_EXECUTELONGFUNCTION)) { - return uv_translate_sys_error(GetLastError()); - } - - uv__req_register(loop, req); - return 0; -} - - -int uv_cancel(uv_req_t* req) { - return UV_ENOSYS; -} - - -void uv_process_work_req(uv_loop_t* loop, uv_work_t* req) { - uv__req_unregister(loop, req); - if(req->after_work_cb) - req->after_work_cb(req, 0); -} diff --git a/third-party/libuv/src/win/timer.c b/third-party/libuv/src/win/timer.c deleted file mode 100644 index 6c53ea37e0..0000000000 --- a/third-party/libuv/src/win/timer.c +++ /dev/null @@ -1,254 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <limits.h> - -#include "uv.h" -#include "internal.h" -#include "tree.h" -#include "handle-inl.h" - - -void uv_update_time(uv_loop_t* loop) { - DWORD ticks; - ULARGE_INTEGER time; - - ticks = GetTickCount(); - - time.QuadPart = loop->time; - - /* GetTickCount() can conceivably wrap around, so when the current tick */ - /* count is lower than the last tick count, we'll assume it has wrapped. */ - /* uv_poll must make sure that the timer can never overflow more than */ - /* once between two subsequent uv_update_time calls. */ - time.LowPart = ticks; - if (ticks < loop->last_tick_count) - time.HighPart++; - - /* Remember the last tick count. */ - loop->last_tick_count = ticks; - - /* The GetTickCount() resolution isn't too good. Sometimes it'll happen */ - /* that GetQueuedCompletionStatus() or GetQueuedCompletionStatusEx() has */ - /* waited for a couple of ms but this is not reflected in the GetTickCount */ - /* result yet. Therefore whenever GetQueuedCompletionStatus times out */ - /* we'll add the number of ms that it has waited to the current loop time. */ - /* When that happened the loop time might be a little ms farther than what */ - /* we've just computed, and we shouldn't update the loop time. */ - if (loop->time < time.QuadPart) - loop->time = time.QuadPart; -} - - -void uv__time_forward(uv_loop_t* loop, uint64_t msecs) { - loop->time += msecs; -} - - -static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) { - if (a->due < b->due) - return -1; - if (a->due > b->due) - return 1; - /* - * compare start_id when both has the same due. start_id is - * allocated with loop->timer_counter in uv_timer_start(). - */ - if (a->start_id < b->start_id) - return -1; - if (a->start_id > b->start_id) - return 1; - return 0; -} - - -RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare); - - -int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_TIMER); - handle->timer_cb = NULL; - handle->repeat = 0; - - return 0; -} - - -void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -static uint64_t get_clamped_due_time(uint64_t loop_time, uint64_t timeout) { - uint64_t clamped_timeout; - - clamped_timeout = loop_time + timeout; - if (clamped_timeout < timeout) - clamped_timeout = (uint64_t) -1; - - return clamped_timeout; -} - - -int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout, - uint64_t repeat) { - uv_loop_t* loop = handle->loop; - uv_timer_t* old; - - if (handle->flags & UV_HANDLE_ACTIVE) { - RB_REMOVE(uv_timer_tree_s, &loop->timers, handle); - } - - handle->timer_cb = timer_cb; - handle->due = get_clamped_due_time(loop->time, timeout); - handle->repeat = repeat; - handle->flags |= UV_HANDLE_ACTIVE; - uv__handle_start(handle); - - /* start_id is the second index to be compared in uv__timer_cmp() */ - handle->start_id = handle->loop->timer_counter++; - - old = RB_INSERT(uv_timer_tree_s, &loop->timers, handle); - assert(old == NULL); - - return 0; -} - - -int uv_timer_stop(uv_timer_t* handle) { - uv_loop_t* loop = handle->loop; - - if (!(handle->flags & UV_HANDLE_ACTIVE)) - return 0; - - RB_REMOVE(uv_timer_tree_s, &loop->timers, handle); - - handle->flags &= ~UV_HANDLE_ACTIVE; - uv__handle_stop(handle); - - return 0; -} - - -int uv_timer_again(uv_timer_t* handle) { - uv_loop_t* loop = handle->loop; - - /* If timer_cb is NULL that means that the timer was never started. */ - if (!handle->timer_cb) { - return UV_EINVAL; - } - - if (handle->flags & UV_HANDLE_ACTIVE) { - RB_REMOVE(uv_timer_tree_s, &loop->timers, handle); - handle->flags &= ~UV_HANDLE_ACTIVE; - uv__handle_stop(handle); - } - - if (handle->repeat) { - handle->due = get_clamped_due_time(loop->time, handle->repeat); - - if (RB_INSERT(uv_timer_tree_s, &loop->timers, handle) != NULL) { - uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT"); - } - - handle->flags |= UV_HANDLE_ACTIVE; - uv__handle_start(handle); - } - - return 0; -} - - -void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) { - assert(handle->type == UV_TIMER); - handle->repeat = repeat; -} - - -uint64_t uv_timer_get_repeat(const uv_timer_t* handle) { - assert(handle->type == UV_TIMER); - return handle->repeat; -} - - -DWORD uv_get_poll_timeout(uv_loop_t* loop) { - uv_timer_t* timer; - int64_t delta; - - /* Check if there are any running timers */ - timer = RB_MIN(uv_timer_tree_s, &loop->timers); - if (timer) { - uv_update_time(loop); - - delta = timer->due - loop->time; - if (delta >= UINT_MAX >> 1) { - /* A timeout value of UINT_MAX means infinite, so that's no good. But */ - /* more importantly, there's always the risk that GetTickCount wraps. */ - /* uv_update_time can detect this, but we must make sure that the */ - /* tick counter never overflows twice between two subsequent */ - /* uv_update_time calls. We do this by never sleeping more than half */ - /* the time it takes to wrap the counter - which is huge overkill, */ - /* but hey, it's not so bad to wake up every 25 days. */ - return UINT_MAX >> 1; - } else if (delta < 0) { - /* Negative timeout values are not allowed */ - return 0; - } else { - return (DWORD)delta; - } - } else { - /* No timers */ - return INFINITE; - } -} - - -void uv_process_timers(uv_loop_t* loop) { - uv_timer_t* timer; - - /* Call timer callbacks */ - for (timer = RB_MIN(uv_timer_tree_s, &loop->timers); - timer != NULL && timer->due <= loop->time; - timer = RB_MIN(uv_timer_tree_s, &loop->timers)) { - RB_REMOVE(uv_timer_tree_s, &loop->timers, timer); - - if (timer->repeat != 0) { - /* If it is a repeating timer, reschedule with repeat timeout. */ - timer->due = get_clamped_due_time(timer->due, timer->repeat); - if (timer->due < loop->time) { - timer->due = loop->time; - } - if (RB_INSERT(uv_timer_tree_s, &loop->timers, timer) != NULL) { - uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT"); - } - } else { - /* If non-repeating, mark the timer as inactive. */ - timer->flags &= ~UV_HANDLE_ACTIVE; - uv__handle_stop(timer); - } - - timer->timer_cb((uv_timer_t*) timer, 0); - } -} diff --git a/third-party/libuv/src/win/tty.c b/third-party/libuv/src/win/tty.c deleted file mode 100644 index 8855af350e..0000000000 --- a/third-party/libuv/src/win/tty.c +++ /dev/null @@ -1,1873 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <io.h> -#include <string.h> -#include <stdlib.h> - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include <stdint.h> -#endif - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -#define UNICODE_REPLACEMENT_CHARACTER (0xfffd) - -#define ANSI_NORMAL 0x00 -#define ANSI_ESCAPE_SEEN 0x02 -#define ANSI_CSI 0x04 -#define ANSI_ST_CONTROL 0x08 -#define ANSI_IGNORE 0x10 -#define ANSI_IN_ARG 0x20 -#define ANSI_IN_STRING 0x40 -#define ANSI_BACKSLASH_SEEN 0x80 - - -static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info); - - -/* Null uv_buf_t */ -static const uv_buf_t uv_null_buf_ = { 0, NULL }; - - -/* - * The console virtual window. - * - * Normally cursor movement in windows is relative to the console screen buffer, - * e.g. the application is allowed to overwrite the 'history'. This is very - * inconvenient, it makes absolute cursor movement pretty useless. There is - * also the concept of 'client rect' which is defined by the actual size of - * the console window and the scroll position of the screen buffer, but it's - * very volatile because it changes when the user scrolls. - * - * To make cursor movement behave sensibly we define a virtual window to which - * cursor movement is confined. The virtual window is always as wide as the - * console screen buffer, but it's height is defined by the size of the - * console window. The top of the virtual window aligns with the position - * of the caret when the first stdout/err handle is created, unless that would - * mean that it would extend beyond the bottom of the screen buffer - in that - * that case it's located as far down as possible. - * - * When the user writes a long text or many newlines, such that the output - * reaches beyond the bottom of the virtual window, the virtual window is - * shifted downwards, but not resized. - * - * Since all tty i/o happens on the same console, this window is shared - * between all stdout/stderr handles. - */ - -static int uv_tty_virtual_offset = -1; -static int uv_tty_virtual_height = -1; -static int uv_tty_virtual_width = -1; - -static CRITICAL_SECTION uv_tty_output_lock; - -static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE; - - -void uv_console_init() { - InitializeCriticalSection(&uv_tty_output_lock); -} - - -int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) { - HANDLE handle; - CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info; - - handle = (HANDLE) _get_osfhandle(fd); - if (handle == INVALID_HANDLE_VALUE) { - return UV_EBADF; - } - - if (!readable) { - /* Obtain the screen buffer info with the output handle. */ - if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) { - return uv_translate_sys_error(GetLastError()); - } - - /* Obtain the the tty_output_lock because the virtual window state is */ - /* shared between all uv_tty_t handles. */ - EnterCriticalSection(&uv_tty_output_lock); - - /* Store the global tty output handle. This handle is used by TTY read */ - /* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */ - /* is received. */ - uv_tty_output_handle = handle; - - uv_tty_update_virtual_window(&screen_buffer_info); - - LeaveCriticalSection(&uv_tty_output_lock); - } - - - uv_stream_init(loop, (uv_stream_t*) tty, UV_TTY); - uv_connection_init((uv_stream_t*) tty); - - tty->handle = handle; - tty->reqs_pending = 0; - tty->flags |= UV_HANDLE_BOUND; - - if (readable) { - /* Initialize TTY input specific fields. */ - tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE; - tty->read_line_handle = NULL; - tty->read_line_buffer = uv_null_buf_; - tty->read_raw_wait = NULL; - - /* Init keycode-to-vt100 mapper state. */ - tty->last_key_len = 0; - tty->last_key_offset = 0; - tty->last_utf16_high_surrogate = 0; - memset(&tty->last_input_record, 0, sizeof tty->last_input_record); - } else { - /* TTY output specific fields. */ - tty->flags |= UV_HANDLE_WRITABLE; - - /* Init utf8-to-utf16 conversion state. */ - tty->utf8_bytes_left = 0; - tty->utf8_codepoint = 0; - - /* Initialize eol conversion state */ - tty->previous_eol = 0; - - /* Init ANSI parser state. */ - tty->ansi_parser_state = ANSI_NORMAL; - } - - return 0; -} - - -int uv_tty_set_mode(uv_tty_t* tty, int mode) { - DWORD flags; - unsigned char was_reading; - uv_alloc_cb alloc_cb; - uv_read_cb read_cb; - int err; - - if (!(tty->flags & UV_HANDLE_TTY_READABLE)) { - return UV_EINVAL; - } - - if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) { - return 0; - } - - if (mode) { - /* Raw input */ - flags = ENABLE_WINDOW_INPUT; - } else { - /* Line-buffered mode. */ - flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; - } - - if (!SetConsoleMode(tty->handle, flags)) { - return uv_translate_sys_error(GetLastError()); - } - - /* If currently reading, stop, and restart reading. */ - if (tty->flags & UV_HANDLE_READING) { - was_reading = 1; - alloc_cb = tty->alloc_cb; - read_cb = tty->read_cb; - - if (was_reading) { - err = uv_tty_read_stop(tty); - if (err) { - return uv_translate_sys_error(err); - } - } - } else { - was_reading = 0; - } - - /* Update flag. */ - tty->flags &= ~UV_HANDLE_TTY_RAW; - tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0; - - /* If we just stopped reading, restart. */ - if (was_reading) { - err = uv_tty_read_start(tty, alloc_cb, read_cb); - if (err) { - return uv_translate_sys_error(err); - } - } - - return 0; -} - - -int uv_is_tty(uv_file file) { - DWORD result; - return GetConsoleMode((HANDLE) _get_osfhandle(file), &result) != 0; -} - - -int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { - CONSOLE_SCREEN_BUFFER_INFO info; - - if (!GetConsoleScreenBufferInfo(tty->handle, &info)) { - return uv_translate_sys_error(GetLastError()); - } - - EnterCriticalSection(&uv_tty_output_lock); - uv_tty_update_virtual_window(&info); - LeaveCriticalSection(&uv_tty_output_lock); - - *width = uv_tty_virtual_width; - *height = uv_tty_virtual_height; - - return 0; -} - - -static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) { - uv_loop_t* loop; - uv_tty_t* handle; - uv_req_t* req; - - assert(data); - assert(!didTimeout); - - req = (uv_req_t*) data; - handle = (uv_tty_t*) req->data; - loop = handle->loop; - - UnregisterWait(handle->read_raw_wait); - handle->read_raw_wait = NULL; - - SET_REQ_SUCCESS(req); - POST_COMPLETION_FOR_REQ(loop, req); -} - - -static void uv_tty_queue_read_raw(uv_loop_t* loop, uv_tty_t* handle) { - uv_read_t* req; - BOOL r; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); - - handle->read_line_buffer = uv_null_buf_; - - req = &handle->read_req; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - - r = RegisterWaitForSingleObject(&handle->read_raw_wait, - handle->handle, - uv_tty_post_raw_read, - (void*) req, - INFINITE, - WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); - if (!r) { - handle->read_raw_wait = NULL; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; -} - - -static DWORD CALLBACK uv_tty_line_read_thread(void* data) { - uv_loop_t* loop; - uv_tty_t* handle; - uv_req_t* req; - DWORD bytes, read_bytes; - - assert(data); - - req = (uv_req_t*) data; - handle = (uv_tty_t*) req->data; - loop = handle->loop; - - assert(handle->read_line_buffer.base != NULL); - assert(handle->read_line_buffer.len > 0); - - /* ReadConsole can't handle big buffers. */ - if (handle->read_line_buffer.len < 8192) { - bytes = handle->read_line_buffer.len; - } else { - bytes = 8192; - } - - /* Todo: Unicode */ - if (ReadConsoleA(handle->read_line_handle, - (void*) handle->read_line_buffer.base, - bytes, - &read_bytes, - NULL)) { - SET_REQ_SUCCESS(req); - req->overlapped.InternalHigh = read_bytes; - } else { - SET_REQ_ERROR(req, GetLastError()); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) { - uv_read_t* req; - BOOL r; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); - - req = &handle->read_req; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - - handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->read_line_buffer); - if (handle->read_line_buffer.len == 0) { - handle->read_cb((uv_stream_t*) handle, - UV_ENOBUFS, - &handle->read_line_buffer); - return; - } - assert(handle->read_line_buffer.base != NULL); - - /* Duplicate the console handle, so if we want to cancel the read, we can */ - /* just close this handle duplicate. */ - if (handle->read_line_handle == NULL) { - HANDLE this_process = GetCurrentProcess(); - r = DuplicateHandle(this_process, - handle->handle, - this_process, - &handle->read_line_handle, - 0, - 0, - DUPLICATE_SAME_ACCESS); - if (!r) { - handle->read_line_handle = NULL; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - goto out; - } - } - - r = QueueUserWorkItem(uv_tty_line_read_thread, - (void*) req, - WT_EXECUTELONGFUNCTION); - if (!r) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - - out: - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; -} - - -static void uv_tty_queue_read(uv_loop_t* loop, uv_tty_t* handle) { - if (handle->flags & UV_HANDLE_TTY_RAW) { - uv_tty_queue_read_raw(loop, handle); - } else { - uv_tty_queue_read_line(loop, handle); - } -} - - -static const char* get_vt100_fn_key(DWORD code, char shift, char ctrl, - size_t* len) { -#define VK_CASE(vk, normal_str, shift_str, ctrl_str, shift_ctrl_str) \ - case (vk): \ - if (shift && ctrl) { \ - *len = sizeof shift_ctrl_str; \ - return "\033" shift_ctrl_str; \ - } else if (shift) { \ - *len = sizeof shift_str ; \ - return "\033" shift_str; \ - } else if (ctrl) { \ - *len = sizeof ctrl_str; \ - return "\033" ctrl_str; \ - } else { \ - *len = sizeof normal_str; \ - return "\033" normal_str; \ - } - - switch (code) { - /* These mappings are the same as Cygwin's. Unmodified and alt-modified */ - /* keypad keys comply with linux console, modifiers comply with xterm */ - /* modifier usage. F1..f12 and shift-f1..f10 comply with linux console, */ - /* f6..f12 with and without modifiers comply with rxvt. */ - VK_CASE(VK_INSERT, "[2~", "[2;2~", "[2;5~", "[2;6~") - VK_CASE(VK_END, "[4~", "[4;2~", "[4;5~", "[4;6~") - VK_CASE(VK_DOWN, "[B", "[1;2B", "[1;5B", "[1;6B") - VK_CASE(VK_NEXT, "[6~", "[6;2~", "[6;5~", "[6;6~") - VK_CASE(VK_LEFT, "[D", "[1;2D", "[1;5D", "[1;6D") - VK_CASE(VK_CLEAR, "[G", "[1;2G", "[1;5G", "[1;6G") - VK_CASE(VK_RIGHT, "[C", "[1;2C", "[1;5C", "[1;6C") - VK_CASE(VK_UP, "[A", "[1;2A", "[1;5A", "[1;6A") - VK_CASE(VK_HOME, "[1~", "[1;2~", "[1;5~", "[1;6~") - VK_CASE(VK_PRIOR, "[5~", "[5;2~", "[5;5~", "[5;6~") - VK_CASE(VK_DELETE, "[3~", "[3;2~", "[3;5~", "[3;6~") - VK_CASE(VK_NUMPAD0, "[2~", "[2;2~", "[2;5~", "[2;6~") - VK_CASE(VK_NUMPAD1, "[4~", "[4;2~", "[4;5~", "[4;6~") - VK_CASE(VK_NUMPAD2, "[B", "[1;2B", "[1;5B", "[1;6B") - VK_CASE(VK_NUMPAD3, "[6~", "[6;2~", "[6;5~", "[6;6~") - VK_CASE(VK_NUMPAD4, "[D", "[1;2D", "[1;5D", "[1;6D") - VK_CASE(VK_NUMPAD5, "[G", "[1;2G", "[1;5G", "[1;6G") - VK_CASE(VK_NUMPAD6, "[C", "[1;2C", "[1;5C", "[1;6C") - VK_CASE(VK_NUMPAD7, "[A", "[1;2A", "[1;5A", "[1;6A") - VK_CASE(VK_NUMPAD8, "[1~", "[1;2~", "[1;5~", "[1;6~") - VK_CASE(VK_NUMPAD9, "[5~", "[5;2~", "[5;5~", "[5;6~") - VK_CASE(VK_DECIMAL, "[3~", "[3;2~", "[3;5~", "[3;6~") - VK_CASE(VK_F1, "[[A", "[23~", "[11^", "[23^" ) - VK_CASE(VK_F2, "[[B", "[24~", "[12^", "[24^" ) - VK_CASE(VK_F3, "[[C", "[25~", "[13^", "[25^" ) - VK_CASE(VK_F4, "[[D", "[26~", "[14^", "[26^" ) - VK_CASE(VK_F5, "[[E", "[28~", "[15^", "[28^" ) - VK_CASE(VK_F6, "[17~", "[29~", "[17^", "[29^" ) - VK_CASE(VK_F7, "[18~", "[31~", "[18^", "[31^" ) - VK_CASE(VK_F8, "[19~", "[32~", "[19^", "[32^" ) - VK_CASE(VK_F9, "[20~", "[33~", "[20^", "[33^" ) - VK_CASE(VK_F10, "[21~", "[34~", "[21^", "[34^" ) - VK_CASE(VK_F11, "[23~", "[23$", "[23^", "[23@" ) - VK_CASE(VK_F12, "[24~", "[24$", "[24^", "[24@" ) - - default: - *len = 0; - return NULL; - } -#undef VK_CASE -} - - -void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req) { - /* Shortcut for handle->last_input_record.Event.KeyEvent. */ -#define KEV handle->last_input_record.Event.KeyEvent - - DWORD records_left, records_read; - uv_buf_t buf; - off_t buf_used; - - assert(handle->type == UV_TTY); - assert(handle->flags & UV_HANDLE_TTY_READABLE); - handle->flags &= ~UV_HANDLE_READ_PENDING; - - if (!(handle->flags & UV_HANDLE_READING) || - !(handle->flags & UV_HANDLE_TTY_RAW)) { - goto out; - } - - if (!REQ_SUCCESS(req)) { - /* An error occurred while waiting for the event. */ - if ((handle->flags & UV_HANDLE_READING)) { - handle->flags &= ~UV_HANDLE_READING; - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(GET_REQ_ERROR(req)), - &uv_null_buf_); - } - goto out; - } - - /* Fetch the number of events */ - if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(GetLastError()), - &uv_null_buf_); - goto out; - } - - /* Windows sends a lot of events that we're not interested in, so buf */ - /* will be allocated on demand, when there's actually something to emit. */ - buf = uv_null_buf_; - buf_used = 0; - - while ((records_left > 0 || handle->last_key_len > 0) && - (handle->flags & UV_HANDLE_READING)) { - if (handle->last_key_len == 0) { - /* Read the next input record */ - if (!ReadConsoleInputW(handle->handle, - &handle->last_input_record, - 1, - &records_read)) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*) handle, - uv_translate_sys_error(GetLastError()), - &buf); - goto out; - } - records_left--; - - /* If the window was resized, recompute the virtual window size. This */ - /* will trigger a SIGWINCH signal if the window size changed in an */ - /* way that matters to libuv. */ - if (handle->last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) { - CONSOLE_SCREEN_BUFFER_INFO info; - - EnterCriticalSection(&uv_tty_output_lock); - - if (uv_tty_output_handle != INVALID_HANDLE_VALUE && - GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) { - uv_tty_update_virtual_window(&info); - } - - LeaveCriticalSection(&uv_tty_output_lock); - - continue; - } - - /* Ignore other events that are not key or resize events. */ - if (handle->last_input_record.EventType != KEY_EVENT) { - continue; - } - - /* Ignore keyup events, unless the left alt key was held and a valid */ - /* unicode character was emitted. */ - if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) || - KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) { - continue; - } - - /* Ignore keypresses to numpad number keys if the left alt is held */ - /* because the user is composing a character, or windows simulating */ - /* this. */ - if ((KEV.dwControlKeyState & LEFT_ALT_PRESSED) && - !(KEV.dwControlKeyState & ENHANCED_KEY) && - (KEV.wVirtualKeyCode == VK_INSERT || - KEV.wVirtualKeyCode == VK_END || - KEV.wVirtualKeyCode == VK_DOWN || - KEV.wVirtualKeyCode == VK_NEXT || - KEV.wVirtualKeyCode == VK_LEFT || - KEV.wVirtualKeyCode == VK_CLEAR || - KEV.wVirtualKeyCode == VK_RIGHT || - KEV.wVirtualKeyCode == VK_HOME || - KEV.wVirtualKeyCode == VK_UP || - KEV.wVirtualKeyCode == VK_PRIOR || - KEV.wVirtualKeyCode == VK_NUMPAD0 || - KEV.wVirtualKeyCode == VK_NUMPAD1 || - KEV.wVirtualKeyCode == VK_NUMPAD2 || - KEV.wVirtualKeyCode == VK_NUMPAD3 || - KEV.wVirtualKeyCode == VK_NUMPAD4 || - KEV.wVirtualKeyCode == VK_NUMPAD5 || - KEV.wVirtualKeyCode == VK_NUMPAD6 || - KEV.wVirtualKeyCode == VK_NUMPAD7 || - KEV.wVirtualKeyCode == VK_NUMPAD8 || - KEV.wVirtualKeyCode == VK_NUMPAD9)) { - continue; - } - - if (KEV.uChar.UnicodeChar != 0) { - int prefix_len, char_len; - - /* Character key pressed */ - if (KEV.uChar.UnicodeChar >= 0xD800 && - KEV.uChar.UnicodeChar < 0xDC00) { - /* UTF-16 high surrogate */ - handle->last_utf16_high_surrogate = KEV.uChar.UnicodeChar; - continue; - } - - /* Prefix with \u033 if alt was held, but alt was not used as part */ - /* a compose sequence. */ - if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) - && !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED | - RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) { - handle->last_key[0] = '\033'; - prefix_len = 1; - } else { - prefix_len = 0; - } - - if (KEV.uChar.UnicodeChar >= 0xDC00 && - KEV.uChar.UnicodeChar < 0xE000) { - /* UTF-16 surrogate pair */ - WCHAR utf16_buffer[2] = { handle->last_utf16_high_surrogate, - KEV.uChar.UnicodeChar}; - char_len = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - 2, - &handle->last_key[prefix_len], - sizeof handle->last_key, - NULL, - NULL); - } else { - /* Single UTF-16 character */ - char_len = WideCharToMultiByte(CP_UTF8, - 0, - &KEV.uChar.UnicodeChar, - 1, - &handle->last_key[prefix_len], - sizeof handle->last_key, - NULL, - NULL); - } - - /* Whatever happened, the last character wasn't a high surrogate. */ - handle->last_utf16_high_surrogate = 0; - - /* If the utf16 character(s) couldn't be converted something must */ - /* be wrong. */ - if (!char_len) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*) handle, - uv_translate_sys_error(GetLastError()), - &buf); - goto out; - } - - handle->last_key_len = (unsigned char) (prefix_len + char_len); - handle->last_key_offset = 0; - continue; - - } else { - /* Function key pressed */ - const char* vt100; - size_t prefix_len, vt100_len; - - vt100 = get_vt100_fn_key(KEV.wVirtualKeyCode, - !!(KEV.dwControlKeyState & SHIFT_PRESSED), - !!(KEV.dwControlKeyState & ( - LEFT_CTRL_PRESSED | - RIGHT_CTRL_PRESSED)), - &vt100_len); - - /* If we were unable to map to a vt100 sequence, just ignore. */ - if (!vt100) { - continue; - } - - /* Prefix with \x033 when the alt key was held. */ - if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) { - handle->last_key[0] = '\033'; - prefix_len = 1; - } else { - prefix_len = 0; - } - - /* Copy the vt100 sequence to the handle buffer. */ - assert(prefix_len + vt100_len < sizeof handle->last_key); - memcpy(&handle->last_key[prefix_len], vt100, vt100_len); - - handle->last_key_len = (unsigned char) (prefix_len + vt100_len); - handle->last_key_offset = 0; - continue; - } - } else { - /* Copy any bytes left from the last keypress to the user buffer. */ - if (handle->last_key_offset < handle->last_key_len) { - /* Allocate a buffer if needed */ - if (buf_used == 0) { - handle->alloc_cb((uv_handle_t*) handle, 1024, &buf); - if (buf.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); - goto out; - } - assert(buf.base != NULL); - } - - buf.base[buf_used++] = handle->last_key[handle->last_key_offset++]; - - /* If the buffer is full, emit it */ - if (buf_used == buf.len) { - handle->read_cb((uv_stream_t*) handle, buf_used, &buf); - buf = uv_null_buf_; - buf_used = 0; - } - - continue; - } - - /* Apply dwRepeat from the last input record. */ - if (--KEV.wRepeatCount > 0) { - handle->last_key_offset = 0; - continue; - } - - handle->last_key_len = 0; - continue; - } - } - - /* Send the buffer back to the user */ - if (buf_used > 0) { - handle->read_cb((uv_stream_t*) handle, buf_used, &buf); - } - - out: - /* Wait for more input events. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_tty_queue_read(loop, handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); - -#undef KEV -} - - - -void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req) { - uv_buf_t buf; - - assert(handle->type == UV_TTY); - assert(handle->flags & UV_HANDLE_TTY_READABLE); - - buf = handle->read_line_buffer; - - handle->flags &= ~UV_HANDLE_READ_PENDING; - handle->read_line_buffer = uv_null_buf_; - - if (!REQ_SUCCESS(req)) { - /* Read was not successful */ - if ((handle->flags & UV_HANDLE_READING) && - handle->read_line_handle != NULL) { - /* Real error */ - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*) handle, - uv_translate_sys_error(GET_REQ_ERROR(req)), - &buf); - } else { - /* The read was cancelled, or whatever we don't care */ - handle->read_cb((uv_stream_t*) handle, 0, &buf); - } - - } else { - /* Read successful */ - /* TODO: read unicode, convert to utf-8 */ - DWORD bytes = req->overlapped.InternalHigh; - handle->read_cb((uv_stream_t*) handle, bytes, &buf); - } - - /* Wait for more input events. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_tty_queue_read(loop, handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req) { - assert(handle->type == UV_TTY); - assert(handle->flags & UV_HANDLE_TTY_READABLE); - - /* If the read_line_buffer member is zero, it must have been an raw read. */ - /* Otherwise it was a line-buffered read. */ - /* FIXME: This is quite obscure. Use a flag or something. */ - if (handle->read_line_buffer.len == 0) { - uv_process_tty_read_raw_req(loop, handle, req); - } else { - uv_process_tty_read_line_req(loop, handle, req); - } -} - - -int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - uv_loop_t* loop = handle->loop; - - if (!(handle->flags & UV_HANDLE_TTY_READABLE)) { - return ERROR_INVALID_PARAMETER; - } - - handle->flags |= UV_HANDLE_READING; - INCREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb = read_cb; - handle->alloc_cb = alloc_cb; - - /* If reading was stopped and then started again, there could still be a */ - /* read request pending. */ - if (handle->flags & UV_HANDLE_READ_PENDING) { - return 0; - } - - /* Maybe the user stopped reading half-way while processing key events. */ - /* Short-circuit if this could be the case. */ - if (handle->last_key_len > 0) { - SET_REQ_SUCCESS(&handle->read_req); - uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req); - return 0; - } - - uv_tty_queue_read(loop, handle); - - return 0; -} - - -int uv_tty_read_stop(uv_tty_t* handle) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(handle->loop, handle); - - /* Cancel raw read */ - if ((handle->flags & UV_HANDLE_READ_PENDING) && - (handle->flags & UV_HANDLE_TTY_RAW)) { - /* Write some bullshit event to force the console wait to return. */ - INPUT_RECORD record; - DWORD written; - memset(&record, 0, sizeof record); - if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) { - return GetLastError(); - } - } - - /* Cancel line-buffered read */ - if (handle->read_line_handle != NULL) { - /* Closing this handle will cancel the ReadConsole operation */ - CloseHandle(handle->read_line_handle); - handle->read_line_handle = NULL; - } - - - return 0; -} - - -static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) { - int old_virtual_width = uv_tty_virtual_width; - int old_virtual_height = uv_tty_virtual_height; - - uv_tty_virtual_width = info->dwSize.X; - uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1; - - /* Recompute virtual window offset row. */ - if (uv_tty_virtual_offset == -1) { - uv_tty_virtual_offset = info->dwCursorPosition.Y; - } else if (uv_tty_virtual_offset < info->dwCursorPosition.Y - - uv_tty_virtual_height + 1) { - /* If suddenly find the cursor outside of the virtual window, it must */ - /* have somehow scrolled. Update the virtual window offset. */ - uv_tty_virtual_offset = info->dwCursorPosition.Y - - uv_tty_virtual_height + 1; - } - if (uv_tty_virtual_offset + uv_tty_virtual_height > info->dwSize.Y) { - uv_tty_virtual_offset = info->dwSize.Y - uv_tty_virtual_height; - } - if (uv_tty_virtual_offset < 0) { - uv_tty_virtual_offset = 0; - } - - /* If the virtual window size changed, emit a SIGWINCH signal. Don't emit */ - /* if this was the first time the virtual window size was computed. */ - if (old_virtual_width != -1 && old_virtual_height != -1 && - (uv_tty_virtual_width != old_virtual_width || - uv_tty_virtual_height != old_virtual_height)) { - uv__signal_dispatch(SIGWINCH); - } -} - - -static COORD uv_tty_make_real_coord(uv_tty_t* handle, - CONSOLE_SCREEN_BUFFER_INFO* info, int x, unsigned char x_relative, int y, - unsigned char y_relative) { - COORD result; - - uv_tty_update_virtual_window(info); - - /* Adjust y position */ - if (y_relative) { - y = info->dwCursorPosition.Y + y; - } else { - y = uv_tty_virtual_offset + y; - } - /* Clip y to virtual client rectangle */ - if (y < uv_tty_virtual_offset) { - y = uv_tty_virtual_offset; - } else if (y >= uv_tty_virtual_offset + uv_tty_virtual_height) { - y = uv_tty_virtual_offset + uv_tty_virtual_height - 1; - } - - /* Adjust x */ - if (x_relative) { - x = info->dwCursorPosition.X + x; - } - /* Clip x */ - if (x < 0) { - x = 0; - } else if (x >= uv_tty_virtual_width) { - x = uv_tty_virtual_width - 1; - } - - result.X = (unsigned short) x; - result.Y = (unsigned short) y; - return result; -} - - -static int uv_tty_emit_text(uv_tty_t* handle, WCHAR buffer[], DWORD length, - DWORD* error) { - DWORD written; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (!WriteConsoleW(handle->handle, - (void*) buffer, - length, - &written, - NULL)) { - *error = GetLastError(); - return -1; - } - - return 0; -} - - -static int uv_tty_move_caret(uv_tty_t* handle, int x, unsigned char x_relative, - int y, unsigned char y_relative, DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - COORD pos; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - retry: - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - } - - pos = uv_tty_make_real_coord(handle, &info, x, x_relative, y, y_relative); - - if (!SetConsoleCursorPosition(handle->handle, pos)) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - /* The console may be resized - retry */ - goto retry; - } else { - *error = GetLastError(); - return -1; - } - } - - return 0; -} - - -static int uv_tty_reset(uv_tty_t* handle, DWORD* error) { - const COORD origin = {0, 0}; - const WORD char_attrs = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - CONSOLE_SCREEN_BUFFER_INFO info; - DWORD count, written; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - /* Reset original text attributes. */ - if (!SetConsoleTextAttribute(handle->handle, char_attrs)) { - *error = GetLastError(); - return -1; - } - - /* Move the cursor position to (0, 0). */ - if (!SetConsoleCursorPosition(handle->handle, origin)) { - *error = GetLastError(); - return -1; - } - - /* Clear the screen buffer. */ - retry: - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - count = info.dwSize.X * info.dwSize.Y; - - if (!(FillConsoleOutputCharacterW(handle->handle, - L'\x20', - count, - origin, - &written) && - FillConsoleOutputAttribute(handle->handle, - char_attrs, - written, - origin, - &written))) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - /* The console may be resized - retry */ - goto retry; - } else { - *error = GetLastError(); - return -1; - } - } - - /* Move the virtual window up to the top. */ - uv_tty_virtual_offset = 0; - uv_tty_update_virtual_window(&info); - - return 0; -} - - -static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen, - DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - COORD start, end; - DWORD count, written; - - int x1, x2, y1, y2; - int x1r, x2r, y1r, y2r; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (dir == 0) { - /* Clear from current position */ - x1 = 0; - x1r = 1; - } else { - /* Clear from column 0 */ - x1 = 0; - x1r = 0; - } - - if (dir == 1) { - /* Clear to current position */ - x2 = 0; - x2r = 1; - } else { - /* Clear to end of row. We pretend the console is 65536 characters wide, */ - /* uv_tty_make_real_coord will clip it to the actual console width. */ - x2 = 0xffff; - x2r = 0; - } - - if (!entire_screen) { - /* Stay on our own row */ - y1 = y2 = 0; - y1r = y2r = 1; - } else { - /* Apply columns direction to row */ - y1 = x1; - y1r = x1r; - y2 = x2; - y2r = x2r; - } - - retry: - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - start = uv_tty_make_real_coord(handle, &info, x1, x1r, y1, y1r); - end = uv_tty_make_real_coord(handle, &info, x2, x2r, y2, y2r); - count = (end.Y * info.dwSize.X + end.X) - - (start.Y * info.dwSize.X + start.X) + 1; - - if (!(FillConsoleOutputCharacterW(handle->handle, - L'\x20', - count, - start, - &written) && - FillConsoleOutputAttribute(handle->handle, - info.wAttributes, - written, - start, - &written))) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - /* The console may be resized - retry */ - goto retry; - } else { - *error = GetLastError(); - return -1; - } - } - - return 0; -} - - -static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { - unsigned short argc = handle->ansi_csi_argc; - unsigned short* argv = handle->ansi_csi_argv; - int i; - CONSOLE_SCREEN_BUFFER_INFO info; - - char fg_color = -1, bg_color = -1; - char fg_bright = -1, bg_bright = -1; - - if (argc == 0) { - /* Reset mode */ - fg_color = 7; - bg_color = 0; - fg_bright = 0; - bg_bright = 0; - } - - for (i = 0; i < argc; i++) { - short arg = argv[i]; - - if (arg == 0) { - /* Reset mode */ - fg_color = 7; - bg_color = 0; - fg_bright = 0; - bg_bright = 0; - - } else if (arg == 1) { - /* Foreground bright on */ - fg_bright = 1; - - } else if (arg == 2) { - /* Both bright off */ - fg_bright = 0; - bg_bright = 0; - - } else if (arg == 5) { - /* Background bright on */ - bg_bright = 1; - - } else if (arg == 21 || arg == 22) { - /* Foreground bright off */ - fg_bright = 0; - - } else if (arg == 25) { - /* Background bright off */ - bg_bright = 0; - - } else if (arg >= 30 && arg <= 37) { - /* Set foreground color */ - fg_color = arg - 30; - - } else if (arg == 39) { - /* Default text color */ - fg_color = 7; - fg_bright = 0; - - } else if (arg >= 40 && arg <= 47) { - /* Set background color */ - bg_color = arg - 40; - - } else if (arg == 49) { - /* Default background color */ - bg_color = 0; - bg_bright = 0; - - } else if (arg >= 90 && arg <= 97) { - /* Set bold foreground color */ - fg_bright = 1; - fg_color = arg - 90; - - } else if (arg >= 100 && arg <= 107) { - /* Set bold background color */ - bg_bright = 1; - bg_color = arg - 100; - - } - } - - if (fg_color == -1 && bg_color == -1 && fg_bright == -1 && - bg_bright == -1) { - /* Nothing changed */ - return 0; - } - - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - if (fg_color != -1) { - info.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - if (fg_color & 1) info.wAttributes |= FOREGROUND_RED; - if (fg_color & 2) info.wAttributes |= FOREGROUND_GREEN; - if (fg_color & 4) info.wAttributes |= FOREGROUND_BLUE; - } - - if (fg_bright != -1) { - if (fg_bright) { - info.wAttributes |= FOREGROUND_INTENSITY; - } else { - info.wAttributes &= ~FOREGROUND_INTENSITY; - } - } - - if (bg_color != -1) { - info.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); - if (bg_color & 1) info.wAttributes |= BACKGROUND_RED; - if (bg_color & 2) info.wAttributes |= BACKGROUND_GREEN; - if (bg_color & 4) info.wAttributes |= BACKGROUND_BLUE; - } - - if (bg_bright != -1) { - if (bg_bright) { - info.wAttributes |= BACKGROUND_INTENSITY; - } else { - info.wAttributes &= ~BACKGROUND_INTENSITY; - } - } - - if (!SetConsoleTextAttribute(handle->handle, info.wAttributes)) { - *error = GetLastError(); - return -1; - } - - return 0; -} - - -static int uv_tty_save_state(uv_tty_t* handle, unsigned char save_attributes, - DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - uv_tty_update_virtual_window(&info); - - handle->saved_position.X = info.dwCursorPosition.X; - handle->saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset; - handle->flags |= UV_HANDLE_TTY_SAVED_POSITION; - - if (save_attributes) { - handle->saved_attributes = info.wAttributes & - (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); - handle->flags |= UV_HANDLE_TTY_SAVED_ATTRIBUTES; - } - - return 0; -} - - -static int uv_tty_restore_state(uv_tty_t* handle, - unsigned char restore_attributes, DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - WORD new_attributes; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (handle->flags & UV_HANDLE_TTY_SAVED_POSITION) { - if (uv_tty_move_caret(handle, - handle->saved_position.X, - 0, - handle->saved_position.Y, - 0, - error) != 0) { - return -1; - } - } - - if (restore_attributes && - (handle->flags & UV_HANDLE_TTY_SAVED_ATTRIBUTES)) { - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - new_attributes = info.wAttributes; - new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); - new_attributes |= handle->saved_attributes; - - if (!SetConsoleTextAttribute(handle->handle, new_attributes)) { - *error = GetLastError(); - return -1; - } - } - - return 0; -} - - -static int uv_tty_write_bufs(uv_tty_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - DWORD* error) { - /* We can only write 8k characters at a time. Windows can't handle */ - /* much more characters in a single console write anyway. */ - WCHAR utf16_buf[8192]; - DWORD utf16_buf_used = 0; - unsigned int i; - -#define FLUSH_TEXT() \ - do { \ - if (utf16_buf_used > 0) { \ - uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error); \ - utf16_buf_used = 0; \ - } \ - } while (0) - - /* Cache for fast access */ - unsigned char utf8_bytes_left = handle->utf8_bytes_left; - unsigned int utf8_codepoint = handle->utf8_codepoint; - unsigned char previous_eol = handle->previous_eol; - unsigned char ansi_parser_state = handle->ansi_parser_state; - - /* Store the error here. If we encounter an error, stop trying to do i/o */ - /* but keep parsing the buffer so we leave the parser in a consistent */ - /* state. */ - *error = ERROR_SUCCESS; - - EnterCriticalSection(&uv_tty_output_lock); - - for (i = 0; i < nbufs; i++) { - uv_buf_t buf = bufs[i]; - unsigned int j; - - for (j = 0; j < buf.len; j++) { - unsigned char c = buf.base[j]; - - /* Run the character through the utf8 decoder We happily accept non */ - /* shortest form encodings and invalid code points - there's no real */ - /* harm that can be done. */ - if (utf8_bytes_left == 0) { - /* Read utf-8 start byte */ - DWORD first_zero_bit; - unsigned char not_c = ~c; -#ifdef _MSC_VER /* msvc */ - if (_BitScanReverse(&first_zero_bit, not_c)) { -#else /* assume gcc */ - if (c != 0) { - first_zero_bit = (sizeof(int) * 8) - 1 - __builtin_clz(not_c); -#endif - if (first_zero_bit == 7) { - /* Ascii - pass right through */ - utf8_codepoint = (unsigned int) c; - - } else if (first_zero_bit <= 5) { - /* Multibyte sequence */ - utf8_codepoint = (0xff >> (8 - first_zero_bit)) & c; - utf8_bytes_left = (char) (6 - first_zero_bit); - - } else { - /* Invalid continuation */ - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - - } else { - /* 0xff -- invalid */ - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - - } else if ((c & 0xc0) == 0x80) { - /* Valid continuation of utf-8 multibyte sequence */ - utf8_bytes_left--; - utf8_codepoint <<= 6; - utf8_codepoint |= ((unsigned int) c & 0x3f); - - } else { - /* Start byte where continuation was expected. */ - utf8_bytes_left = 0; - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - /* Patch buf offset so this character will be parsed again as a */ - /* start byte. */ - j--; - } - - /* Maybe we need to parse more bytes to find a character. */ - if (utf8_bytes_left != 0) { - continue; - } - - /* Parse vt100/ansi escape codes */ - if (ansi_parser_state == ANSI_NORMAL) { - switch (utf8_codepoint) { - case '\033': - ansi_parser_state = ANSI_ESCAPE_SEEN; - continue; - - case 0233: - ansi_parser_state = ANSI_CSI; - handle->ansi_csi_argc = 0; - continue; - } - - } else if (ansi_parser_state == ANSI_ESCAPE_SEEN) { - switch (utf8_codepoint) { - case '[': - ansi_parser_state = ANSI_CSI; - handle->ansi_csi_argc = 0; - continue; - - case '^': - case '_': - case 'P': - case ']': - /* Not supported, but we'll have to parse until we see a stop */ - /* code, e.g. ESC \ or BEL. */ - ansi_parser_state = ANSI_ST_CONTROL; - continue; - - case '\033': - /* Ignore double escape. */ - continue; - - case 'c': - /* Full console reset. */ - FLUSH_TEXT(); - uv_tty_reset(handle, error); - ansi_parser_state = ANSI_NORMAL; - continue; - - case '7': - /* Save the cursor position and text attributes. */ - FLUSH_TEXT(); - uv_tty_save_state(handle, 1, error); - ansi_parser_state = ANSI_NORMAL; - continue; - - case '8': - /* Restore the cursor position and text attributes */ - FLUSH_TEXT(); - uv_tty_restore_state(handle, 1, error); - ansi_parser_state = ANSI_NORMAL; - continue; - - default: - if (utf8_codepoint >= '@' && utf8_codepoint <= '_') { - /* Single-char control. */ - ansi_parser_state = ANSI_NORMAL; - continue; - } else { - /* Invalid - proceed as normal, */ - ansi_parser_state = ANSI_NORMAL; - } - } - - } else if (ansi_parser_state & ANSI_CSI) { - if (!(ansi_parser_state & ANSI_IGNORE)) { - if (utf8_codepoint >= '0' && utf8_codepoint <= '9') { - /* Parsing a numerical argument */ - - if (!(ansi_parser_state & ANSI_IN_ARG)) { - /* We were not currently parsing a number */ - - /* Check for too many arguments */ - if (handle->ansi_csi_argc >= ARRAY_SIZE(handle->ansi_csi_argv)) { - ansi_parser_state |= ANSI_IGNORE; - continue; - } - - ansi_parser_state |= ANSI_IN_ARG; - handle->ansi_csi_argc++; - handle->ansi_csi_argv[handle->ansi_csi_argc - 1] = - (unsigned short) utf8_codepoint - '0'; - continue; - } else { - /* We were already parsing a number. Parse next digit. */ - uint32_t value = 10 * - handle->ansi_csi_argv[handle->ansi_csi_argc - 1]; - - /* Check for overflow. */ - if (value > UINT16_MAX) { - ansi_parser_state |= ANSI_IGNORE; - continue; - } - - handle->ansi_csi_argv[handle->ansi_csi_argc - 1] = - (unsigned short) value + (utf8_codepoint - '0'); - continue; - } - - } else if (utf8_codepoint == ';') { - /* Denotes the end of an argument. */ - if (ansi_parser_state & ANSI_IN_ARG) { - ansi_parser_state &= ~ANSI_IN_ARG; - continue; - - } else { - /* If ANSI_IN_ARG is not set, add another argument and */ - /* default it to 0. */ - /* Check for too many arguments */ - if (handle->ansi_csi_argc >= ARRAY_SIZE(handle->ansi_csi_argv)) { - ansi_parser_state |= ANSI_IGNORE; - continue; - } - - handle->ansi_csi_argc++; - handle->ansi_csi_argv[handle->ansi_csi_argc - 1] = 0; - continue; - } - - } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' && - (handle->ansi_csi_argc > 0 || utf8_codepoint != '[')) { - int x, y, d; - - /* Command byte */ - switch (utf8_codepoint) { - case 'A': - /* cursor up */ - FLUSH_TEXT(); - y = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1); - uv_tty_move_caret(handle, 0, 1, y, 1, error); - break; - - case 'B': - /* cursor down */ - FLUSH_TEXT(); - y = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1; - uv_tty_move_caret(handle, 0, 1, y, 1, error); - break; - - case 'C': - /* cursor forward */ - FLUSH_TEXT(); - x = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1; - uv_tty_move_caret(handle, x, 1, 0, 1, error); - break; - - case 'D': - /* cursor back */ - FLUSH_TEXT(); - x = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1); - uv_tty_move_caret(handle, x, 1, 0, 1, error); - break; - - case 'E': - /* cursor next line */ - FLUSH_TEXT(); - y = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1; - uv_tty_move_caret(handle, 0, 0, y, 1, error); - break; - - case 'F': - /* cursor previous line */ - FLUSH_TEXT(); - y = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1); - uv_tty_move_caret(handle, 0, 0, y, 1, error); - break; - - case 'G': - /* cursor horizontal move absolute */ - FLUSH_TEXT(); - x = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0]) - ? handle->ansi_csi_argv[0] - 1 : 0; - uv_tty_move_caret(handle, x, 0, 0, 1, error); - break; - - case 'H': - case 'f': - /* cursor move absolute */ - FLUSH_TEXT(); - y = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0]) - ? handle->ansi_csi_argv[0] - 1 : 0; - x = (handle->ansi_csi_argc >= 2 && handle->ansi_csi_argv[1]) - ? handle->ansi_csi_argv[1] - 1 : 0; - uv_tty_move_caret(handle, x, 0, y, 0, error); - break; - - case 'J': - /* Erase screen */ - FLUSH_TEXT(); - d = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 0; - if (d >= 0 && d <= 2) { - uv_tty_clear(handle, d, 1, error); - } - break; - - case 'K': - /* Erase line */ - FLUSH_TEXT(); - d = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 0; - if (d >= 0 && d <= 2) { - uv_tty_clear(handle, d, 0, error); - } - break; - - case 'm': - /* Set style */ - FLUSH_TEXT(); - uv_tty_set_style(handle, error); - break; - - case 's': - /* Save the cursor position. */ - FLUSH_TEXT(); - uv_tty_save_state(handle, 0, error); - break; - - case 'u': - /* Restore the cursor position */ - FLUSH_TEXT(); - uv_tty_restore_state(handle, 0, error); - break; - } - - /* Sequence ended - go back to normal state. */ - ansi_parser_state = ANSI_NORMAL; - continue; - - } else { - /* We don't support commands that use private mode characters or */ - /* intermediaries. Ignore the rest of the sequence. */ - ansi_parser_state |= ANSI_IGNORE; - continue; - } - } else { - /* We're ignoring this command. Stop only on command character. */ - if (utf8_codepoint >= '@' && utf8_codepoint <= '~') { - ansi_parser_state = ANSI_NORMAL; - } - continue; - } - - } else if (ansi_parser_state & ANSI_ST_CONTROL) { - /* Unsupported control code */ - /* Ignore everything until we see BEL or ESC \ */ - if (ansi_parser_state & ANSI_IN_STRING) { - if (!(ansi_parser_state & ANSI_BACKSLASH_SEEN)) { - if (utf8_codepoint == '"') { - ansi_parser_state &= ~ANSI_IN_STRING; - } else if (utf8_codepoint == '\\') { - ansi_parser_state |= ANSI_BACKSLASH_SEEN; - } - } else { - ansi_parser_state &= ~ANSI_BACKSLASH_SEEN; - } - } else { - if (utf8_codepoint == '\007' || (utf8_codepoint == '\\' && - (ansi_parser_state & ANSI_ESCAPE_SEEN))) { - /* End of sequence */ - ansi_parser_state = ANSI_NORMAL; - } else if (utf8_codepoint == '\033') { - /* Escape character */ - ansi_parser_state |= ANSI_ESCAPE_SEEN; - } else if (utf8_codepoint == '"') { - /* String starting */ - ansi_parser_state |= ANSI_IN_STRING; - ansi_parser_state &= ~ANSI_ESCAPE_SEEN; - ansi_parser_state &= ~ANSI_BACKSLASH_SEEN; - } else { - ansi_parser_state &= ~ANSI_ESCAPE_SEEN; - } - } - continue; - } else { - /* Inconsistent state */ - abort(); - } - - /* We wouldn't mind emitting utf-16 surrogate pairs. Too bad, the */ - /* windows console doesn't really support UTF-16, so just emit the */ - /* replacement character. */ - if (utf8_codepoint > 0xffff) { - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - - if (utf8_codepoint == 0x0a || utf8_codepoint == 0x0d) { - /* EOL conversion - emit \r\n, when we see either \r or \n. */ - /* If a \n immediately follows a \r or vice versa, ignore it. */ - if (previous_eol == 0 || utf8_codepoint == previous_eol) { - /* If there's no room in the utf16 buf, flush it first. */ - if (2 > ARRAY_SIZE(utf16_buf) - utf16_buf_used) { - uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error); - utf16_buf_used = 0; - } - - utf16_buf[utf16_buf_used++] = L'\r'; - utf16_buf[utf16_buf_used++] = L'\n'; - previous_eol = (char) utf8_codepoint; - } else { - /* Ignore this newline, but don't ignore later ones. */ - previous_eol = 0; - } - - } else if (utf8_codepoint <= 0xffff) { - /* Encode character into utf-16 buffer. */ - - /* If there's no room in the utf16 buf, flush it first. */ - if (1 > ARRAY_SIZE(utf16_buf) - utf16_buf_used) { - uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error); - utf16_buf_used = 0; - } - - utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint; - previous_eol = 0; - } - } - } - - /* Flush remaining characters */ - FLUSH_TEXT(); - - /* Copy cached values back to struct. */ - handle->utf8_bytes_left = utf8_bytes_left; - handle->utf8_codepoint = utf8_codepoint; - handle->previous_eol = previous_eol; - handle->ansi_parser_state = ansi_parser_state; - - LeaveCriticalSection(&uv_tty_output_lock); - - if (*error == STATUS_SUCCESS) { - return 0; - } else { - return -1; - } - -#undef FLUSH_TEXT -} - - -int uv_tty_write(uv_loop_t* loop, - uv_write_t* req, - uv_tty_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - DWORD error; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - - handle->reqs_pending++; - handle->write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - - req->queued_bytes = 0; - - if (!uv_tty_write_bufs(handle, bufs, nbufs, &error)) { - SET_REQ_SUCCESS(req); - } else { - SET_REQ_ERROR(req, error); - } - - uv_insert_pending_req(loop, (uv_req_t*) req); - - return 0; -} - - -void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, - uv_write_t* req) { - int err; - - handle->write_queue_size -= req->queued_bytes; - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (req->cb) { - err = GET_REQ_ERROR(req); - req->cb(req, uv_translate_sys_error(err)); - } - - handle->write_reqs_pending--; - if (handle->shutdown_req != NULL && - handle->write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_tty_close(uv_tty_t* handle) { - CloseHandle(handle->handle); - - if (handle->flags & UV_HANDLE_READING) - uv_tty_read_stop(handle); - - handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); - uv__handle_closing(handle); - - if (handle->reqs_pending == 0) { - uv_want_endgame(handle->loop, (uv_handle_t*) handle); - } -} - - -void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { - if (!(handle->flags && UV_HANDLE_TTY_READABLE) && - handle->shutdown_req != NULL && - handle->write_reqs_pending == 0) { - UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req); - - /* TTY shutdown is really just a no-op */ - if (handle->shutdown_req->cb) { - if (handle->flags & UV__HANDLE_CLOSING) { - handle->shutdown_req->cb(handle->shutdown_req, UV_ECANCELED); - } else { - handle->shutdown_req->cb(handle->shutdown_req, 0); - } - } - - handle->shutdown_req = NULL; - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - /* The console handle duplicate used for line reading should be destroyed */ - /* by uv_tty_read_stop. */ - assert(!(handle->flags & UV_HANDLE_TTY_READABLE) || - handle->read_line_handle == NULL); - - /* The wait handle used for raw reading should be unregistered when the */ - /* wait callback runs. */ - assert(!(handle->flags & UV_HANDLE_TTY_READABLE) || - handle->read_raw_wait == NULL); - - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -/* TODO: remove me */ -void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* raw_req) { - abort(); -} - - -/* TODO: remove me */ -void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, - uv_connect_t* req) { - abort(); -} - - -int uv_tty_reset_mode(void) { - /* Not necessary to do anything. */ - return 0; -} diff --git a/third-party/libuv/src/win/udp.c b/third-party/libuv/src/win/udp.c deleted file mode 100644 index 31812e4642..0000000000 --- a/third-party/libuv/src/win/udp.c +++ /dev/null @@ -1,749 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -/* - * Threshold of active udp streams for which to preallocate udp read buffers. - */ -const unsigned int uv_active_udp_streams_threshold = 0; - -/* A zero-size buffer for use by uv_udp_read */ -static char uv_zero_[] = ""; - -int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, - int* namelen) { - int result; - - if (!(handle->flags & UV_HANDLE_BOUND)) { - return UV_EINVAL; - } - - result = getsockname(handle->socket, name, namelen); - if (result != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket, - int family) { - DWORD yes = 1; - WSAPROTOCOL_INFOW info; - int opt_len; - - assert(handle->socket == INVALID_SOCKET); - - /* Set SO_REUSEADDR on the socket. */ - if (setsockopt(socket, - SOL_SOCKET, - SO_REUSEADDR, - (char*) &yes, - sizeof yes) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - /* Set the socket to nonblocking mode */ - if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) { - return GetLastError(); - } - - /* Associate it with the I/O completion port. */ - /* Use uv_handle_t pointer as completion key. */ - if (CreateIoCompletionPort((HANDLE)socket, - loop->iocp, - (ULONG_PTR)socket, - 0) == NULL) { - return GetLastError(); - } - - if (pSetFileCompletionNotificationModes) { - /* All know windowses that support SetFileCompletionNotificationModes */ - /* have a bug that makes it impossible to use this function in */ - /* conjunction with datagram sockets. We can work around that but only */ - /* if the user is using the default UDP driver (AFD) and has no other */ - /* LSPs stacked on top. Here we check whether that is the case. */ - opt_len = (int) sizeof info; - if (getsockopt(socket, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &info, - &opt_len) == SOCKET_ERROR) { - return GetLastError(); - } - - if (info.ProtocolChain.ChainLen == 1) { - if (pSetFileCompletionNotificationModes((HANDLE)socket, - FILE_SKIP_SET_EVENT_ON_HANDLE | - FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { - handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; - handle->func_wsarecv = uv_wsarecv_workaround; - handle->func_wsarecvfrom = uv_wsarecvfrom_workaround; - } else if (GetLastError() != ERROR_INVALID_FUNCTION) { - return GetLastError(); - } - } - } - - handle->socket = socket; - - if (family == AF_INET6) { - handle->flags |= UV_HANDLE_IPV6; - } else { - assert(!(handle->flags & UV_HANDLE_IPV6)); - } - - return 0; -} - - -int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP); - - handle->socket = INVALID_SOCKET; - handle->reqs_pending = 0; - handle->activecnt = 0; - handle->func_wsarecv = WSARecv; - handle->func_wsarecvfrom = WSARecvFrom; - - uv_req_init(loop, (uv_req_t*) &(handle->recv_req)); - handle->recv_req.type = UV_UDP_RECV; - handle->recv_req.data = handle; - - return 0; -} - - -void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) { - uv_udp_recv_stop(handle); - closesocket(handle->socket); - - uv__handle_closing(handle); - - if (handle->reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -static int uv_udp_try_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int r; - int err; - DWORD no = 0; - - if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) { - /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */ - return ERROR_INVALID_PARAMETER; - } - - if (handle->socket == INVALID_SOCKET) { - SOCKET sock = socket(addr->sa_family, SOCK_DGRAM, 0); - if (sock == INVALID_SOCKET) { - return WSAGetLastError(); - } - - err = uv_udp_set_socket(handle->loop, handle, sock, addr->sa_family); - if (err) { - closesocket(sock); - return err; - } - - if (addr->sa_family == AF_INET6) - handle->flags |= UV_HANDLE_IPV6; - } - - if (addr->sa_family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) { - /* On windows IPV6ONLY is on by default. */ - /* If the user doesn't specify it libuv turns it off. */ - - /* TODO: how to handle errors? This may fail if there is no ipv4 stack */ - /* available, or when run on XP/2003 which have no support for dualstack */ - /* sockets. For now we're silently ignoring the error. */ - setsockopt(handle->socket, - IPPROTO_IPV6, - IPV6_V6ONLY, - (char*) &no, - sizeof no); - } - - r = bind(handle->socket, addr, addrlen); - if (r == SOCKET_ERROR) { - return WSAGetLastError(); - } - - handle->flags |= UV_HANDLE_BOUND; - - return 0; -} - - -static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { - uv_req_t* req; - uv_buf_t buf; - DWORD bytes, flags; - int result; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - req = &handle->recv_req; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - - /* - * Preallocate a read buffer if the number of active streams is below - * the threshold. - */ - if (loop->active_udp_streams < uv_active_udp_streams_threshold) { - handle->flags &= ~UV_HANDLE_ZERO_READ; - - handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer); - if (handle->recv_buffer.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0); - return; - } - assert(handle->recv_buffer.base != NULL); - - buf = handle->recv_buffer; - memset(&handle->recv_from, 0, sizeof handle->recv_from); - handle->recv_from_len = sizeof handle->recv_from; - flags = 0; - - result = handle->func_wsarecvfrom(handle->socket, - (WSABUF*) &buf, - 1, - &bytes, - &flags, - (struct sockaddr*) &handle->recv_from, - &handle->recv_from_len, - &req->overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Process the req without IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - req->overlapped.InternalHigh = bytes; - handle->reqs_pending++; - uv_insert_pending_req(loop, req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* The req will be processed with IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, req); - handle->reqs_pending++; - } - - } else { - handle->flags |= UV_HANDLE_ZERO_READ; - - buf.base = (char*) uv_zero_; - buf.len = 0; - flags = MSG_PEEK; - - result = handle->func_wsarecv(handle->socket, - (WSABUF*) &buf, - 1, - &bytes, - &flags, - &req->overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Process the req without IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - req->overlapped.InternalHigh = bytes; - handle->reqs_pending++; - uv_insert_pending_req(loop, req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* The req will be processed with IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, req); - handle->reqs_pending++; - } - } -} - - -int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, - uv_udp_recv_cb recv_cb) { - uv_loop_t* loop = handle->loop; - int err; - - if (handle->flags & UV_HANDLE_READING) { - return WSAEALREADY; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - err = uv_udp_try_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - 0); - if (err) - return err; - } - - handle->flags |= UV_HANDLE_READING; - INCREASE_ACTIVE_COUNT(loop, handle); - loop->active_udp_streams++; - - handle->recv_cb = recv_cb; - handle->alloc_cb = alloc_cb; - - /* If reading was stopped and then started again, there could still be a */ - /* recv request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) - uv_udp_queue_recv(loop, handle); - - return 0; -} - - -int uv__udp_recv_stop(uv_udp_t* handle) { - if (handle->flags & UV_HANDLE_READING) { - handle->flags &= ~UV_HANDLE_READING; - handle->loop->active_udp_streams--; - DECREASE_ACTIVE_COUNT(loop, handle); - } - - return 0; -} - - -static int uv__send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb cb) { - uv_loop_t* loop = handle->loop; - DWORD result, bytes; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_UDP_SEND; - req->handle = handle; - req->cb = cb; - memset(&req->overlapped, 0, sizeof(req->overlapped)); - - result = WSASendTo(handle->socket, - (WSABUF*)bufs, - nbufs, - &bytes, - 0, - addr, - addrlen, - &req->overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Request completed immediately. */ - req->queued_bytes = 0; - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* Request queued by the kernel. */ - req->queued_bytes = uv_count_bufs(bufs, nbufs); - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - } else { - /* Send failed due to an error. */ - return WSAGetLastError(); - } - - return 0; -} - - -void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, - uv_req_t* req) { - uv_buf_t buf; - int partial; - - assert(handle->type == UV_UDP); - - handle->flags &= ~UV_HANDLE_READ_PENDING; - - if (!REQ_SUCCESS(req)) { - DWORD err = GET_REQ_SOCK_ERROR(req); - if (err == WSAEMSGSIZE) { - /* Not a real error, it just indicates that the received packet */ - /* was bigger than the receive buffer. */ - } else if (err == WSAECONNRESET || err == WSAENETRESET) { - /* A previous sendto operation failed; ignore this error. If */ - /* zero-reading we need to call WSARecv/WSARecvFrom _without_ the */ - /* MSG_PEEK flag to clear out the error queue. For nonzero reads, */ - /* immediately queue a new receive. */ - if (!(handle->flags & UV_HANDLE_ZERO_READ)) { - goto done; - } - } else { - /* A real error occurred. Report the error to the user only if we're */ - /* currently reading. */ - if (handle->flags & UV_HANDLE_READING) { - uv_udp_recv_stop(handle); - buf = (handle->flags & UV_HANDLE_ZERO_READ) ? - uv_buf_init(NULL, 0) : handle->recv_buffer; - handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); - } - goto done; - } - } - - if (!(handle->flags & UV_HANDLE_ZERO_READ)) { - /* Successful read */ - partial = !REQ_SUCCESS(req); - handle->recv_cb(handle, - req->overlapped.InternalHigh, - &handle->recv_buffer, - (const struct sockaddr*) &handle->recv_from, - partial ? UV_UDP_PARTIAL : 0); - } else if (handle->flags & UV_HANDLE_READING) { - DWORD bytes, err, flags; - struct sockaddr_storage from; - int from_len; - - /* Do a nonblocking receive */ - /* TODO: try to read multiple datagrams at once. FIONREAD maybe? */ - handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); - if (buf.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); - goto done; - } - assert(buf.base != NULL); - - memset(&from, 0, sizeof from); - from_len = sizeof from; - - flags = 0; - - if (WSARecvFrom(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - (struct sockaddr*) &from, - &from_len, - NULL, - NULL) != SOCKET_ERROR) { - - /* Message received */ - handle->recv_cb(handle, bytes, &buf, (const struct sockaddr*) &from, 0); - } else { - err = WSAGetLastError(); - if (err == WSAEMSGSIZE) { - /* Message truncated */ - handle->recv_cb(handle, - bytes, - &buf, - (const struct sockaddr*) &from, - UV_UDP_PARTIAL); - } else if (err == WSAEWOULDBLOCK) { - /* Kernel buffer empty */ - handle->recv_cb(handle, 0, &buf, NULL, 0); - } else if (err != WSAECONNRESET && err != WSAENETRESET) { - /* Serious error. WSAECONNRESET/WSANETRESET is ignored because this */ - /* just indicates that a previous sendto operation failed. */ - uv_udp_recv_stop(handle); - handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); - } - } - } - -done: - /* Post another read if still reading and not closing. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_udp_queue_recv(loop, handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, - uv_udp_send_t* req) { - int err; - - assert(handle->type == UV_UDP); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (req->cb) { - err = 0; - if (!REQ_SUCCESS(req)) { - err = GET_REQ_SOCK_ERROR(req); - } - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, - const char* interface_addr, uv_membership membership) { - int err; - int optname; - struct ip_mreq mreq; - - /* If the socket is unbound, bind to inaddr_any. */ - if (!(handle->flags & UV_HANDLE_BOUND)) { - err = uv_udp_try_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - 0); - if (err) - return uv_translate_sys_error(err); - } - - if (handle->flags & UV_HANDLE_IPV6) { - return UV_ENOSYS; - } - - memset(&mreq, 0, sizeof mreq); - - if (interface_addr) { - mreq.imr_interface.s_addr = inet_addr(interface_addr); - } else { - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - } - - mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr); - - switch (membership) { - case UV_JOIN_GROUP: - optname = IP_ADD_MEMBERSHIP; - break; - case UV_LEAVE_GROUP: - optname = IP_DROP_MEMBERSHIP; - break; - default: - return UV_EINVAL; - } - - if (setsockopt(handle->socket, - IPPROTO_IP, - optname, - (char*) &mreq, - sizeof mreq) == SOCKET_ERROR) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_udp_set_broadcast(uv_udp_t* handle, int value) { - BOOL optval = (BOOL) value; - int err; - - /* If the socket is unbound, bind to inaddr_any. */ - if (!(handle->flags & UV_HANDLE_BOUND)) { - err = uv_udp_try_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - 0); - if (err) - return uv_translate_sys_error(err); - } - - if (setsockopt(handle->socket, - SOL_SOCKET, - SO_BROADCAST, - (char*) &optval, - sizeof optval)) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { - WSAPROTOCOL_INFOW protocol_info; - int opt_len; - int err; - - /* Detect the address family of the socket. */ - opt_len = (int) sizeof protocol_info; - if (getsockopt(sock, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) { - return uv_translate_sys_error(GetLastError()); - } - - err = uv_udp_set_socket(handle->loop, - handle, - sock, - protocol_info.iAddressFamily); - return uv_translate_sys_error(err); -} - - -#define SOCKOPT_SETTER(name, option4, option6, validate) \ - int uv_udp_set_##name(uv_udp_t* handle, int value) { \ - DWORD optval = (DWORD) value; \ - int err; \ - \ - if (!(validate(value))) { \ - return UV_EINVAL; \ - } \ - \ - /* If the socket is unbound, bind to inaddr_any. */ \ - if (!(handle->flags & UV_HANDLE_BOUND)) { \ - err = uv_udp_try_bind(handle, \ - (const struct sockaddr*) &uv_addr_ip4_any_, \ - sizeof(uv_addr_ip4_any_), \ - 0); \ - if (err) \ - return uv_translate_sys_error(err); \ - } \ - \ - if (!(handle->flags & UV_HANDLE_IPV6)) { \ - /* Set IPv4 socket option */ \ - if (setsockopt(handle->socket, \ - IPPROTO_IP, \ - option4, \ - (char*) &optval, \ - sizeof optval)) { \ - return uv_translate_sys_error(WSAGetLastError()); \ - } \ - } else { \ - /* Set IPv6 socket option */ \ - if (setsockopt(handle->socket, \ - IPPROTO_IPV6, \ - option6, \ - (char*) &optval, \ - sizeof optval)) { \ - return uv_translate_sys_error(WSAGetLastError()); \ - } \ - } \ - return 0; \ - } - -#define VALIDATE_TTL(value) ((value) >= 1 && (value) <= 255) -#define VALIDATE_MULTICAST_TTL(value) ((value) >= -1 && (value) <= 255) -#define VALIDATE_MULTICAST_LOOP(value) (1) - -SOCKOPT_SETTER(ttl, - IP_TTL, - IPV6_HOPLIMIT, - VALIDATE_TTL) -SOCKOPT_SETTER(multicast_ttl, - IP_MULTICAST_TTL, - IPV6_MULTICAST_HOPS, - VALIDATE_MULTICAST_TTL) -SOCKOPT_SETTER(multicast_loop, - IP_MULTICAST_LOOP, - IPV6_MULTICAST_LOOP, - VALIDATE_MULTICAST_LOOP) - -#undef SOCKOPT_SETTER -#undef VALIDATE_TTL -#undef VALIDATE_MULTICAST_TTL -#undef VALIDATE_MULTICAST_LOOP - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - - err = uv_udp_try_bind(handle, addr, addrlen, flags); - if (err) - return uv_translate_sys_error(err); - - return 0; -} - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb send_cb) { - const struct sockaddr* bind_addr; - int err; - - if (!(handle->flags & UV_HANDLE_BOUND)) { - if (addrlen == sizeof(uv_addr_ip4_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; - } else if (addrlen == sizeof(uv_addr_ip6_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; - } else { - abort(); - } - err = uv_udp_try_bind(handle, bind_addr, addrlen, 0); - if (err) - return uv_translate_sys_error(err); - } - - err = uv__send(req, handle, bufs, nbufs, addr, addrlen, send_cb); - if (err) - return uv_translate_sys_error(err); - - return 0; -} diff --git a/third-party/libuv/src/win/util.c b/third-party/libuv/src/win/util.c deleted file mode 100644 index 266b881640..0000000000 --- a/third-party/libuv/src/win/util.c +++ /dev/null @@ -1,990 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <direct.h> -#include <limits.h> -#include <malloc.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <wchar.h> - -#include "uv.h" -#include "internal.h" - -#include <winsock2.h> -#include <winperf.h> -#include <iphlpapi.h> -#include <psapi.h> -#include <tlhelp32.h> - - -/* - * Max title length; the only thing MSDN tells us about the maximum length - * of the console title is that it is smaller than 64K. However in practice - * it is much smaller, and there is no way to figure out what the exact length - * of the title is or can be, at least not on XP. To make it even more - * annoying, GetConsoleTitle failes when the buffer to be read into is bigger - * than the actual maximum length. So we make a conservative guess here; - * just don't put the novel you're writing in the title, unless the plot - * survives truncation. - */ -#define MAX_TITLE_LENGTH 8192 - -/* The number of nanoseconds in one second. */ -#undef NANOSEC -#define NANOSEC 1000000000 - - -/* Cached copy of the process title, plus a mutex guarding it. */ -static char *process_title; -static CRITICAL_SECTION process_title_lock; - -/* Frequency (ticks per nanosecond) of the high-resolution clock. */ -static double hrtime_frequency_ = 0; - - -/* - * One-time intialization code for functionality defined in util.c. - */ -void uv__util_init() { - LARGE_INTEGER perf_frequency; - - /* Initialize process title access mutex. */ - InitializeCriticalSection(&process_title_lock); - - /* Retrieve high-resolution timer frequency. */ - if (QueryPerformanceFrequency(&perf_frequency)) - hrtime_frequency_ = (double) perf_frequency.QuadPart / (double) NANOSEC; - else - hrtime_frequency_= 0; -} - - -int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size, - char* utf8Buffer, size_t utf8Size) { - return WideCharToMultiByte(CP_UTF8, - 0, - utf16Buffer, - utf16Size, - utf8Buffer, - utf8Size, - NULL, - NULL); -} - - -int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer, - size_t utf16Size) { - return MultiByteToWideChar(CP_UTF8, - 0, - utf8Buffer, - -1, - utf16Buffer, - utf16Size); -} - - -int uv_exepath(char* buffer, size_t* size_ptr) { - int utf8_len, utf16_buffer_len, utf16_len; - WCHAR* utf16_buffer; - int err; - - if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) { - return UV_EINVAL; - } - - if (*size_ptr > 32768) { - /* Windows paths can never be longer than this. */ - utf16_buffer_len = 32768; - } else { - utf16_buffer_len = (int) *size_ptr; - } - - utf16_buffer = (WCHAR*) malloc(sizeof(WCHAR) * utf16_buffer_len); - if (!utf16_buffer) { - return UV_ENOMEM; - } - - /* Get the path as UTF-16. */ - utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len); - if (utf16_len <= 0) { - err = GetLastError(); - goto error; - } - - /* utf16_len contains the length, *not* including the terminating null. */ - utf16_buffer[utf16_len] = L'\0'; - - /* Convert to UTF-8 */ - utf8_len = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - -1, - buffer, - *size_ptr > INT_MAX ? INT_MAX : (int) *size_ptr, - NULL, - NULL); - if (utf8_len == 0) { - err = GetLastError(); - goto error; - } - - free(utf16_buffer); - - /* utf8_len *does* include the terminating null at this point, but the */ - /* returned size shouldn't. */ - *size_ptr = utf8_len - 1; - return 0; - - error: - free(utf16_buffer); - return uv_translate_sys_error(err); -} - - -int uv_cwd(char* buffer, size_t size) { - DWORD utf16_len; - WCHAR utf16_buffer[MAX_PATH]; - int r; - - if (buffer == NULL || size == 0) { - return UV_EINVAL; - } - - utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer); - if (utf16_len == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (utf16_len > MAX_PATH) { - /* This should be impossible; however the CRT has a code path to deal */ - /* with this scenario, so I added a check anyway. */ - return UV_EIO; - } - - /* utf16_len contains the length, *not* including the terminating null. */ - utf16_buffer[utf16_len] = L'\0'; - - /* The returned directory should not have a trailing slash, unless it */ - /* points at a drive root, like c:\. Remove it if needed.*/ - if (utf16_buffer[utf16_len - 1] == L'\\' && - !(utf16_len == 3 && utf16_buffer[1] == L':')) { - utf16_len--; - utf16_buffer[utf16_len] = L'\0'; - } - - /* Convert to UTF-8 */ - r = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - -1, - buffer, - size > INT_MAX ? INT_MAX : (int) size, - NULL, - NULL); - if (r == 0) { - return uv_translate_sys_error(GetLastError()); - } - - return 0; -} - - -int uv_chdir(const char* dir) { - WCHAR utf16_buffer[MAX_PATH]; - size_t utf16_len; - WCHAR drive_letter, env_var[4]; - - if (dir == NULL) { - return UV_EINVAL; - } - - if (MultiByteToWideChar(CP_UTF8, - 0, - dir, - -1, - utf16_buffer, - MAX_PATH) == 0) { - DWORD error = GetLastError(); - /* The maximum length of the current working directory is 260 chars, */ - /* including terminating null. If it doesn't fit, the path name must be */ - /* too long. */ - if (error == ERROR_INSUFFICIENT_BUFFER) { - return UV_ENAMETOOLONG; - } else { - return uv_translate_sys_error(error); - } - } - - if (!SetCurrentDirectoryW(utf16_buffer)) { - return uv_translate_sys_error(GetLastError()); - } - - /* Windows stores the drive-local path in an "hidden" environment variable, */ - /* which has the form "=C:=C:\Windows". SetCurrentDirectory does not */ - /* update this, so we'll have to do it. */ - utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer); - if (utf16_len == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (utf16_len > MAX_PATH) { - return UV_EIO; - } - - /* The returned directory should not have a trailing slash, unless it */ - /* points at a drive root, like c:\. Remove it if needed. */ - if (utf16_buffer[utf16_len - 1] == L'\\' && - !(utf16_len == 3 && utf16_buffer[1] == L':')) { - utf16_len--; - utf16_buffer[utf16_len] = L'\0'; - } - - if (utf16_len < 2 || utf16_buffer[1] != L':') { - /* Doesn't look like a drive letter could be there - probably an UNC */ - /* path. TODO: Need to handle win32 namespaces like \\?\C:\ ? */ - drive_letter = 0; - } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') { - drive_letter = utf16_buffer[0]; - } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') { - /* Convert to uppercase. */ - drive_letter = utf16_buffer[0] - L'a' + L'A'; - } else { - /* Not valid. */ - drive_letter = 0; - } - - if (drive_letter != 0) { - /* Construct the environment variable name and set it. */ - env_var[0] = L'='; - env_var[1] = drive_letter; - env_var[2] = L':'; - env_var[3] = L'\0'; - - if (!SetEnvironmentVariableW(env_var, utf16_buffer)) { - return uv_translate_sys_error(GetLastError()); - } - } - - return 0; -} - - -void uv_loadavg(double avg[3]) { - /* Can't be implemented */ - avg[0] = avg[1] = avg[2] = 0; -} - - -uint64_t uv_get_free_memory(void) { - MEMORYSTATUSEX memory_status; - memory_status.dwLength = sizeof(memory_status); - - if(!GlobalMemoryStatusEx(&memory_status)) - { - return -1; - } - - return (uint64_t)memory_status.ullAvailPhys; -} - - -uint64_t uv_get_total_memory(void) { - MEMORYSTATUSEX memory_status; - memory_status.dwLength = sizeof(memory_status); - - if(!GlobalMemoryStatusEx(&memory_status)) - { - return -1; - } - - return (uint64_t)memory_status.ullTotalPhys; -} - - -int uv_parent_pid() { - int parent_pid = -1; - HANDLE handle; - PROCESSENTRY32 pe; - int current_pid = GetCurrentProcessId(); - - pe.dwSize = sizeof(PROCESSENTRY32); - handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - - if (Process32First(handle, &pe)) { - do { - if (pe.th32ProcessID == current_pid) { - parent_pid = pe.th32ParentProcessID; - break; - } - } while( Process32Next(handle, &pe)); - } - - CloseHandle(handle); - return parent_pid; -} - - -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - int err; - int length; - WCHAR* title_w = NULL; - - uv__once_init(); - - /* Find out how big the buffer for the wide-char title must be */ - length = uv_utf8_to_utf16(title, NULL, 0); - if (!length) { - err = GetLastError(); - goto done; - } - - /* Convert to wide-char string */ - title_w = (WCHAR*)malloc(sizeof(WCHAR) * length); - if (!title_w) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - length = uv_utf8_to_utf16(title, title_w, length); - if (!length) { - err = GetLastError(); - goto done; - }; - - /* If the title must be truncated insert a \0 terminator there */ - if (length > MAX_TITLE_LENGTH) { - title_w[MAX_TITLE_LENGTH - 1] = L'\0'; - } - - if (!SetConsoleTitleW(title_w)) { - err = GetLastError(); - goto done; - } - - EnterCriticalSection(&process_title_lock); - free(process_title); - process_title = strdup(title); - LeaveCriticalSection(&process_title_lock); - - err = 0; - -done: - free(title_w); - return uv_translate_sys_error(err); -} - - -static int uv__get_process_title() { - WCHAR title_w[MAX_TITLE_LENGTH]; - int length; - - if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) { - return -1; - } - - /* Find out what the size of the buffer is that we need */ - length = uv_utf16_to_utf8(title_w, -1, NULL, 0); - if (!length) { - return -1; - } - - assert(!process_title); - process_title = (char*)malloc(length); - if (!process_title) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); - } - - /* Do utf16 -> utf8 conversion here */ - if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) { - free(process_title); - return -1; - } - - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - uv__once_init(); - - EnterCriticalSection(&process_title_lock); - /* - * If the process_title was never read before nor explicitly set, - * we must query it with getConsoleTitleW - */ - if (!process_title && uv__get_process_title() == -1) { - return uv_translate_sys_error(GetLastError()); - } - - assert(process_title); - strncpy(buffer, process_title, size); - LeaveCriticalSection(&process_title_lock); - - return 0; -} - - -uint64_t uv_hrtime(void) { - LARGE_INTEGER counter; - - uv__once_init(); - - /* If the performance frequency is zero, there's no support. */ - if (hrtime_frequency_ == 0) { - /* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */ - return 0; - } - - if (!QueryPerformanceCounter(&counter)) { - /* uv__set_sys_error(loop, GetLastError()); */ - return 0; - } - - /* Because we have no guarantee about the order of magnitude of the - * performance counter frequency, integer math could cause this computation - * to overflow. Therefore we resort to floating point math. - */ - return (uint64_t) ((double) counter.QuadPart / hrtime_frequency_); -} - - -int uv_resident_set_memory(size_t* rss) { - HANDLE current_process; - PROCESS_MEMORY_COUNTERS pmc; - - current_process = GetCurrentProcess(); - - if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) { - return uv_translate_sys_error(GetLastError()); - } - - *rss = pmc.WorkingSetSize; - - return 0; -} - - -int uv_uptime(double* uptime) { - BYTE stack_buffer[4096]; - BYTE* malloced_buffer = NULL; - BYTE* buffer = (BYTE*) stack_buffer; - size_t buffer_size = sizeof(stack_buffer); - DWORD data_size; - - PERF_DATA_BLOCK* data_block; - PERF_OBJECT_TYPE* object_type; - PERF_COUNTER_DEFINITION* counter_definition; - - DWORD i; - - for (;;) { - LONG result; - - data_size = (DWORD) buffer_size; - result = RegQueryValueExW(HKEY_PERFORMANCE_DATA, - L"2", - NULL, - NULL, - buffer, - &data_size); - if (result == ERROR_SUCCESS) { - break; - } else if (result != ERROR_MORE_DATA) { - *uptime = 0; - return uv_translate_sys_error(result); - } - - free(malloced_buffer); - - buffer_size *= 2; - /* Don't let the buffer grow infinitely. */ - if (buffer_size > 1 << 20) { - goto internalError; - } - - buffer = malloced_buffer = (BYTE*) malloc(buffer_size); - if (malloced_buffer == NULL) { - *uptime = 0; - return UV_ENOMEM; - } - } - - if (data_size < sizeof(*data_block)) - goto internalError; - - data_block = (PERF_DATA_BLOCK*) buffer; - - if (wmemcmp(data_block->Signature, L"PERF", 4) != 0) - goto internalError; - - if (data_size < data_block->HeaderLength + sizeof(*object_type)) - goto internalError; - - object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength); - - if (object_type->NumInstances != PERF_NO_INSTANCES) - goto internalError; - - counter_definition = (PERF_COUNTER_DEFINITION*) (buffer + - data_block->HeaderLength + object_type->HeaderLength); - for (i = 0; i < object_type->NumCounters; i++) { - if ((BYTE*) counter_definition + sizeof(*counter_definition) > - buffer + data_size) { - break; - } - - if (counter_definition->CounterNameTitleIndex == 674 && - counter_definition->CounterSize == sizeof(uint64_t)) { - if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size || - !(counter_definition->CounterType & PERF_OBJECT_TIMER)) { - goto internalError; - } else { - BYTE* address = (BYTE*) object_type + object_type->DefinitionLength + - counter_definition->CounterOffset; - uint64_t value = *((uint64_t*) address); - *uptime = (double) (object_type->PerfTime.QuadPart - value) / - (double) object_type->PerfFreq.QuadPart; - free(malloced_buffer); - return 0; - } - } - - counter_definition = (PERF_COUNTER_DEFINITION*) - ((BYTE*) counter_definition + counter_definition->ByteLength); - } - - /* If we get here, the uptime value was not found. */ - free(malloced_buffer); - *uptime = 0; - return UV_ENOSYS; - - internalError: - free(malloced_buffer); - *uptime = 0; - return UV_EIO; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { - uv_cpu_info_t* cpu_infos; - SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; - DWORD sppi_size; - SYSTEM_INFO system_info; - DWORD cpu_count, r, i; - NTSTATUS status; - ULONG result_size; - int err; - uv_cpu_info_t* cpu_info; - - cpu_infos = NULL; - cpu_count = 0; - sppi = NULL; - - uv__once_init(); - - GetSystemInfo(&system_info); - cpu_count = system_info.dwNumberOfProcessors; - - cpu_infos = calloc(cpu_count, sizeof *cpu_infos); - if (cpu_infos == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - sppi_size = cpu_count * sizeof(*sppi); - sppi = malloc(sppi_size); - if (sppi == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, - sppi, - sppi_size, - &result_size); - if (!NT_SUCCESS(status)) { - err = pRtlNtStatusToDosError(status); - goto error; - } - - assert(result_size == sppi_size); - - for (i = 0; i < cpu_count; i++) { - WCHAR key_name[128]; - HKEY processor_key; - DWORD cpu_speed; - DWORD cpu_speed_size = sizeof(cpu_speed); - WCHAR cpu_brand[256]; - DWORD cpu_brand_size = sizeof(cpu_brand); - int len; - - len = _snwprintf(key_name, - ARRAY_SIZE(key_name), - L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", - i); - - assert(len > 0 && len < ARRAY_SIZE(key_name)); - - r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, - key_name, - 0, - KEY_QUERY_VALUE, - &processor_key); - if (r != ERROR_SUCCESS) { - err = GetLastError(); - goto error; - } - - if (RegQueryValueExW(processor_key, - L"~MHz", - NULL, - NULL, - (BYTE*) &cpu_speed, - &cpu_speed_size) != ERROR_SUCCESS) { - err = GetLastError(); - RegCloseKey(processor_key); - goto error; - } - - if (RegQueryValueExW(processor_key, - L"ProcessorNameString", - NULL, - NULL, - (BYTE*) &cpu_brand, - &cpu_brand_size) != ERROR_SUCCESS) { - err = GetLastError(); - RegCloseKey(processor_key); - goto error; - } - - RegCloseKey(processor_key); - - cpu_info = &cpu_infos[i]; - cpu_info->speed = cpu_speed; - cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; - cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - - sppi[i].IdleTime.QuadPart) / 10000; - cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; - cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; - cpu_info->cpu_times.nice = 0; - - - len = WideCharToMultiByte(CP_UTF8, - 0, - cpu_brand, - cpu_brand_size / sizeof(WCHAR), - NULL, - 0, - NULL, - NULL); - if (len == 0) { - err = GetLastError(); - goto error; - } - - assert(len > 0); - - /* Allocate 1 extra byte for the null terminator. */ - cpu_info->model = malloc(len + 1); - if (cpu_info->model == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - if (WideCharToMultiByte(CP_UTF8, - 0, - cpu_brand, - cpu_brand_size / sizeof(WCHAR), - cpu_info->model, - len, - NULL, - NULL) == 0) { - err = GetLastError(); - goto error; - } - - /* Ensure that cpu_info->model is null terminated. */ - cpu_info->model[len] = '\0'; - } - - free(sppi); - - *cpu_count_ptr = cpu_count; - *cpu_infos_ptr = cpu_infos; - - return 0; - - error: - /* This is safe because the cpu_infos array is zeroed on allocation. */ - for (i = 0; i < cpu_count; i++) - free(cpu_infos[i].model); - - free(cpu_infos); - free(sppi); - - return uv_translate_sys_error(err); -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - free(cpu_infos[i].model); - } - - free(cpu_infos); -} - - -int uv_interface_addresses(uv_interface_address_t** addresses_ptr, - int* count_ptr) { - IP_ADAPTER_ADDRESSES* win_address_buf; - ULONG win_address_buf_size; - IP_ADAPTER_ADDRESSES* win_address; - - uv_interface_address_t* uv_address_buf; - char* name_buf; - size_t uv_address_buf_size; - uv_interface_address_t* uv_address; - - int count; - - /* Fetch the size of the adapters reported by windows, and then get the */ - /* list itself. */ - win_address_buf_size = 0; - win_address_buf = NULL; - - for (;;) { - ULONG r; - - /* If win_address_buf is 0, then GetAdaptersAddresses will fail with */ - /* ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in */ - /* win_address_buf_size. */ - r = GetAdaptersAddresses(AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX, - NULL, - win_address_buf, - &win_address_buf_size); - - if (r == ERROR_SUCCESS) - break; - - free(win_address_buf); - - switch (r) { - case ERROR_BUFFER_OVERFLOW: - /* This happens when win_address_buf is NULL or too small to hold */ - /* all adapters. */ - win_address_buf = malloc(win_address_buf_size); - if (win_address_buf == NULL) - return UV_ENOMEM; - - continue; - - case ERROR_NO_DATA: { - /* No adapters were found. */ - uv_address_buf = malloc(1); - if (uv_address_buf == NULL) - return UV_ENOMEM; - - *count_ptr = 0; - *addresses_ptr = uv_address_buf; - - return 0; - } - - case ERROR_ADDRESS_NOT_ASSOCIATED: - return UV_EAGAIN; - - case ERROR_INVALID_PARAMETER: - /* MSDN says: - * "This error is returned for any of the following conditions: the - * SizePointer parameter is NULL, the Address parameter is not - * AF_INET, AF_INET6, or AF_UNSPEC, or the address information for - * the parameters requested is greater than ULONG_MAX." - * Since the first two conditions are not met, it must be that the - * adapter data is too big. - */ - return UV_ENOBUFS; - - default: - /* Other (unspecified) errors can happen, but we don't have any */ - /* special meaning for them. */ - assert(r != ERROR_SUCCESS); - return uv_translate_sys_error(r); - } - } - - /* Count the number of enabled interfaces and compute how much space is */ - /* needed to store their info. */ - count = 0; - uv_address_buf_size = 0; - - for (win_address = win_address_buf; - win_address != NULL; - win_address = win_address->Next) { - /* Use IP_ADAPTER_UNICAST_ADDRESS_XP to retain backwards compatibility */ - /* with Windows XP */ - IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address; - int name_size; - - /* Interfaces that are not 'up' should not be reported. Also skip */ - /* interfaces that have no associated unicast address, as to avoid */ - /* allocating space for the name for this interface. */ - if (win_address->OperStatus != IfOperStatusUp || - win_address->FirstUnicastAddress == NULL) - continue; - - /* Compute the size of the interface name. */ - name_size = WideCharToMultiByte(CP_UTF8, - 0, - win_address->FriendlyName, - -1, - NULL, - 0, - NULL, - FALSE); - if (name_size <= 0) { - free(win_address_buf); - return uv_translate_sys_error(GetLastError()); - } - uv_address_buf_size += name_size; - - /* Count the number of addresses associated with this interface, and */ - /* compute the size. */ - for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*) - win_address->FirstUnicastAddress; - unicast_address != NULL; - unicast_address = unicast_address->Next) { - count++; - uv_address_buf_size += sizeof(uv_interface_address_t); - } - } - - /* Allocate space to store interface data plus adapter names. */ - uv_address_buf = malloc(uv_address_buf_size); - if (uv_address_buf == NULL) { - free(win_address_buf); - return UV_ENOMEM; - } - - /* Compute the start of the uv_interface_address_t array, and the place in */ - /* the buffer where the interface names will be stored. */ - uv_address = uv_address_buf; - name_buf = (char*) (uv_address_buf + count); - - /* Fill out the output buffer. */ - for (win_address = win_address_buf; - win_address != NULL; - win_address = win_address->Next) { - IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address; - IP_ADAPTER_PREFIX* prefix; - int name_size; - size_t max_name_size; - - if (win_address->OperStatus != IfOperStatusUp || - win_address->FirstUnicastAddress == NULL) - continue; - - /* Convert the interface name to UTF8. */ - max_name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf; - if (max_name_size > (size_t) INT_MAX) - max_name_size = INT_MAX; - name_size = WideCharToMultiByte(CP_UTF8, - 0, - win_address->FriendlyName, - -1, - name_buf, - (int) max_name_size, - NULL, - FALSE); - if (name_size <= 0) { - free(win_address_buf); - free(uv_address_buf); - return uv_translate_sys_error(GetLastError()); - } - - prefix = win_address->FirstPrefix; - - /* Add an uv_interface_address_t element for every unicast address. */ - /* Walk the prefix list in tandem with the address list. */ - for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*) - win_address->FirstUnicastAddress; - unicast_address != NULL && prefix != NULL; - unicast_address = unicast_address->Next, prefix = prefix->Next) { - struct sockaddr* sa; - ULONG prefix_len; - - sa = unicast_address->Address.lpSockaddr; - prefix_len = prefix->PrefixLength; - - memset(uv_address, 0, sizeof *uv_address); - - uv_address->name = name_buf; - - if (win_address->PhysicalAddressLength == sizeof(uv_address->phys_addr)) { - memcpy(uv_address->phys_addr, - win_address->PhysicalAddress, - sizeof(uv_address->phys_addr)); - } - - uv_address->is_internal = - (win_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK); - - if (sa->sa_family == AF_INET6) { - uv_address->address.address6 = *((struct sockaddr_in6 *) sa); - - uv_address->netmask.netmask6.sin6_family = AF_INET6; - memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3); - uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] = - 0xff << (8 - prefix_len % 8); - - } else { - uv_address->address.address4 = *((struct sockaddr_in *) sa); - - uv_address->netmask.netmask4.sin_family = AF_INET; - uv_address->netmask.netmask4.sin_addr.s_addr = - htonl(0xffffffff << (32 - prefix_len)); - } - - uv_address++; - } - - name_buf += name_size; - } - - free(win_address_buf); - - *addresses_ptr = uv_address_buf; - *count_ptr = count; - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - free(addresses); -} diff --git a/third-party/libuv/src/win/winapi.c b/third-party/libuv/src/win/winapi.c deleted file mode 100644 index 3e439ea5b2..0000000000 --- a/third-party/libuv/src/win/winapi.c +++ /dev/null @@ -1,159 +0,0 @@ -/* 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 - * 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 <assert.h> - -#include "uv.h" -#include "internal.h" - - -/* Ntdll function pointers */ -sRtlNtStatusToDosError pRtlNtStatusToDosError; -sNtDeviceIoControlFile pNtDeviceIoControlFile; -sNtQueryInformationFile pNtQueryInformationFile; -sNtSetInformationFile pNtSetInformationFile; -sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; -sNtQuerySystemInformation pNtQuerySystemInformation; - - -/* Kernel32 function pointers */ -sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; -sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes; -sCreateSymbolicLinkW pCreateSymbolicLinkW; -sCancelIoEx pCancelIoEx; -sInitializeSRWLock pInitializeSRWLock; -sAcquireSRWLockShared pAcquireSRWLockShared; -sAcquireSRWLockExclusive pAcquireSRWLockExclusive; -sTryAcquireSRWLockShared pTryAcquireSRWLockShared; -sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive; -sReleaseSRWLockShared pReleaseSRWLockShared; -sReleaseSRWLockExclusive pReleaseSRWLockExclusive; -sInitializeConditionVariable pInitializeConditionVariable; -sSleepConditionVariableCS pSleepConditionVariableCS; -sSleepConditionVariableSRW pSleepConditionVariableSRW; -sWakeAllConditionVariable pWakeAllConditionVariable; -sWakeConditionVariable pWakeConditionVariable; - - -void uv_winapi_init() { - HMODULE ntdll_module; - HMODULE kernel32_module; - - ntdll_module = GetModuleHandleA("ntdll.dll"); - if (ntdll_module == NULL) { - uv_fatal_error(GetLastError(), "GetModuleHandleA"); - } - - pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress( - ntdll_module, - "RtlNtStatusToDosError"); - if (pRtlNtStatusToDosError == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtDeviceIoControlFile = (sNtDeviceIoControlFile) GetProcAddress( - ntdll_module, - "NtDeviceIoControlFile"); - if (pNtDeviceIoControlFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQueryInformationFile = (sNtQueryInformationFile) GetProcAddress( - ntdll_module, - "NtQueryInformationFile"); - if (pNtQueryInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtSetInformationFile = (sNtSetInformationFile) GetProcAddress( - ntdll_module, - "NtSetInformationFile"); - if (pNtSetInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQueryVolumeInformationFile = (sNtQueryVolumeInformationFile) - GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile"); - if (pNtQueryVolumeInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress( - ntdll_module, - "NtQuerySystemInformation"); - if (pNtQuerySystemInformation == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - kernel32_module = GetModuleHandleA("kernel32.dll"); - if (kernel32_module == NULL) { - uv_fatal_error(GetLastError(), "GetModuleHandleA"); - } - - pGetQueuedCompletionStatusEx = (sGetQueuedCompletionStatusEx) GetProcAddress( - kernel32_module, - "GetQueuedCompletionStatusEx"); - - pSetFileCompletionNotificationModes = (sSetFileCompletionNotificationModes) - GetProcAddress(kernel32_module, "SetFileCompletionNotificationModes"); - - pCreateSymbolicLinkW = (sCreateSymbolicLinkW) - GetProcAddress(kernel32_module, "CreateSymbolicLinkW"); - - pCancelIoEx = (sCancelIoEx) - GetProcAddress(kernel32_module, "CancelIoEx"); - - pInitializeSRWLock = (sInitializeSRWLock) - GetProcAddress(kernel32_module, "InitializeSRWLock"); - - pAcquireSRWLockShared = (sAcquireSRWLockShared) - GetProcAddress(kernel32_module, "AcquireSRWLockShared"); - - pAcquireSRWLockExclusive = (sAcquireSRWLockExclusive) - GetProcAddress(kernel32_module, "AcquireSRWLockExclusive"); - - pTryAcquireSRWLockShared = (sTryAcquireSRWLockShared) - GetProcAddress(kernel32_module, "TryAcquireSRWLockShared"); - - pTryAcquireSRWLockExclusive = (sTryAcquireSRWLockExclusive) - GetProcAddress(kernel32_module, "TryAcquireSRWLockExclusive"); - - pReleaseSRWLockShared = (sReleaseSRWLockShared) - GetProcAddress(kernel32_module, "ReleaseSRWLockShared"); - - pReleaseSRWLockExclusive = (sReleaseSRWLockExclusive) - GetProcAddress(kernel32_module, "ReleaseSRWLockExclusive"); - - pInitializeConditionVariable = (sInitializeConditionVariable) - GetProcAddress(kernel32_module, "InitializeConditionVariable"); - - pSleepConditionVariableCS = (sSleepConditionVariableCS) - GetProcAddress(kernel32_module, "SleepConditionVariableCS"); - - pSleepConditionVariableSRW = (sSleepConditionVariableSRW) - GetProcAddress(kernel32_module, "SleepConditionVariableSRW"); - - pWakeAllConditionVariable = (sWakeAllConditionVariable) - GetProcAddress(kernel32_module, "WakeAllConditionVariable"); - - pWakeConditionVariable = (sWakeConditionVariable) - GetProcAddress(kernel32_module, "WakeConditionVariable"); -} diff --git a/third-party/libuv/src/win/winapi.h b/third-party/libuv/src/win/winapi.h deleted file mode 100644 index 21d7fe4ac3..0000000000 --- a/third-party/libuv/src/win/winapi.h +++ /dev/null @@ -1,4648 +0,0 @@ -/* 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 - * 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. - */ - -#ifndef UV_WIN_WINAPI_H_ -#define UV_WIN_WINAPI_H_ - -#include <windows.h> - - -/* - * Ntdll headers - */ -#ifndef STATUS_SEVERITY_SUCCESS -# define STATUS_SEVERITY_SUCCESS 0x0 -#endif - -#ifndef STATUS_SEVERITY_INFORMATIONAL -# define STATUS_SEVERITY_INFORMATIONAL 0x1 -#endif - -#ifndef STATUS_SEVERITY_WARNING -# define STATUS_SEVERITY_WARNING 0x2 -#endif - -#ifndef STATUS_SEVERITY_ERROR -# define STATUS_SEVERITY_ERROR 0x3 -#endif - -#ifndef FACILITY_NTWIN32 -# define FACILITY_NTWIN32 0x7 -#endif - -#ifndef NT_SUCCESS -# define NT_SUCCESS(status) (((NTSTATUS) (status)) >= 0) -#endif - -#ifndef NT_INFORMATION -# define NT_INFORMATION(status) ((((ULONG) (status)) >> 30) == 1) -#endif - -#ifndef NT_WARNING -# define NT_WARNING(status) ((((ULONG) (status)) >> 30) == 2) -#endif - -#ifndef NT_ERROR -# define NT_ERROR(status) ((((ULONG) (status)) >> 30) == 3) -#endif - -#ifndef STATUS_SUCCESS -# define STATUS_SUCCESS ((NTSTATUS) 0x00000000L) -#endif - -#ifndef STATUS_WAIT_0 -# define STATUS_WAIT_0 ((NTSTATUS) 0x00000000L) -#endif - -#ifndef STATUS_WAIT_1 -# define STATUS_WAIT_1 ((NTSTATUS) 0x00000001L) -#endif - -#ifndef STATUS_WAIT_2 -# define STATUS_WAIT_2 ((NTSTATUS) 0x00000002L) -#endif - -#ifndef STATUS_WAIT_3 -# define STATUS_WAIT_3 ((NTSTATUS) 0x00000003L) -#endif - -#ifndef STATUS_WAIT_63 -# define STATUS_WAIT_63 ((NTSTATUS) 0x0000003FL) -#endif - -#ifndef STATUS_ABANDONED -# define STATUS_ABANDONED ((NTSTATUS) 0x00000080L) -#endif - -#ifndef STATUS_ABANDONED_WAIT_0 -# define STATUS_ABANDONED_WAIT_0 ((NTSTATUS) 0x00000080L) -#endif - -#ifndef STATUS_ABANDONED_WAIT_63 -# define STATUS_ABANDONED_WAIT_63 ((NTSTATUS) 0x000000BFL) -#endif - -#ifndef STATUS_USER_APC -# define STATUS_USER_APC ((NTSTATUS) 0x000000C0L) -#endif - -#ifndef STATUS_KERNEL_APC -# define STATUS_KERNEL_APC ((NTSTATUS) 0x00000100L) -#endif - -#ifndef STATUS_ALERTED -# define STATUS_ALERTED ((NTSTATUS) 0x00000101L) -#endif - -#ifndef STATUS_TIMEOUT -# define STATUS_TIMEOUT ((NTSTATUS) 0x00000102L) -#endif - -#ifndef STATUS_PENDING -# define STATUS_PENDING ((NTSTATUS) 0x00000103L) -#endif - -#ifndef STATUS_REPARSE -# define STATUS_REPARSE ((NTSTATUS) 0x00000104L) -#endif - -#ifndef STATUS_MORE_ENTRIES -# define STATUS_MORE_ENTRIES ((NTSTATUS) 0x00000105L) -#endif - -#ifndef STATUS_NOT_ALL_ASSIGNED -# define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106L) -#endif - -#ifndef STATUS_SOME_NOT_MAPPED -# define STATUS_SOME_NOT_MAPPED ((NTSTATUS) 0x00000107L) -#endif - -#ifndef STATUS_OPLOCK_BREAK_IN_PROGRESS -# define STATUS_OPLOCK_BREAK_IN_PROGRESS ((NTSTATUS) 0x00000108L) -#endif - -#ifndef STATUS_VOLUME_MOUNTED -# define STATUS_VOLUME_MOUNTED ((NTSTATUS) 0x00000109L) -#endif - -#ifndef STATUS_RXACT_COMMITTED -# define STATUS_RXACT_COMMITTED ((NTSTATUS) 0x0000010AL) -#endif - -#ifndef STATUS_NOTIFY_CLEANUP -# define STATUS_NOTIFY_CLEANUP ((NTSTATUS) 0x0000010BL) -#endif - -#ifndef STATUS_NOTIFY_ENUM_DIR -# define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS) 0x0000010CL) -#endif - -#ifndef STATUS_NO_QUOTAS_FOR_ACCOUNT -# define STATUS_NO_QUOTAS_FOR_ACCOUNT ((NTSTATUS) 0x0000010DL) -#endif - -#ifndef STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED -# define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS) 0x0000010EL) -#endif - -#ifndef STATUS_PAGE_FAULT_TRANSITION -# define STATUS_PAGE_FAULT_TRANSITION ((NTSTATUS) 0x00000110L) -#endif - -#ifndef STATUS_PAGE_FAULT_DEMAND_ZERO -# define STATUS_PAGE_FAULT_DEMAND_ZERO ((NTSTATUS) 0x00000111L) -#endif - -#ifndef STATUS_PAGE_FAULT_COPY_ON_WRITE -# define STATUS_PAGE_FAULT_COPY_ON_WRITE ((NTSTATUS) 0x00000112L) -#endif - -#ifndef STATUS_PAGE_FAULT_GUARD_PAGE -# define STATUS_PAGE_FAULT_GUARD_PAGE ((NTSTATUS) 0x00000113L) -#endif - -#ifndef STATUS_PAGE_FAULT_PAGING_FILE -# define STATUS_PAGE_FAULT_PAGING_FILE ((NTSTATUS) 0x00000114L) -#endif - -#ifndef STATUS_CACHE_PAGE_LOCKED -# define STATUS_CACHE_PAGE_LOCKED ((NTSTATUS) 0x00000115L) -#endif - -#ifndef STATUS_CRASH_DUMP -# define STATUS_CRASH_DUMP ((NTSTATUS) 0x00000116L) -#endif - -#ifndef STATUS_BUFFER_ALL_ZEROS -# define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS) 0x00000117L) -#endif - -#ifndef STATUS_REPARSE_OBJECT -# define STATUS_REPARSE_OBJECT ((NTSTATUS) 0x00000118L) -#endif - -#ifndef STATUS_RESOURCE_REQUIREMENTS_CHANGED -# define STATUS_RESOURCE_REQUIREMENTS_CHANGED ((NTSTATUS) 0x00000119L) -#endif - -#ifndef STATUS_TRANSLATION_COMPLETE -# define STATUS_TRANSLATION_COMPLETE ((NTSTATUS) 0x00000120L) -#endif - -#ifndef STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY -# define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((NTSTATUS) 0x00000121L) -#endif - -#ifndef STATUS_NOTHING_TO_TERMINATE -# define STATUS_NOTHING_TO_TERMINATE ((NTSTATUS) 0x00000122L) -#endif - -#ifndef STATUS_PROCESS_NOT_IN_JOB -# define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS) 0x00000123L) -#endif - -#ifndef STATUS_PROCESS_IN_JOB -# define STATUS_PROCESS_IN_JOB ((NTSTATUS) 0x00000124L) -#endif - -#ifndef STATUS_VOLSNAP_HIBERNATE_READY -# define STATUS_VOLSNAP_HIBERNATE_READY ((NTSTATUS) 0x00000125L) -#endif - -#ifndef STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY -# define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY ((NTSTATUS) 0x00000126L) -#endif - -#ifndef STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED -# define STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED ((NTSTATUS) 0x00000127L) -#endif - -#ifndef STATUS_INTERRUPT_STILL_CONNECTED -# define STATUS_INTERRUPT_STILL_CONNECTED ((NTSTATUS) 0x00000128L) -#endif - -#ifndef STATUS_PROCESS_CLONED -# define STATUS_PROCESS_CLONED ((NTSTATUS) 0x00000129L) -#endif - -#ifndef STATUS_FILE_LOCKED_WITH_ONLY_READERS -# define STATUS_FILE_LOCKED_WITH_ONLY_READERS ((NTSTATUS) 0x0000012AL) -#endif - -#ifndef STATUS_FILE_LOCKED_WITH_WRITERS -# define STATUS_FILE_LOCKED_WITH_WRITERS ((NTSTATUS) 0x0000012BL) -#endif - -#ifndef STATUS_RESOURCEMANAGER_READ_ONLY -# define STATUS_RESOURCEMANAGER_READ_ONLY ((NTSTATUS) 0x00000202L) -#endif - -#ifndef STATUS_RING_PREVIOUSLY_EMPTY -# define STATUS_RING_PREVIOUSLY_EMPTY ((NTSTATUS) 0x00000210L) -#endif - -#ifndef STATUS_RING_PREVIOUSLY_FULL -# define STATUS_RING_PREVIOUSLY_FULL ((NTSTATUS) 0x00000211L) -#endif - -#ifndef STATUS_RING_PREVIOUSLY_ABOVE_QUOTA -# define STATUS_RING_PREVIOUSLY_ABOVE_QUOTA ((NTSTATUS) 0x00000212L) -#endif - -#ifndef STATUS_RING_NEWLY_EMPTY -# define STATUS_RING_NEWLY_EMPTY ((NTSTATUS) 0x00000213L) -#endif - -#ifndef STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT -# define STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT ((NTSTATUS) 0x00000214L) -#endif - -#ifndef STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE -# define STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ((NTSTATUS) 0x00000215L) -#endif - -#ifndef STATUS_OPLOCK_HANDLE_CLOSED -# define STATUS_OPLOCK_HANDLE_CLOSED ((NTSTATUS) 0x00000216L) -#endif - -#ifndef STATUS_WAIT_FOR_OPLOCK -# define STATUS_WAIT_FOR_OPLOCK ((NTSTATUS) 0x00000367L) -#endif - -#ifndef STATUS_OBJECT_NAME_EXISTS -# define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000L) -#endif - -#ifndef STATUS_THREAD_WAS_SUSPENDED -# define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS) 0x40000001L) -#endif - -#ifndef STATUS_WORKING_SET_LIMIT_RANGE -# define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS) 0x40000002L) -#endif - -#ifndef STATUS_IMAGE_NOT_AT_BASE -# define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS) 0x40000003L) -#endif - -#ifndef STATUS_RXACT_STATE_CREATED -# define STATUS_RXACT_STATE_CREATED ((NTSTATUS) 0x40000004L) -#endif - -#ifndef STATUS_SEGMENT_NOTIFICATION -# define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS) 0x40000005L) -#endif - -#ifndef STATUS_LOCAL_USER_SESSION_KEY -# define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS) 0x40000006L) -#endif - -#ifndef STATUS_BAD_CURRENT_DIRECTORY -# define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS) 0x40000007L) -#endif - -#ifndef STATUS_SERIAL_MORE_WRITES -# define STATUS_SERIAL_MORE_WRITES ((NTSTATUS) 0x40000008L) -#endif - -#ifndef STATUS_REGISTRY_RECOVERED -# define STATUS_REGISTRY_RECOVERED ((NTSTATUS) 0x40000009L) -#endif - -#ifndef STATUS_FT_READ_RECOVERY_FROM_BACKUP -# define STATUS_FT_READ_RECOVERY_FROM_BACKUP ((NTSTATUS) 0x4000000AL) -#endif - -#ifndef STATUS_FT_WRITE_RECOVERY -# define STATUS_FT_WRITE_RECOVERY ((NTSTATUS) 0x4000000BL) -#endif - -#ifndef STATUS_SERIAL_COUNTER_TIMEOUT -# define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS) 0x4000000CL) -#endif - -#ifndef STATUS_NULL_LM_PASSWORD -# define STATUS_NULL_LM_PASSWORD ((NTSTATUS) 0x4000000DL) -#endif - -#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH -# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS) 0x4000000EL) -#endif - -#ifndef STATUS_RECEIVE_PARTIAL -# define STATUS_RECEIVE_PARTIAL ((NTSTATUS) 0x4000000FL) -#endif - -#ifndef STATUS_RECEIVE_EXPEDITED -# define STATUS_RECEIVE_EXPEDITED ((NTSTATUS) 0x40000010L) -#endif - -#ifndef STATUS_RECEIVE_PARTIAL_EXPEDITED -# define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS) 0x40000011L) -#endif - -#ifndef STATUS_EVENT_DONE -# define STATUS_EVENT_DONE ((NTSTATUS) 0x40000012L) -#endif - -#ifndef STATUS_EVENT_PENDING -# define STATUS_EVENT_PENDING ((NTSTATUS) 0x40000013L) -#endif - -#ifndef STATUS_CHECKING_FILE_SYSTEM -# define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS) 0x40000014L) -#endif - -#ifndef STATUS_FATAL_APP_EXIT -# define STATUS_FATAL_APP_EXIT ((NTSTATUS) 0x40000015L) -#endif - -#ifndef STATUS_PREDEFINED_HANDLE -# define STATUS_PREDEFINED_HANDLE ((NTSTATUS) 0x40000016L) -#endif - -#ifndef STATUS_WAS_UNLOCKED -# define STATUS_WAS_UNLOCKED ((NTSTATUS) 0x40000017L) -#endif - -#ifndef STATUS_SERVICE_NOTIFICATION -# define STATUS_SERVICE_NOTIFICATION ((NTSTATUS) 0x40000018L) -#endif - -#ifndef STATUS_WAS_LOCKED -# define STATUS_WAS_LOCKED ((NTSTATUS) 0x40000019L) -#endif - -#ifndef STATUS_LOG_HARD_ERROR -# define STATUS_LOG_HARD_ERROR ((NTSTATUS) 0x4000001AL) -#endif - -#ifndef STATUS_ALREADY_WIN32 -# define STATUS_ALREADY_WIN32 ((NTSTATUS) 0x4000001BL) -#endif - -#ifndef STATUS_WX86_UNSIMULATE -# define STATUS_WX86_UNSIMULATE ((NTSTATUS) 0x4000001CL) -#endif - -#ifndef STATUS_WX86_CONTINUE -# define STATUS_WX86_CONTINUE ((NTSTATUS) 0x4000001DL) -#endif - -#ifndef STATUS_WX86_SINGLE_STEP -# define STATUS_WX86_SINGLE_STEP ((NTSTATUS) 0x4000001EL) -#endif - -#ifndef STATUS_WX86_BREAKPOINT -# define STATUS_WX86_BREAKPOINT ((NTSTATUS) 0x4000001FL) -#endif - -#ifndef STATUS_WX86_EXCEPTION_CONTINUE -# define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS) 0x40000020L) -#endif - -#ifndef STATUS_WX86_EXCEPTION_LASTCHANCE -# define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS) 0x40000021L) -#endif - -#ifndef STATUS_WX86_EXCEPTION_CHAIN -# define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS) 0x40000022L) -#endif - -#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE -# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS) 0x40000023L) -#endif - -#ifndef STATUS_NO_YIELD_PERFORMED -# define STATUS_NO_YIELD_PERFORMED ((NTSTATUS) 0x40000024L) -#endif - -#ifndef STATUS_TIMER_RESUME_IGNORED -# define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS) 0x40000025L) -#endif - -#ifndef STATUS_ARBITRATION_UNHANDLED -# define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS) 0x40000026L) -#endif - -#ifndef STATUS_CARDBUS_NOT_SUPPORTED -# define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS) 0x40000027L) -#endif - -#ifndef STATUS_WX86_CREATEWX86TIB -# define STATUS_WX86_CREATEWX86TIB ((NTSTATUS) 0x40000028L) -#endif - -#ifndef STATUS_MP_PROCESSOR_MISMATCH -# define STATUS_MP_PROCESSOR_MISMATCH ((NTSTATUS) 0x40000029L) -#endif - -#ifndef STATUS_HIBERNATED -# define STATUS_HIBERNATED ((NTSTATUS) 0x4000002AL) -#endif - -#ifndef STATUS_RESUME_HIBERNATION -# define STATUS_RESUME_HIBERNATION ((NTSTATUS) 0x4000002BL) -#endif - -#ifndef STATUS_FIRMWARE_UPDATED -# define STATUS_FIRMWARE_UPDATED ((NTSTATUS) 0x4000002CL) -#endif - -#ifndef STATUS_DRIVERS_LEAKING_LOCKED_PAGES -# define STATUS_DRIVERS_LEAKING_LOCKED_PAGES ((NTSTATUS) 0x4000002DL) -#endif - -#ifndef STATUS_MESSAGE_RETRIEVED -# define STATUS_MESSAGE_RETRIEVED ((NTSTATUS) 0x4000002EL) -#endif - -#ifndef STATUS_SYSTEM_POWERSTATE_TRANSITION -# define STATUS_SYSTEM_POWERSTATE_TRANSITION ((NTSTATUS) 0x4000002FL) -#endif - -#ifndef STATUS_ALPC_CHECK_COMPLETION_LIST -# define STATUS_ALPC_CHECK_COMPLETION_LIST ((NTSTATUS) 0x40000030L) -#endif - -#ifndef STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION -# define STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION ((NTSTATUS) 0x40000031L) -#endif - -#ifndef STATUS_ACCESS_AUDIT_BY_POLICY -# define STATUS_ACCESS_AUDIT_BY_POLICY ((NTSTATUS) 0x40000032L) -#endif - -#ifndef STATUS_ABANDON_HIBERFILE -# define STATUS_ABANDON_HIBERFILE ((NTSTATUS) 0x40000033L) -#endif - -#ifndef STATUS_BIZRULES_NOT_ENABLED -# define STATUS_BIZRULES_NOT_ENABLED ((NTSTATUS) 0x40000034L) -#endif - -#ifndef STATUS_GUARD_PAGE_VIOLATION -# define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS) 0x80000001L) -#endif - -#ifndef STATUS_DATATYPE_MISALIGNMENT -# define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS) 0x80000002L) -#endif - -#ifndef STATUS_BREAKPOINT -# define STATUS_BREAKPOINT ((NTSTATUS) 0x80000003L) -#endif - -#ifndef STATUS_SINGLE_STEP -# define STATUS_SINGLE_STEP ((NTSTATUS) 0x80000004L) -#endif - -#ifndef STATUS_BUFFER_OVERFLOW -# define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005L) -#endif - -#ifndef STATUS_NO_MORE_FILES -# define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006L) -#endif - -#ifndef STATUS_WAKE_SYSTEM_DEBUGGER -# define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS) 0x80000007L) -#endif - -#ifndef STATUS_HANDLES_CLOSED -# define STATUS_HANDLES_CLOSED ((NTSTATUS) 0x8000000AL) -#endif - -#ifndef STATUS_NO_INHERITANCE -# define STATUS_NO_INHERITANCE ((NTSTATUS) 0x8000000BL) -#endif - -#ifndef STATUS_GUID_SUBSTITUTION_MADE -# define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS) 0x8000000CL) -#endif - -#ifndef STATUS_PARTIAL_COPY -# define STATUS_PARTIAL_COPY ((NTSTATUS) 0x8000000DL) -#endif - -#ifndef STATUS_DEVICE_PAPER_EMPTY -# define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS) 0x8000000EL) -#endif - -#ifndef STATUS_DEVICE_POWERED_OFF -# define STATUS_DEVICE_POWERED_OFF ((NTSTATUS) 0x8000000FL) -#endif - -#ifndef STATUS_DEVICE_OFF_LINE -# define STATUS_DEVICE_OFF_LINE ((NTSTATUS) 0x80000010L) -#endif - -#ifndef STATUS_DEVICE_BUSY -# define STATUS_DEVICE_BUSY ((NTSTATUS) 0x80000011L) -#endif - -#ifndef STATUS_NO_MORE_EAS -# define STATUS_NO_MORE_EAS ((NTSTATUS) 0x80000012L) -#endif - -#ifndef STATUS_INVALID_EA_NAME -# define STATUS_INVALID_EA_NAME ((NTSTATUS) 0x80000013L) -#endif - -#ifndef STATUS_EA_LIST_INCONSISTENT -# define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS) 0x80000014L) -#endif - -#ifndef STATUS_INVALID_EA_FLAG -# define STATUS_INVALID_EA_FLAG ((NTSTATUS) 0x80000015L) -#endif - -#ifndef STATUS_VERIFY_REQUIRED -# define STATUS_VERIFY_REQUIRED ((NTSTATUS) 0x80000016L) -#endif - -#ifndef STATUS_EXTRANEOUS_INFORMATION -# define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS) 0x80000017L) -#endif - -#ifndef STATUS_RXACT_COMMIT_NECESSARY -# define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS) 0x80000018L) -#endif - -#ifndef STATUS_NO_MORE_ENTRIES -# define STATUS_NO_MORE_ENTRIES ((NTSTATUS) 0x8000001AL) -#endif - -#ifndef STATUS_FILEMARK_DETECTED -# define STATUS_FILEMARK_DETECTED ((NTSTATUS) 0x8000001BL) -#endif - -#ifndef STATUS_MEDIA_CHANGED -# define STATUS_MEDIA_CHANGED ((NTSTATUS) 0x8000001CL) -#endif - -#ifndef STATUS_BUS_RESET -# define STATUS_BUS_RESET ((NTSTATUS) 0x8000001DL) -#endif - -#ifndef STATUS_END_OF_MEDIA -# define STATUS_END_OF_MEDIA ((NTSTATUS) 0x8000001EL) -#endif - -#ifndef STATUS_BEGINNING_OF_MEDIA -# define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS) 0x8000001FL) -#endif - -#ifndef STATUS_MEDIA_CHECK -# define STATUS_MEDIA_CHECK ((NTSTATUS) 0x80000020L) -#endif - -#ifndef STATUS_SETMARK_DETECTED -# define STATUS_SETMARK_DETECTED ((NTSTATUS) 0x80000021L) -#endif - -#ifndef STATUS_NO_DATA_DETECTED -# define STATUS_NO_DATA_DETECTED ((NTSTATUS) 0x80000022L) -#endif - -#ifndef STATUS_REDIRECTOR_HAS_OPEN_HANDLES -# define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000023L) -#endif - -#ifndef STATUS_SERVER_HAS_OPEN_HANDLES -# define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000024L) -#endif - -#ifndef STATUS_ALREADY_DISCONNECTED -# define STATUS_ALREADY_DISCONNECTED ((NTSTATUS) 0x80000025L) -#endif - -#ifndef STATUS_LONGJUMP -# define STATUS_LONGJUMP ((NTSTATUS) 0x80000026L) -#endif - -#ifndef STATUS_CLEANER_CARTRIDGE_INSTALLED -# define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS) 0x80000027L) -#endif - -#ifndef STATUS_PLUGPLAY_QUERY_VETOED -# define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS) 0x80000028L) -#endif - -#ifndef STATUS_UNWIND_CONSOLIDATE -# define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS) 0x80000029L) -#endif - -#ifndef STATUS_REGISTRY_HIVE_RECOVERED -# define STATUS_REGISTRY_HIVE_RECOVERED ((NTSTATUS) 0x8000002AL) -#endif - -#ifndef STATUS_DLL_MIGHT_BE_INSECURE -# define STATUS_DLL_MIGHT_BE_INSECURE ((NTSTATUS) 0x8000002BL) -#endif - -#ifndef STATUS_DLL_MIGHT_BE_INCOMPATIBLE -# define STATUS_DLL_MIGHT_BE_INCOMPATIBLE ((NTSTATUS) 0x8000002CL) -#endif - -#ifndef STATUS_STOPPED_ON_SYMLINK -# define STATUS_STOPPED_ON_SYMLINK ((NTSTATUS) 0x8000002DL) -#endif - -#ifndef STATUS_CANNOT_GRANT_REQUESTED_OPLOCK -# define STATUS_CANNOT_GRANT_REQUESTED_OPLOCK ((NTSTATUS) 0x8000002EL) -#endif - -#ifndef STATUS_NO_ACE_CONDITION -# define STATUS_NO_ACE_CONDITION ((NTSTATUS) 0x8000002FL) -#endif - -#ifndef STATUS_UNSUCCESSFUL -# define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L) -#endif - -#ifndef STATUS_NOT_IMPLEMENTED -# define STATUS_NOT_IMPLEMENTED ((NTSTATUS) 0xC0000002L) -#endif - -#ifndef STATUS_INVALID_INFO_CLASS -# define STATUS_INVALID_INFO_CLASS ((NTSTATUS) 0xC0000003L) -#endif - -#ifndef STATUS_INFO_LENGTH_MISMATCH -# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004L) -#endif - -#ifndef STATUS_ACCESS_VIOLATION -# define STATUS_ACCESS_VIOLATION ((NTSTATUS) 0xC0000005L) -#endif - -#ifndef STATUS_IN_PAGE_ERROR -# define STATUS_IN_PAGE_ERROR ((NTSTATUS) 0xC0000006L) -#endif - -#ifndef STATUS_PAGEFILE_QUOTA -# define STATUS_PAGEFILE_QUOTA ((NTSTATUS) 0xC0000007L) -#endif - -#ifndef STATUS_INVALID_HANDLE -# define STATUS_INVALID_HANDLE ((NTSTATUS) 0xC0000008L) -#endif - -#ifndef STATUS_BAD_INITIAL_STACK -# define STATUS_BAD_INITIAL_STACK ((NTSTATUS) 0xC0000009L) -#endif - -#ifndef STATUS_BAD_INITIAL_PC -# define STATUS_BAD_INITIAL_PC ((NTSTATUS) 0xC000000AL) -#endif - -#ifndef STATUS_INVALID_CID -# define STATUS_INVALID_CID ((NTSTATUS) 0xC000000BL) -#endif - -#ifndef STATUS_TIMER_NOT_CANCELED -# define STATUS_TIMER_NOT_CANCELED ((NTSTATUS) 0xC000000CL) -#endif - -#ifndef STATUS_INVALID_PARAMETER -# define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000DL) -#endif - -#ifndef STATUS_NO_SUCH_DEVICE -# define STATUS_NO_SUCH_DEVICE ((NTSTATUS) 0xC000000EL) -#endif - -#ifndef STATUS_NO_SUCH_FILE -# define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xC000000FL) -#endif - -#ifndef STATUS_INVALID_DEVICE_REQUEST -# define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xC0000010L) -#endif - -#ifndef STATUS_END_OF_FILE -# define STATUS_END_OF_FILE ((NTSTATUS) 0xC0000011L) -#endif - -#ifndef STATUS_WRONG_VOLUME -# define STATUS_WRONG_VOLUME ((NTSTATUS) 0xC0000012L) -#endif - -#ifndef STATUS_NO_MEDIA_IN_DEVICE -# define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xC0000013L) -#endif - -#ifndef STATUS_UNRECOGNIZED_MEDIA -# define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS) 0xC0000014L) -#endif - -#ifndef STATUS_NONEXISTENT_SECTOR -# define STATUS_NONEXISTENT_SECTOR ((NTSTATUS) 0xC0000015L) -#endif - -#ifndef STATUS_MORE_PROCESSING_REQUIRED -# define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS) 0xC0000016L) -#endif - -#ifndef STATUS_NO_MEMORY -# define STATUS_NO_MEMORY ((NTSTATUS) 0xC0000017L) -#endif - -#ifndef STATUS_CONFLICTING_ADDRESSES -# define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS) 0xC0000018L) -#endif - -#ifndef STATUS_NOT_MAPPED_VIEW -# define STATUS_NOT_MAPPED_VIEW ((NTSTATUS) 0xC0000019L) -#endif - -#ifndef STATUS_UNABLE_TO_FREE_VM -# define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS) 0xC000001AL) -#endif - -#ifndef STATUS_UNABLE_TO_DELETE_SECTION -# define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS) 0xC000001BL) -#endif - -#ifndef STATUS_INVALID_SYSTEM_SERVICE -# define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS) 0xC000001CL) -#endif - -#ifndef STATUS_ILLEGAL_INSTRUCTION -# define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS) 0xC000001DL) -#endif - -#ifndef STATUS_INVALID_LOCK_SEQUENCE -# define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS) 0xC000001EL) -#endif - -#ifndef STATUS_INVALID_VIEW_SIZE -# define STATUS_INVALID_VIEW_SIZE ((NTSTATUS) 0xC000001FL) -#endif - -#ifndef STATUS_INVALID_FILE_FOR_SECTION -# define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS) 0xC0000020L) -#endif - -#ifndef STATUS_ALREADY_COMMITTED -# define STATUS_ALREADY_COMMITTED ((NTSTATUS) 0xC0000021L) -#endif - -#ifndef STATUS_ACCESS_DENIED -# define STATUS_ACCESS_DENIED ((NTSTATUS) 0xC0000022L) -#endif - -#ifndef STATUS_BUFFER_TOO_SMALL -# define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xC0000023L) -#endif - -#ifndef STATUS_OBJECT_TYPE_MISMATCH -# define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS) 0xC0000024L) -#endif - -#ifndef STATUS_NONCONTINUABLE_EXCEPTION -# define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS) 0xC0000025L) -#endif - -#ifndef STATUS_INVALID_DISPOSITION -# define STATUS_INVALID_DISPOSITION ((NTSTATUS) 0xC0000026L) -#endif - -#ifndef STATUS_UNWIND -# define STATUS_UNWIND ((NTSTATUS) 0xC0000027L) -#endif - -#ifndef STATUS_BAD_STACK -# define STATUS_BAD_STACK ((NTSTATUS) 0xC0000028L) -#endif - -#ifndef STATUS_INVALID_UNWIND_TARGET -# define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS) 0xC0000029L) -#endif - -#ifndef STATUS_NOT_LOCKED -# define STATUS_NOT_LOCKED ((NTSTATUS) 0xC000002AL) -#endif - -#ifndef STATUS_PARITY_ERROR -# define STATUS_PARITY_ERROR ((NTSTATUS) 0xC000002BL) -#endif - -#ifndef STATUS_UNABLE_TO_DECOMMIT_VM -# define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS) 0xC000002CL) -#endif - -#ifndef STATUS_NOT_COMMITTED -# define STATUS_NOT_COMMITTED ((NTSTATUS) 0xC000002DL) -#endif - -#ifndef STATUS_INVALID_PORT_ATTRIBUTES -# define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS) 0xC000002EL) -#endif - -#ifndef STATUS_PORT_MESSAGE_TOO_LONG -# define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS) 0xC000002FL) -#endif - -#ifndef STATUS_INVALID_PARAMETER_MIX -# define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS) 0xC0000030L) -#endif - -#ifndef STATUS_INVALID_QUOTA_LOWER -# define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS) 0xC0000031L) -#endif - -#ifndef STATUS_DISK_CORRUPT_ERROR -# define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L) -#endif - -#ifndef STATUS_OBJECT_NAME_INVALID -# define STATUS_OBJECT_NAME_INVALID ((NTSTATUS) 0xC0000033L) -#endif - -#ifndef STATUS_OBJECT_NAME_NOT_FOUND -# define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xC0000034L) -#endif - -#ifndef STATUS_OBJECT_NAME_COLLISION -# define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS) 0xC0000035L) -#endif - -#ifndef STATUS_PORT_DISCONNECTED -# define STATUS_PORT_DISCONNECTED ((NTSTATUS) 0xC0000037L) -#endif - -#ifndef STATUS_DEVICE_ALREADY_ATTACHED -# define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L) -#endif - -#ifndef STATUS_OBJECT_PATH_INVALID -# define STATUS_OBJECT_PATH_INVALID ((NTSTATUS) 0xC0000039L) -#endif - -#ifndef STATUS_OBJECT_PATH_NOT_FOUND -# define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xC000003AL) -#endif - -#ifndef STATUS_OBJECT_PATH_SYNTAX_BAD -# define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS) 0xC000003BL) -#endif - -#ifndef STATUS_DATA_OVERRUN -# define STATUS_DATA_OVERRUN ((NTSTATUS) 0xC000003CL) -#endif - -#ifndef STATUS_DATA_LATE_ERROR -# define STATUS_DATA_LATE_ERROR ((NTSTATUS) 0xC000003DL) -#endif - -#ifndef STATUS_DATA_ERROR -# define STATUS_DATA_ERROR ((NTSTATUS) 0xC000003EL) -#endif - -#ifndef STATUS_CRC_ERROR -# define STATUS_CRC_ERROR ((NTSTATUS) 0xC000003FL) -#endif - -#ifndef STATUS_SECTION_TOO_BIG -# define STATUS_SECTION_TOO_BIG ((NTSTATUS) 0xC0000040L) -#endif - -#ifndef STATUS_PORT_CONNECTION_REFUSED -# define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS) 0xC0000041L) -#endif - -#ifndef STATUS_INVALID_PORT_HANDLE -# define STATUS_INVALID_PORT_HANDLE ((NTSTATUS) 0xC0000042L) -#endif - -#ifndef STATUS_SHARING_VIOLATION -# define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xC0000043L) -#endif - -#ifndef STATUS_QUOTA_EXCEEDED -# define STATUS_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000044L) -#endif - -#ifndef STATUS_INVALID_PAGE_PROTECTION -# define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS) 0xC0000045L) -#endif - -#ifndef STATUS_MUTANT_NOT_OWNED -# define STATUS_MUTANT_NOT_OWNED ((NTSTATUS) 0xC0000046L) -#endif - -#ifndef STATUS_SEMAPHORE_LIMIT_EXCEEDED -# define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000047L) -#endif - -#ifndef STATUS_PORT_ALREADY_SET -# define STATUS_PORT_ALREADY_SET ((NTSTATUS) 0xC0000048L) -#endif - -#ifndef STATUS_SECTION_NOT_IMAGE -# define STATUS_SECTION_NOT_IMAGE ((NTSTATUS) 0xC0000049L) -#endif - -#ifndef STATUS_SUSPEND_COUNT_EXCEEDED -# define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS) 0xC000004AL) -#endif - -#ifndef STATUS_THREAD_IS_TERMINATING -# define STATUS_THREAD_IS_TERMINATING ((NTSTATUS) 0xC000004BL) -#endif - -#ifndef STATUS_BAD_WORKING_SET_LIMIT -# define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS) 0xC000004CL) -#endif - -#ifndef STATUS_INCOMPATIBLE_FILE_MAP -# define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS) 0xC000004DL) -#endif - -#ifndef STATUS_SECTION_PROTECTION -# define STATUS_SECTION_PROTECTION ((NTSTATUS) 0xC000004EL) -#endif - -#ifndef STATUS_EAS_NOT_SUPPORTED -# define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS) 0xC000004FL) -#endif - -#ifndef STATUS_EA_TOO_LARGE -# define STATUS_EA_TOO_LARGE ((NTSTATUS) 0xC0000050L) -#endif - -#ifndef STATUS_NONEXISTENT_EA_ENTRY -# define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS) 0xC0000051L) -#endif - -#ifndef STATUS_NO_EAS_ON_FILE -# define STATUS_NO_EAS_ON_FILE ((NTSTATUS) 0xC0000052L) -#endif - -#ifndef STATUS_EA_CORRUPT_ERROR -# define STATUS_EA_CORRUPT_ERROR ((NTSTATUS) 0xC0000053L) -#endif - -#ifndef STATUS_FILE_LOCK_CONFLICT -# define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS) 0xC0000054L) -#endif - -#ifndef STATUS_LOCK_NOT_GRANTED -# define STATUS_LOCK_NOT_GRANTED ((NTSTATUS) 0xC0000055L) -#endif - -#ifndef STATUS_DELETE_PENDING -# define STATUS_DELETE_PENDING ((NTSTATUS) 0xC0000056L) -#endif - -#ifndef STATUS_CTL_FILE_NOT_SUPPORTED -# define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS) 0xC0000057L) -#endif - -#ifndef STATUS_UNKNOWN_REVISION -# define STATUS_UNKNOWN_REVISION ((NTSTATUS) 0xC0000058L) -#endif - -#ifndef STATUS_REVISION_MISMATCH -# define STATUS_REVISION_MISMATCH ((NTSTATUS) 0xC0000059L) -#endif - -#ifndef STATUS_INVALID_OWNER -# define STATUS_INVALID_OWNER ((NTSTATUS) 0xC000005AL) -#endif - -#ifndef STATUS_INVALID_PRIMARY_GROUP -# define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS) 0xC000005BL) -#endif - -#ifndef STATUS_NO_IMPERSONATION_TOKEN -# define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS) 0xC000005CL) -#endif - -#ifndef STATUS_CANT_DISABLE_MANDATORY -# define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS) 0xC000005DL) -#endif - -#ifndef STATUS_NO_LOGON_SERVERS -# define STATUS_NO_LOGON_SERVERS ((NTSTATUS) 0xC000005EL) -#endif - -#ifndef STATUS_NO_SUCH_LOGON_SESSION -# define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS) 0xC000005FL) -#endif - -#ifndef STATUS_NO_SUCH_PRIVILEGE -# define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS) 0xC0000060L) -#endif - -#ifndef STATUS_PRIVILEGE_NOT_HELD -# define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS) 0xC0000061L) -#endif - -#ifndef STATUS_INVALID_ACCOUNT_NAME -# define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS) 0xC0000062L) -#endif - -#ifndef STATUS_USER_EXISTS -# define STATUS_USER_EXISTS ((NTSTATUS) 0xC0000063L) -#endif - -#ifndef STATUS_NO_SUCH_USER -# define STATUS_NO_SUCH_USER ((NTSTATUS) 0xC0000064L) -#endif - -#ifndef STATUS_GROUP_EXISTS -# define STATUS_GROUP_EXISTS ((NTSTATUS) 0xC0000065L) -#endif - -#ifndef STATUS_NO_SUCH_GROUP -# define STATUS_NO_SUCH_GROUP ((NTSTATUS) 0xC0000066L) -#endif - -#ifndef STATUS_MEMBER_IN_GROUP -# define STATUS_MEMBER_IN_GROUP ((NTSTATUS) 0xC0000067L) -#endif - -#ifndef STATUS_MEMBER_NOT_IN_GROUP -# define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS) 0xC0000068L) -#endif - -#ifndef STATUS_LAST_ADMIN -# define STATUS_LAST_ADMIN ((NTSTATUS) 0xC0000069L) -#endif - -#ifndef STATUS_WRONG_PASSWORD -# define STATUS_WRONG_PASSWORD ((NTSTATUS) 0xC000006AL) -#endif - -#ifndef STATUS_ILL_FORMED_PASSWORD -# define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS) 0xC000006BL) -#endif - -#ifndef STATUS_PASSWORD_RESTRICTION -# define STATUS_PASSWORD_RESTRICTION ((NTSTATUS) 0xC000006CL) -#endif - -#ifndef STATUS_LOGON_FAILURE -# define STATUS_LOGON_FAILURE ((NTSTATUS) 0xC000006DL) -#endif - -#ifndef STATUS_ACCOUNT_RESTRICTION -# define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS) 0xC000006EL) -#endif - -#ifndef STATUS_INVALID_LOGON_HOURS -# define STATUS_INVALID_LOGON_HOURS ((NTSTATUS) 0xC000006FL) -#endif - -#ifndef STATUS_INVALID_WORKSTATION -# define STATUS_INVALID_WORKSTATION ((NTSTATUS) 0xC0000070L) -#endif - -#ifndef STATUS_PASSWORD_EXPIRED -# define STATUS_PASSWORD_EXPIRED ((NTSTATUS) 0xC0000071L) -#endif - -#ifndef STATUS_ACCOUNT_DISABLED -# define STATUS_ACCOUNT_DISABLED ((NTSTATUS) 0xC0000072L) -#endif - -#ifndef STATUS_NONE_MAPPED -# define STATUS_NONE_MAPPED ((NTSTATUS) 0xC0000073L) -#endif - -#ifndef STATUS_TOO_MANY_LUIDS_REQUESTED -# define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS) 0xC0000074L) -#endif - -#ifndef STATUS_LUIDS_EXHAUSTED -# define STATUS_LUIDS_EXHAUSTED ((NTSTATUS) 0xC0000075L) -#endif - -#ifndef STATUS_INVALID_SUB_AUTHORITY -# define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS) 0xC0000076L) -#endif - -#ifndef STATUS_INVALID_ACL -# define STATUS_INVALID_ACL ((NTSTATUS) 0xC0000077L) -#endif - -#ifndef STATUS_INVALID_SID -# define STATUS_INVALID_SID ((NTSTATUS) 0xC0000078L) -#endif - -#ifndef STATUS_INVALID_SECURITY_DESCR -# define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS) 0xC0000079L) -#endif - -#ifndef STATUS_PROCEDURE_NOT_FOUND -# define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS) 0xC000007AL) -#endif - -#ifndef STATUS_INVALID_IMAGE_FORMAT -# define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS) 0xC000007BL) -#endif - -#ifndef STATUS_NO_TOKEN -# define STATUS_NO_TOKEN ((NTSTATUS) 0xC000007CL) -#endif - -#ifndef STATUS_BAD_INHERITANCE_ACL -# define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS) 0xC000007DL) -#endif - -#ifndef STATUS_RANGE_NOT_LOCKED -# define STATUS_RANGE_NOT_LOCKED ((NTSTATUS) 0xC000007EL) -#endif - -#ifndef STATUS_DISK_FULL -# define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL) -#endif - -#ifndef STATUS_SERVER_DISABLED -# define STATUS_SERVER_DISABLED ((NTSTATUS) 0xC0000080L) -#endif - -#ifndef STATUS_SERVER_NOT_DISABLED -# define STATUS_SERVER_NOT_DISABLED ((NTSTATUS) 0xC0000081L) -#endif - -#ifndef STATUS_TOO_MANY_GUIDS_REQUESTED -# define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS) 0xC0000082L) -#endif - -#ifndef STATUS_GUIDS_EXHAUSTED -# define STATUS_GUIDS_EXHAUSTED ((NTSTATUS) 0xC0000083L) -#endif - -#ifndef STATUS_INVALID_ID_AUTHORITY -# define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS) 0xC0000084L) -#endif - -#ifndef STATUS_AGENTS_EXHAUSTED -# define STATUS_AGENTS_EXHAUSTED ((NTSTATUS) 0xC0000085L) -#endif - -#ifndef STATUS_INVALID_VOLUME_LABEL -# define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS) 0xC0000086L) -#endif - -#ifndef STATUS_SECTION_NOT_EXTENDED -# define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS) 0xC0000087L) -#endif - -#ifndef STATUS_NOT_MAPPED_DATA -# define STATUS_NOT_MAPPED_DATA ((NTSTATUS) 0xC0000088L) -#endif - -#ifndef STATUS_RESOURCE_DATA_NOT_FOUND -# define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS) 0xC0000089L) -#endif - -#ifndef STATUS_RESOURCE_TYPE_NOT_FOUND -# define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS) 0xC000008AL) -#endif - -#ifndef STATUS_RESOURCE_NAME_NOT_FOUND -# define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS) 0xC000008BL) -#endif - -#ifndef STATUS_ARRAY_BOUNDS_EXCEEDED -# define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS) 0xC000008CL) -#endif - -#ifndef STATUS_FLOAT_DENORMAL_OPERAND -# define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS) 0xC000008DL) -#endif - -#ifndef STATUS_FLOAT_DIVIDE_BY_ZERO -# define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS) 0xC000008EL) -#endif - -#ifndef STATUS_FLOAT_INEXACT_RESULT -# define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS) 0xC000008FL) -#endif - -#ifndef STATUS_FLOAT_INVALID_OPERATION -# define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS) 0xC0000090L) -#endif - -#ifndef STATUS_FLOAT_OVERFLOW -# define STATUS_FLOAT_OVERFLOW ((NTSTATUS) 0xC0000091L) -#endif - -#ifndef STATUS_FLOAT_STACK_CHECK -# define STATUS_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000092L) -#endif - -#ifndef STATUS_FLOAT_UNDERFLOW -# define STATUS_FLOAT_UNDERFLOW ((NTSTATUS) 0xC0000093L) -#endif - -#ifndef STATUS_INTEGER_DIVIDE_BY_ZERO -# define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS) 0xC0000094L) -#endif - -#ifndef STATUS_INTEGER_OVERFLOW -# define STATUS_INTEGER_OVERFLOW ((NTSTATUS) 0xC0000095L) -#endif - -#ifndef STATUS_PRIVILEGED_INSTRUCTION -# define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS) 0xC0000096L) -#endif - -#ifndef STATUS_TOO_MANY_PAGING_FILES -# define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS) 0xC0000097L) -#endif - -#ifndef STATUS_FILE_INVALID -# define STATUS_FILE_INVALID ((NTSTATUS) 0xC0000098L) -#endif - -#ifndef STATUS_ALLOTTED_SPACE_EXCEEDED -# define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS) 0xC0000099L) -#endif - -#ifndef STATUS_INSUFFICIENT_RESOURCES -# define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL) -#endif - -#ifndef STATUS_DFS_EXIT_PATH_FOUND -# define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS) 0xC000009BL) -#endif - -#ifndef STATUS_DEVICE_DATA_ERROR -# define STATUS_DEVICE_DATA_ERROR ((NTSTATUS) 0xC000009CL) -#endif - -#ifndef STATUS_DEVICE_NOT_CONNECTED -# define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS) 0xC000009DL) -#endif - -#ifndef STATUS_DEVICE_POWER_FAILURE -# define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS) 0xC000009EL) -#endif - -#ifndef STATUS_FREE_VM_NOT_AT_BASE -# define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS) 0xC000009FL) -#endif - -#ifndef STATUS_MEMORY_NOT_ALLOCATED -# define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS) 0xC00000A0L) -#endif - -#ifndef STATUS_WORKING_SET_QUOTA -# define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xC00000A1L) -#endif - -#ifndef STATUS_MEDIA_WRITE_PROTECTED -# define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L) -#endif - -#ifndef STATUS_DEVICE_NOT_READY -# define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L) -#endif - -#ifndef STATUS_INVALID_GROUP_ATTRIBUTES -# define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS) 0xC00000A4L) -#endif - -#ifndef STATUS_BAD_IMPERSONATION_LEVEL -# define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS) 0xC00000A5L) -#endif - -#ifndef STATUS_CANT_OPEN_ANONYMOUS -# define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS) 0xC00000A6L) -#endif - -#ifndef STATUS_BAD_VALIDATION_CLASS -# define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS) 0xC00000A7L) -#endif - -#ifndef STATUS_BAD_TOKEN_TYPE -# define STATUS_BAD_TOKEN_TYPE ((NTSTATUS) 0xC00000A8L) -#endif - -#ifndef STATUS_BAD_MASTER_BOOT_RECORD -# define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS) 0xC00000A9L) -#endif - -#ifndef STATUS_INSTRUCTION_MISALIGNMENT -# define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS) 0xC00000AAL) -#endif - -#ifndef STATUS_INSTANCE_NOT_AVAILABLE -# define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ABL) -#endif - -#ifndef STATUS_PIPE_NOT_AVAILABLE -# define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ACL) -#endif - -#ifndef STATUS_INVALID_PIPE_STATE -# define STATUS_INVALID_PIPE_STATE ((NTSTATUS) 0xC00000ADL) -#endif - -#ifndef STATUS_PIPE_BUSY -# define STATUS_PIPE_BUSY ((NTSTATUS) 0xC00000AEL) -#endif - -#ifndef STATUS_ILLEGAL_FUNCTION -# define STATUS_ILLEGAL_FUNCTION ((NTSTATUS) 0xC00000AFL) -#endif - -#ifndef STATUS_PIPE_DISCONNECTED -# define STATUS_PIPE_DISCONNECTED ((NTSTATUS) 0xC00000B0L) -#endif - -#ifndef STATUS_PIPE_CLOSING -# define STATUS_PIPE_CLOSING ((NTSTATUS) 0xC00000B1L) -#endif - -#ifndef STATUS_PIPE_CONNECTED -# define STATUS_PIPE_CONNECTED ((NTSTATUS) 0xC00000B2L) -#endif - -#ifndef STATUS_PIPE_LISTENING -# define STATUS_PIPE_LISTENING ((NTSTATUS) 0xC00000B3L) -#endif - -#ifndef STATUS_INVALID_READ_MODE -# define STATUS_INVALID_READ_MODE ((NTSTATUS) 0xC00000B4L) -#endif - -#ifndef STATUS_IO_TIMEOUT -# define STATUS_IO_TIMEOUT ((NTSTATUS) 0xC00000B5L) -#endif - -#ifndef STATUS_FILE_FORCED_CLOSED -# define STATUS_FILE_FORCED_CLOSED ((NTSTATUS) 0xC00000B6L) -#endif - -#ifndef STATUS_PROFILING_NOT_STARTED -# define STATUS_PROFILING_NOT_STARTED ((NTSTATUS) 0xC00000B7L) -#endif - -#ifndef STATUS_PROFILING_NOT_STOPPED -# define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS) 0xC00000B8L) -#endif - -#ifndef STATUS_COULD_NOT_INTERPRET -# define STATUS_COULD_NOT_INTERPRET ((NTSTATUS) 0xC00000B9L) -#endif - -#ifndef STATUS_FILE_IS_A_DIRECTORY -# define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS) 0xC00000BAL) -#endif - -#ifndef STATUS_NOT_SUPPORTED -# define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xC00000BBL) -#endif - -#ifndef STATUS_REMOTE_NOT_LISTENING -# define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS) 0xC00000BCL) -#endif - -#ifndef STATUS_DUPLICATE_NAME -# define STATUS_DUPLICATE_NAME ((NTSTATUS) 0xC00000BDL) -#endif - -#ifndef STATUS_BAD_NETWORK_PATH -# define STATUS_BAD_NETWORK_PATH ((NTSTATUS) 0xC00000BEL) -#endif - -#ifndef STATUS_NETWORK_BUSY -# define STATUS_NETWORK_BUSY ((NTSTATUS) 0xC00000BFL) -#endif - -#ifndef STATUS_DEVICE_DOES_NOT_EXIST -# define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS) 0xC00000C0L) -#endif - -#ifndef STATUS_TOO_MANY_COMMANDS -# define STATUS_TOO_MANY_COMMANDS ((NTSTATUS) 0xC00000C1L) -#endif - -#ifndef STATUS_ADAPTER_HARDWARE_ERROR -# define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS) 0xC00000C2L) -#endif - -#ifndef STATUS_INVALID_NETWORK_RESPONSE -# define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS) 0xC00000C3L) -#endif - -#ifndef STATUS_UNEXPECTED_NETWORK_ERROR -# define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS) 0xC00000C4L) -#endif - -#ifndef STATUS_BAD_REMOTE_ADAPTER -# define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS) 0xC00000C5L) -#endif - -#ifndef STATUS_PRINT_QUEUE_FULL -# define STATUS_PRINT_QUEUE_FULL ((NTSTATUS) 0xC00000C6L) -#endif - -#ifndef STATUS_NO_SPOOL_SPACE -# define STATUS_NO_SPOOL_SPACE ((NTSTATUS) 0xC00000C7L) -#endif - -#ifndef STATUS_PRINT_CANCELLED -# define STATUS_PRINT_CANCELLED ((NTSTATUS) 0xC00000C8L) -#endif - -#ifndef STATUS_NETWORK_NAME_DELETED -# define STATUS_NETWORK_NAME_DELETED ((NTSTATUS) 0xC00000C9L) -#endif - -#ifndef STATUS_NETWORK_ACCESS_DENIED -# define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS) 0xC00000CAL) -#endif - -#ifndef STATUS_BAD_DEVICE_TYPE -# define STATUS_BAD_DEVICE_TYPE ((NTSTATUS) 0xC00000CBL) -#endif - -#ifndef STATUS_BAD_NETWORK_NAME -# define STATUS_BAD_NETWORK_NAME ((NTSTATUS) 0xC00000CCL) -#endif - -#ifndef STATUS_TOO_MANY_NAMES -# define STATUS_TOO_MANY_NAMES ((NTSTATUS) 0xC00000CDL) -#endif - -#ifndef STATUS_TOO_MANY_SESSIONS -# define STATUS_TOO_MANY_SESSIONS ((NTSTATUS) 0xC00000CEL) -#endif - -#ifndef STATUS_SHARING_PAUSED -# define STATUS_SHARING_PAUSED ((NTSTATUS) 0xC00000CFL) -#endif - -#ifndef STATUS_REQUEST_NOT_ACCEPTED -# define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS) 0xC00000D0L) -#endif - -#ifndef STATUS_REDIRECTOR_PAUSED -# define STATUS_REDIRECTOR_PAUSED ((NTSTATUS) 0xC00000D1L) -#endif - -#ifndef STATUS_NET_WRITE_FAULT -# define STATUS_NET_WRITE_FAULT ((NTSTATUS) 0xC00000D2L) -#endif - -#ifndef STATUS_PROFILING_AT_LIMIT -# define STATUS_PROFILING_AT_LIMIT ((NTSTATUS) 0xC00000D3L) -#endif - -#ifndef STATUS_NOT_SAME_DEVICE -# define STATUS_NOT_SAME_DEVICE ((NTSTATUS) 0xC00000D4L) -#endif - -#ifndef STATUS_FILE_RENAMED -# define STATUS_FILE_RENAMED ((NTSTATUS) 0xC00000D5L) -#endif - -#ifndef STATUS_VIRTUAL_CIRCUIT_CLOSED -# define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS) 0xC00000D6L) -#endif - -#ifndef STATUS_NO_SECURITY_ON_OBJECT -# define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS) 0xC00000D7L) -#endif - -#ifndef STATUS_CANT_WAIT -# define STATUS_CANT_WAIT ((NTSTATUS) 0xC00000D8L) -#endif - -#ifndef STATUS_PIPE_EMPTY -# define STATUS_PIPE_EMPTY ((NTSTATUS) 0xC00000D9L) -#endif - -#ifndef STATUS_CANT_ACCESS_DOMAIN_INFO -# define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS) 0xC00000DAL) -#endif - -#ifndef STATUS_CANT_TERMINATE_SELF -# define STATUS_CANT_TERMINATE_SELF ((NTSTATUS) 0xC00000DBL) -#endif - -#ifndef STATUS_INVALID_SERVER_STATE -# define STATUS_INVALID_SERVER_STATE ((NTSTATUS) 0xC00000DCL) -#endif - -#ifndef STATUS_INVALID_DOMAIN_STATE -# define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS) 0xC00000DDL) -#endif - -#ifndef STATUS_INVALID_DOMAIN_ROLE -# define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS) 0xC00000DEL) -#endif - -#ifndef STATUS_NO_SUCH_DOMAIN -# define STATUS_NO_SUCH_DOMAIN ((NTSTATUS) 0xC00000DFL) -#endif - -#ifndef STATUS_DOMAIN_EXISTS -# define STATUS_DOMAIN_EXISTS ((NTSTATUS) 0xC00000E0L) -#endif - -#ifndef STATUS_DOMAIN_LIMIT_EXCEEDED -# define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00000E1L) -#endif - -#ifndef STATUS_OPLOCK_NOT_GRANTED -# define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS) 0xC00000E2L) -#endif - -#ifndef STATUS_INVALID_OPLOCK_PROTOCOL -# define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS) 0xC00000E3L) -#endif - -#ifndef STATUS_INTERNAL_DB_CORRUPTION -# define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS) 0xC00000E4L) -#endif - -#ifndef STATUS_INTERNAL_ERROR -# define STATUS_INTERNAL_ERROR ((NTSTATUS) 0xC00000E5L) -#endif - -#ifndef STATUS_GENERIC_NOT_MAPPED -# define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS) 0xC00000E6L) -#endif - -#ifndef STATUS_BAD_DESCRIPTOR_FORMAT -# define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS) 0xC00000E7L) -#endif - -#ifndef STATUS_INVALID_USER_BUFFER -# define STATUS_INVALID_USER_BUFFER ((NTSTATUS) 0xC00000E8L) -#endif - -#ifndef STATUS_UNEXPECTED_IO_ERROR -# define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS) 0xC00000E9L) -#endif - -#ifndef STATUS_UNEXPECTED_MM_CREATE_ERR -# define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS) 0xC00000EAL) -#endif - -#ifndef STATUS_UNEXPECTED_MM_MAP_ERROR -# define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS) 0xC00000EBL) -#endif - -#ifndef STATUS_UNEXPECTED_MM_EXTEND_ERR -# define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS) 0xC00000ECL) -#endif - -#ifndef STATUS_NOT_LOGON_PROCESS -# define STATUS_NOT_LOGON_PROCESS ((NTSTATUS) 0xC00000EDL) -#endif - -#ifndef STATUS_LOGON_SESSION_EXISTS -# define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS) 0xC00000EEL) -#endif - -#ifndef STATUS_INVALID_PARAMETER_1 -# define STATUS_INVALID_PARAMETER_1 ((NTSTATUS) 0xC00000EFL) -#endif - -#ifndef STATUS_INVALID_PARAMETER_2 -# define STATUS_INVALID_PARAMETER_2 ((NTSTATUS) 0xC00000F0L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_3 -# define STATUS_INVALID_PARAMETER_3 ((NTSTATUS) 0xC00000F1L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_4 -# define STATUS_INVALID_PARAMETER_4 ((NTSTATUS) 0xC00000F2L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_5 -# define STATUS_INVALID_PARAMETER_5 ((NTSTATUS) 0xC00000F3L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_6 -# define STATUS_INVALID_PARAMETER_6 ((NTSTATUS) 0xC00000F4L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_7 -# define STATUS_INVALID_PARAMETER_7 ((NTSTATUS) 0xC00000F5L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_8 -# define STATUS_INVALID_PARAMETER_8 ((NTSTATUS) 0xC00000F6L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_9 -# define STATUS_INVALID_PARAMETER_9 ((NTSTATUS) 0xC00000F7L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_10 -# define STATUS_INVALID_PARAMETER_10 ((NTSTATUS) 0xC00000F8L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_11 -# define STATUS_INVALID_PARAMETER_11 ((NTSTATUS) 0xC00000F9L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_12 -# define STATUS_INVALID_PARAMETER_12 ((NTSTATUS) 0xC00000FAL) -#endif - -#ifndef STATUS_REDIRECTOR_NOT_STARTED -# define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS) 0xC00000FBL) -#endif - -#ifndef STATUS_REDIRECTOR_STARTED -# define STATUS_REDIRECTOR_STARTED ((NTSTATUS) 0xC00000FCL) -#endif - -#ifndef STATUS_STACK_OVERFLOW -# define STATUS_STACK_OVERFLOW ((NTSTATUS) 0xC00000FDL) -#endif - -#ifndef STATUS_NO_SUCH_PACKAGE -# define STATUS_NO_SUCH_PACKAGE ((NTSTATUS) 0xC00000FEL) -#endif - -#ifndef STATUS_BAD_FUNCTION_TABLE -# define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS) 0xC00000FFL) -#endif - -#ifndef STATUS_VARIABLE_NOT_FOUND -# define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS) 0xC0000100L) -#endif - -#ifndef STATUS_DIRECTORY_NOT_EMPTY -# define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xC0000101L) -#endif - -#ifndef STATUS_FILE_CORRUPT_ERROR -# define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS) 0xC0000102L) -#endif - -#ifndef STATUS_NOT_A_DIRECTORY -# define STATUS_NOT_A_DIRECTORY ((NTSTATUS) 0xC0000103L) -#endif - -#ifndef STATUS_BAD_LOGON_SESSION_STATE -# define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS) 0xC0000104L) -#endif - -#ifndef STATUS_LOGON_SESSION_COLLISION -# define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS) 0xC0000105L) -#endif - -#ifndef STATUS_NAME_TOO_LONG -# define STATUS_NAME_TOO_LONG ((NTSTATUS) 0xC0000106L) -#endif - -#ifndef STATUS_FILES_OPEN -# define STATUS_FILES_OPEN ((NTSTATUS) 0xC0000107L) -#endif - -#ifndef STATUS_CONNECTION_IN_USE -# define STATUS_CONNECTION_IN_USE ((NTSTATUS) 0xC0000108L) -#endif - -#ifndef STATUS_MESSAGE_NOT_FOUND -# define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS) 0xC0000109L) -#endif - -#ifndef STATUS_PROCESS_IS_TERMINATING -# define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS) 0xC000010AL) -#endif - -#ifndef STATUS_INVALID_LOGON_TYPE -# define STATUS_INVALID_LOGON_TYPE ((NTSTATUS) 0xC000010BL) -#endif - -#ifndef STATUS_NO_GUID_TRANSLATION -# define STATUS_NO_GUID_TRANSLATION ((NTSTATUS) 0xC000010CL) -#endif - -#ifndef STATUS_CANNOT_IMPERSONATE -# define STATUS_CANNOT_IMPERSONATE ((NTSTATUS) 0xC000010DL) -#endif - -#ifndef STATUS_IMAGE_ALREADY_LOADED -# define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS) 0xC000010EL) -#endif - -#ifndef STATUS_ABIOS_NOT_PRESENT -# define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS) 0xC000010FL) -#endif - -#ifndef STATUS_ABIOS_LID_NOT_EXIST -# define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS) 0xC0000110L) -#endif - -#ifndef STATUS_ABIOS_LID_ALREADY_OWNED -# define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS) 0xC0000111L) -#endif - -#ifndef STATUS_ABIOS_NOT_LID_OWNER -# define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS) 0xC0000112L) -#endif - -#ifndef STATUS_ABIOS_INVALID_COMMAND -# define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS) 0xC0000113L) -#endif - -#ifndef STATUS_ABIOS_INVALID_LID -# define STATUS_ABIOS_INVALID_LID ((NTSTATUS) 0xC0000114L) -#endif - -#ifndef STATUS_ABIOS_SELECTOR_NOT_AVAILABLE -# define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS) 0xC0000115L) -#endif - -#ifndef STATUS_ABIOS_INVALID_SELECTOR -# define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS) 0xC0000116L) -#endif - -#ifndef STATUS_NO_LDT -# define STATUS_NO_LDT ((NTSTATUS) 0xC0000117L) -#endif - -#ifndef STATUS_INVALID_LDT_SIZE -# define STATUS_INVALID_LDT_SIZE ((NTSTATUS) 0xC0000118L) -#endif - -#ifndef STATUS_INVALID_LDT_OFFSET -# define STATUS_INVALID_LDT_OFFSET ((NTSTATUS) 0xC0000119L) -#endif - -#ifndef STATUS_INVALID_LDT_DESCRIPTOR -# define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS) 0xC000011AL) -#endif - -#ifndef STATUS_INVALID_IMAGE_NE_FORMAT -# define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS) 0xC000011BL) -#endif - -#ifndef STATUS_RXACT_INVALID_STATE -# define STATUS_RXACT_INVALID_STATE ((NTSTATUS) 0xC000011CL) -#endif - -#ifndef STATUS_RXACT_COMMIT_FAILURE -# define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS) 0xC000011DL) -#endif - -#ifndef STATUS_MAPPED_FILE_SIZE_ZERO -# define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS) 0xC000011EL) -#endif - -#ifndef STATUS_TOO_MANY_OPENED_FILES -# define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS) 0xC000011FL) -#endif - -#ifndef STATUS_CANCELLED -# define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L) -#endif - -#ifndef STATUS_CANNOT_DELETE -# define STATUS_CANNOT_DELETE ((NTSTATUS) 0xC0000121L) -#endif - -#ifndef STATUS_INVALID_COMPUTER_NAME -# define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS) 0xC0000122L) -#endif - -#ifndef STATUS_FILE_DELETED -# define STATUS_FILE_DELETED ((NTSTATUS) 0xC0000123L) -#endif - -#ifndef STATUS_SPECIAL_ACCOUNT -# define STATUS_SPECIAL_ACCOUNT ((NTSTATUS) 0xC0000124L) -#endif - -#ifndef STATUS_SPECIAL_GROUP -# define STATUS_SPECIAL_GROUP ((NTSTATUS) 0xC0000125L) -#endif - -#ifndef STATUS_SPECIAL_USER -# define STATUS_SPECIAL_USER ((NTSTATUS) 0xC0000126L) -#endif - -#ifndef STATUS_MEMBERS_PRIMARY_GROUP -# define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS) 0xC0000127L) -#endif - -#ifndef STATUS_FILE_CLOSED -# define STATUS_FILE_CLOSED ((NTSTATUS) 0xC0000128L) -#endif - -#ifndef STATUS_TOO_MANY_THREADS -# define STATUS_TOO_MANY_THREADS ((NTSTATUS) 0xC0000129L) -#endif - -#ifndef STATUS_THREAD_NOT_IN_PROCESS -# define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS) 0xC000012AL) -#endif - -#ifndef STATUS_TOKEN_ALREADY_IN_USE -# define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS) 0xC000012BL) -#endif - -#ifndef STATUS_PAGEFILE_QUOTA_EXCEEDED -# define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS) 0xC000012CL) -#endif - -#ifndef STATUS_COMMITMENT_LIMIT -# define STATUS_COMMITMENT_LIMIT ((NTSTATUS) 0xC000012DL) -#endif - -#ifndef STATUS_INVALID_IMAGE_LE_FORMAT -# define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS) 0xC000012EL) -#endif - -#ifndef STATUS_INVALID_IMAGE_NOT_MZ -# define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS) 0xC000012FL) -#endif - -#ifndef STATUS_INVALID_IMAGE_PROTECT -# define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS) 0xC0000130L) -#endif - -#ifndef STATUS_INVALID_IMAGE_WIN_16 -# define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS) 0xC0000131L) -#endif - -#ifndef STATUS_LOGON_SERVER_CONFLICT -# define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS) 0xC0000132L) -#endif - -#ifndef STATUS_TIME_DIFFERENCE_AT_DC -# define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS) 0xC0000133L) -#endif - -#ifndef STATUS_SYNCHRONIZATION_REQUIRED -# define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS) 0xC0000134L) -#endif - -#ifndef STATUS_DLL_NOT_FOUND -# define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xC0000135L) -#endif - -#ifndef STATUS_OPEN_FAILED -# define STATUS_OPEN_FAILED ((NTSTATUS) 0xC0000136L) -#endif - -#ifndef STATUS_IO_PRIVILEGE_FAILED -# define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS) 0xC0000137L) -#endif - -#ifndef STATUS_ORDINAL_NOT_FOUND -# define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000138L) -#endif - -#ifndef STATUS_ENTRYPOINT_NOT_FOUND -# define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000139L) -#endif - -#ifndef STATUS_CONTROL_C_EXIT -# define STATUS_CONTROL_C_EXIT ((NTSTATUS) 0xC000013AL) -#endif - -#ifndef STATUS_LOCAL_DISCONNECT -# define STATUS_LOCAL_DISCONNECT ((NTSTATUS) 0xC000013BL) -#endif - -#ifndef STATUS_REMOTE_DISCONNECT -# define STATUS_REMOTE_DISCONNECT ((NTSTATUS) 0xC000013CL) -#endif - -#ifndef STATUS_REMOTE_RESOURCES -# define STATUS_REMOTE_RESOURCES ((NTSTATUS) 0xC000013DL) -#endif - -#ifndef STATUS_LINK_FAILED -# define STATUS_LINK_FAILED ((NTSTATUS) 0xC000013EL) -#endif - -#ifndef STATUS_LINK_TIMEOUT -# define STATUS_LINK_TIMEOUT ((NTSTATUS) 0xC000013FL) -#endif - -#ifndef STATUS_INVALID_CONNECTION -# define STATUS_INVALID_CONNECTION ((NTSTATUS) 0xC0000140L) -#endif - -#ifndef STATUS_INVALID_ADDRESS -# define STATUS_INVALID_ADDRESS ((NTSTATUS) 0xC0000141L) -#endif - -#ifndef STATUS_DLL_INIT_FAILED -# define STATUS_DLL_INIT_FAILED ((NTSTATUS) 0xC0000142L) -#endif - -#ifndef STATUS_MISSING_SYSTEMFILE -# define STATUS_MISSING_SYSTEMFILE ((NTSTATUS) 0xC0000143L) -#endif - -#ifndef STATUS_UNHANDLED_EXCEPTION -# define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS) 0xC0000144L) -#endif - -#ifndef STATUS_APP_INIT_FAILURE -# define STATUS_APP_INIT_FAILURE ((NTSTATUS) 0xC0000145L) -#endif - -#ifndef STATUS_PAGEFILE_CREATE_FAILED -# define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS) 0xC0000146L) -#endif - -#ifndef STATUS_NO_PAGEFILE -# define STATUS_NO_PAGEFILE ((NTSTATUS) 0xC0000147L) -#endif - -#ifndef STATUS_INVALID_LEVEL -# define STATUS_INVALID_LEVEL ((NTSTATUS) 0xC0000148L) -#endif - -#ifndef STATUS_WRONG_PASSWORD_CORE -# define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS) 0xC0000149L) -#endif - -#ifndef STATUS_ILLEGAL_FLOAT_CONTEXT -# define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS) 0xC000014AL) -#endif - -#ifndef STATUS_PIPE_BROKEN -# define STATUS_PIPE_BROKEN ((NTSTATUS) 0xC000014BL) -#endif - -#ifndef STATUS_REGISTRY_CORRUPT -# define STATUS_REGISTRY_CORRUPT ((NTSTATUS) 0xC000014CL) -#endif - -#ifndef STATUS_REGISTRY_IO_FAILED -# define STATUS_REGISTRY_IO_FAILED ((NTSTATUS) 0xC000014DL) -#endif - -#ifndef STATUS_NO_EVENT_PAIR -# define STATUS_NO_EVENT_PAIR ((NTSTATUS) 0xC000014EL) -#endif - -#ifndef STATUS_UNRECOGNIZED_VOLUME -# define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS) 0xC000014FL) -#endif - -#ifndef STATUS_SERIAL_NO_DEVICE_INITED -# define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS) 0xC0000150L) -#endif - -#ifndef STATUS_NO_SUCH_ALIAS -# define STATUS_NO_SUCH_ALIAS ((NTSTATUS) 0xC0000151L) -#endif - -#ifndef STATUS_MEMBER_NOT_IN_ALIAS -# define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS) 0xC0000152L) -#endif - -#ifndef STATUS_MEMBER_IN_ALIAS -# define STATUS_MEMBER_IN_ALIAS ((NTSTATUS) 0xC0000153L) -#endif - -#ifndef STATUS_ALIAS_EXISTS -# define STATUS_ALIAS_EXISTS ((NTSTATUS) 0xC0000154L) -#endif - -#ifndef STATUS_LOGON_NOT_GRANTED -# define STATUS_LOGON_NOT_GRANTED ((NTSTATUS) 0xC0000155L) -#endif - -#ifndef STATUS_TOO_MANY_SECRETS -# define STATUS_TOO_MANY_SECRETS ((NTSTATUS) 0xC0000156L) -#endif - -#ifndef STATUS_SECRET_TOO_LONG -# define STATUS_SECRET_TOO_LONG ((NTSTATUS) 0xC0000157L) -#endif - -#ifndef STATUS_INTERNAL_DB_ERROR -# define STATUS_INTERNAL_DB_ERROR ((NTSTATUS) 0xC0000158L) -#endif - -#ifndef STATUS_FULLSCREEN_MODE -# define STATUS_FULLSCREEN_MODE ((NTSTATUS) 0xC0000159L) -#endif - -#ifndef STATUS_TOO_MANY_CONTEXT_IDS -# define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS) 0xC000015AL) -#endif - -#ifndef STATUS_LOGON_TYPE_NOT_GRANTED -# define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS) 0xC000015BL) -#endif - -#ifndef STATUS_NOT_REGISTRY_FILE -# define STATUS_NOT_REGISTRY_FILE ((NTSTATUS) 0xC000015CL) -#endif - -#ifndef STATUS_NT_CROSS_ENCRYPTION_REQUIRED -# define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000015DL) -#endif - -#ifndef STATUS_DOMAIN_CTRLR_CONFIG_ERROR -# define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS) 0xC000015EL) -#endif - -#ifndef STATUS_FT_MISSING_MEMBER -# define STATUS_FT_MISSING_MEMBER ((NTSTATUS) 0xC000015FL) -#endif - -#ifndef STATUS_ILL_FORMED_SERVICE_ENTRY -# define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS) 0xC0000160L) -#endif - -#ifndef STATUS_ILLEGAL_CHARACTER -# define STATUS_ILLEGAL_CHARACTER ((NTSTATUS) 0xC0000161L) -#endif - -#ifndef STATUS_UNMAPPABLE_CHARACTER -# define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS) 0xC0000162L) -#endif - -#ifndef STATUS_UNDEFINED_CHARACTER -# define STATUS_UNDEFINED_CHARACTER ((NTSTATUS) 0xC0000163L) -#endif - -#ifndef STATUS_FLOPPY_VOLUME -# define STATUS_FLOPPY_VOLUME ((NTSTATUS) 0xC0000164L) -#endif - -#ifndef STATUS_FLOPPY_ID_MARK_NOT_FOUND -# define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS) 0xC0000165L) -#endif - -#ifndef STATUS_FLOPPY_WRONG_CYLINDER -# define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS) 0xC0000166L) -#endif - -#ifndef STATUS_FLOPPY_UNKNOWN_ERROR -# define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS) 0xC0000167L) -#endif - -#ifndef STATUS_FLOPPY_BAD_REGISTERS -# define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS) 0xC0000168L) -#endif - -#ifndef STATUS_DISK_RECALIBRATE_FAILED -# define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS) 0xC0000169L) -#endif - -#ifndef STATUS_DISK_OPERATION_FAILED -# define STATUS_DISK_OPERATION_FAILED ((NTSTATUS) 0xC000016AL) -#endif - -#ifndef STATUS_DISK_RESET_FAILED -# define STATUS_DISK_RESET_FAILED ((NTSTATUS) 0xC000016BL) -#endif - -#ifndef STATUS_SHARED_IRQ_BUSY -# define STATUS_SHARED_IRQ_BUSY ((NTSTATUS) 0xC000016CL) -#endif - -#ifndef STATUS_FT_ORPHANING -# define STATUS_FT_ORPHANING ((NTSTATUS) 0xC000016DL) -#endif - -#ifndef STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT -# define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS) 0xC000016EL) -#endif - -#ifndef STATUS_PARTITION_FAILURE -# define STATUS_PARTITION_FAILURE ((NTSTATUS) 0xC0000172L) -#endif - -#ifndef STATUS_INVALID_BLOCK_LENGTH -# define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS) 0xC0000173L) -#endif - -#ifndef STATUS_DEVICE_NOT_PARTITIONED -# define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS) 0xC0000174L) -#endif - -#ifndef STATUS_UNABLE_TO_LOCK_MEDIA -# define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS) 0xC0000175L) -#endif - -#ifndef STATUS_UNABLE_TO_UNLOAD_MEDIA -# define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS) 0xC0000176L) -#endif - -#ifndef STATUS_EOM_OVERFLOW -# define STATUS_EOM_OVERFLOW ((NTSTATUS) 0xC0000177L) -#endif - -#ifndef STATUS_NO_MEDIA -# define STATUS_NO_MEDIA ((NTSTATUS) 0xC0000178L) -#endif - -#ifndef STATUS_NO_SUCH_MEMBER -# define STATUS_NO_SUCH_MEMBER ((NTSTATUS) 0xC000017AL) -#endif - -#ifndef STATUS_INVALID_MEMBER -# define STATUS_INVALID_MEMBER ((NTSTATUS) 0xC000017BL) -#endif - -#ifndef STATUS_KEY_DELETED -# define STATUS_KEY_DELETED ((NTSTATUS) 0xC000017CL) -#endif - -#ifndef STATUS_NO_LOG_SPACE -# define STATUS_NO_LOG_SPACE ((NTSTATUS) 0xC000017DL) -#endif - -#ifndef STATUS_TOO_MANY_SIDS -# define STATUS_TOO_MANY_SIDS ((NTSTATUS) 0xC000017EL) -#endif - -#ifndef STATUS_LM_CROSS_ENCRYPTION_REQUIRED -# define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000017FL) -#endif - -#ifndef STATUS_KEY_HAS_CHILDREN -# define STATUS_KEY_HAS_CHILDREN ((NTSTATUS) 0xC0000180L) -#endif - -#ifndef STATUS_CHILD_MUST_BE_VOLATILE -# define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS) 0xC0000181L) -#endif - -#ifndef STATUS_DEVICE_CONFIGURATION_ERROR -# define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS) 0xC0000182L) -#endif - -#ifndef STATUS_DRIVER_INTERNAL_ERROR -# define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS) 0xC0000183L) -#endif - -#ifndef STATUS_INVALID_DEVICE_STATE -# define STATUS_INVALID_DEVICE_STATE ((NTSTATUS) 0xC0000184L) -#endif - -#ifndef STATUS_IO_DEVICE_ERROR -# define STATUS_IO_DEVICE_ERROR ((NTSTATUS) 0xC0000185L) -#endif - -#ifndef STATUS_DEVICE_PROTOCOL_ERROR -# define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS) 0xC0000186L) -#endif - -#ifndef STATUS_BACKUP_CONTROLLER -# define STATUS_BACKUP_CONTROLLER ((NTSTATUS) 0xC0000187L) -#endif - -#ifndef STATUS_LOG_FILE_FULL -# define STATUS_LOG_FILE_FULL ((NTSTATUS) 0xC0000188L) -#endif - -#ifndef STATUS_TOO_LATE -# define STATUS_TOO_LATE ((NTSTATUS) 0xC0000189L) -#endif - -#ifndef STATUS_NO_TRUST_LSA_SECRET -# define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS) 0xC000018AL) -#endif - -#ifndef STATUS_NO_TRUST_SAM_ACCOUNT -# define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS) 0xC000018BL) -#endif - -#ifndef STATUS_TRUSTED_DOMAIN_FAILURE -# define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS) 0xC000018CL) -#endif - -#ifndef STATUS_TRUSTED_RELATIONSHIP_FAILURE -# define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS) 0xC000018DL) -#endif - -#ifndef STATUS_EVENTLOG_FILE_CORRUPT -# define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS) 0xC000018EL) -#endif - -#ifndef STATUS_EVENTLOG_CANT_START -# define STATUS_EVENTLOG_CANT_START ((NTSTATUS) 0xC000018FL) -#endif - -#ifndef STATUS_TRUST_FAILURE -# define STATUS_TRUST_FAILURE ((NTSTATUS) 0xC0000190L) -#endif - -#ifndef STATUS_MUTANT_LIMIT_EXCEEDED -# define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000191L) -#endif - -#ifndef STATUS_NETLOGON_NOT_STARTED -# define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS) 0xC0000192L) -#endif - -#ifndef STATUS_ACCOUNT_EXPIRED -# define STATUS_ACCOUNT_EXPIRED ((NTSTATUS) 0xC0000193L) -#endif - -#ifndef STATUS_POSSIBLE_DEADLOCK -# define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS) 0xC0000194L) -#endif - -#ifndef STATUS_NETWORK_CREDENTIAL_CONFLICT -# define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS) 0xC0000195L) -#endif - -#ifndef STATUS_REMOTE_SESSION_LIMIT -# define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS) 0xC0000196L) -#endif - -#ifndef STATUS_EVENTLOG_FILE_CHANGED -# define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS) 0xC0000197L) -#endif - -#ifndef STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT -# define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS) 0xC0000198L) -#endif - -#ifndef STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT -# define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS) 0xC0000199L) -#endif - -#ifndef STATUS_NOLOGON_SERVER_TRUST_ACCOUNT -# define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS) 0xC000019AL) -#endif - -#ifndef STATUS_DOMAIN_TRUST_INCONSISTENT -# define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS) 0xC000019BL) -#endif - -#ifndef STATUS_FS_DRIVER_REQUIRED -# define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS) 0xC000019CL) -#endif - -#ifndef STATUS_IMAGE_ALREADY_LOADED_AS_DLL -# define STATUS_IMAGE_ALREADY_LOADED_AS_DLL ((NTSTATUS) 0xC000019DL) -#endif - -#ifndef STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING -# define STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING ((NTSTATUS) 0xC000019EL) -#endif - -#ifndef STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME -# define STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME ((NTSTATUS) 0xC000019FL) -#endif - -#ifndef STATUS_SECURITY_STREAM_IS_INCONSISTENT -# define STATUS_SECURITY_STREAM_IS_INCONSISTENT ((NTSTATUS) 0xC00001A0L) -#endif - -#ifndef STATUS_INVALID_LOCK_RANGE -# define STATUS_INVALID_LOCK_RANGE ((NTSTATUS) 0xC00001A1L) -#endif - -#ifndef STATUS_INVALID_ACE_CONDITION -# define STATUS_INVALID_ACE_CONDITION ((NTSTATUS) 0xC00001A2L) -#endif - -#ifndef STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT -# define STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT ((NTSTATUS) 0xC00001A3L) -#endif - -#ifndef STATUS_NOTIFICATION_GUID_ALREADY_DEFINED -# define STATUS_NOTIFICATION_GUID_ALREADY_DEFINED ((NTSTATUS) 0xC00001A4L) -#endif - -#ifndef STATUS_NETWORK_OPEN_RESTRICTION -# define STATUS_NETWORK_OPEN_RESTRICTION ((NTSTATUS) 0xC0000201L) -#endif - -#ifndef STATUS_NO_USER_SESSION_KEY -# define STATUS_NO_USER_SESSION_KEY ((NTSTATUS) 0xC0000202L) -#endif - -#ifndef STATUS_USER_SESSION_DELETED -# define STATUS_USER_SESSION_DELETED ((NTSTATUS) 0xC0000203L) -#endif - -#ifndef STATUS_RESOURCE_LANG_NOT_FOUND -# define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS) 0xC0000204L) -#endif - -#ifndef STATUS_INSUFF_SERVER_RESOURCES -# define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS) 0xC0000205L) -#endif - -#ifndef STATUS_INVALID_BUFFER_SIZE -# define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS) 0xC0000206L) -#endif - -#ifndef STATUS_INVALID_ADDRESS_COMPONENT -# define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS) 0xC0000207L) -#endif - -#ifndef STATUS_INVALID_ADDRESS_WILDCARD -# define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS) 0xC0000208L) -#endif - -#ifndef STATUS_TOO_MANY_ADDRESSES -# define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS) 0xC0000209L) -#endif - -#ifndef STATUS_ADDRESS_ALREADY_EXISTS -# define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS) 0xC000020AL) -#endif - -#ifndef STATUS_ADDRESS_CLOSED -# define STATUS_ADDRESS_CLOSED ((NTSTATUS) 0xC000020BL) -#endif - -#ifndef STATUS_CONNECTION_DISCONNECTED -# define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS) 0xC000020CL) -#endif - -#ifndef STATUS_CONNECTION_RESET -# define STATUS_CONNECTION_RESET ((NTSTATUS) 0xC000020DL) -#endif - -#ifndef STATUS_TOO_MANY_NODES -# define STATUS_TOO_MANY_NODES ((NTSTATUS) 0xC000020EL) -#endif - -#ifndef STATUS_TRANSACTION_ABORTED -# define STATUS_TRANSACTION_ABORTED ((NTSTATUS) 0xC000020FL) -#endif - -#ifndef STATUS_TRANSACTION_TIMED_OUT -# define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS) 0xC0000210L) -#endif - -#ifndef STATUS_TRANSACTION_NO_RELEASE -# define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS) 0xC0000211L) -#endif - -#ifndef STATUS_TRANSACTION_NO_MATCH -# define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS) 0xC0000212L) -#endif - -#ifndef STATUS_TRANSACTION_RESPONDED -# define STATUS_TRANSACTION_RESPONDED ((NTSTATUS) 0xC0000213L) -#endif - -#ifndef STATUS_TRANSACTION_INVALID_ID -# define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS) 0xC0000214L) -#endif - -#ifndef STATUS_TRANSACTION_INVALID_TYPE -# define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS) 0xC0000215L) -#endif - -#ifndef STATUS_NOT_SERVER_SESSION -# define STATUS_NOT_SERVER_SESSION ((NTSTATUS) 0xC0000216L) -#endif - -#ifndef STATUS_NOT_CLIENT_SESSION -# define STATUS_NOT_CLIENT_SESSION ((NTSTATUS) 0xC0000217L) -#endif - -#ifndef STATUS_CANNOT_LOAD_REGISTRY_FILE -# define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS) 0xC0000218L) -#endif - -#ifndef STATUS_DEBUG_ATTACH_FAILED -# define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS) 0xC0000219L) -#endif - -#ifndef STATUS_SYSTEM_PROCESS_TERMINATED -# define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS) 0xC000021AL) -#endif - -#ifndef STATUS_DATA_NOT_ACCEPTED -# define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS) 0xC000021BL) -#endif - -#ifndef STATUS_NO_BROWSER_SERVERS_FOUND -# define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS) 0xC000021CL) -#endif - -#ifndef STATUS_VDM_HARD_ERROR -# define STATUS_VDM_HARD_ERROR ((NTSTATUS) 0xC000021DL) -#endif - -#ifndef STATUS_DRIVER_CANCEL_TIMEOUT -# define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS) 0xC000021EL) -#endif - -#ifndef STATUS_REPLY_MESSAGE_MISMATCH -# define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS) 0xC000021FL) -#endif - -#ifndef STATUS_MAPPED_ALIGNMENT -# define STATUS_MAPPED_ALIGNMENT ((NTSTATUS) 0xC0000220L) -#endif - -#ifndef STATUS_IMAGE_CHECKSUM_MISMATCH -# define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS) 0xC0000221L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA -# define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS) 0xC0000222L) -#endif - -#ifndef STATUS_CLIENT_SERVER_PARAMETERS_INVALID -# define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS) 0xC0000223L) -#endif - -#ifndef STATUS_PASSWORD_MUST_CHANGE -# define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS) 0xC0000224L) -#endif - -#ifndef STATUS_NOT_FOUND -# define STATUS_NOT_FOUND ((NTSTATUS) 0xC0000225L) -#endif - -#ifndef STATUS_NOT_TINY_STREAM -# define STATUS_NOT_TINY_STREAM ((NTSTATUS) 0xC0000226L) -#endif - -#ifndef STATUS_RECOVERY_FAILURE -# define STATUS_RECOVERY_FAILURE ((NTSTATUS) 0xC0000227L) -#endif - -#ifndef STATUS_STACK_OVERFLOW_READ -# define STATUS_STACK_OVERFLOW_READ ((NTSTATUS) 0xC0000228L) -#endif - -#ifndef STATUS_FAIL_CHECK -# define STATUS_FAIL_CHECK ((NTSTATUS) 0xC0000229L) -#endif - -#ifndef STATUS_DUPLICATE_OBJECTID -# define STATUS_DUPLICATE_OBJECTID ((NTSTATUS) 0xC000022AL) -#endif - -#ifndef STATUS_OBJECTID_EXISTS -# define STATUS_OBJECTID_EXISTS ((NTSTATUS) 0xC000022BL) -#endif - -#ifndef STATUS_CONVERT_TO_LARGE -# define STATUS_CONVERT_TO_LARGE ((NTSTATUS) 0xC000022CL) -#endif - -#ifndef STATUS_RETRY -# define STATUS_RETRY ((NTSTATUS) 0xC000022DL) -#endif - -#ifndef STATUS_FOUND_OUT_OF_SCOPE -# define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS) 0xC000022EL) -#endif - -#ifndef STATUS_ALLOCATE_BUCKET -# define STATUS_ALLOCATE_BUCKET ((NTSTATUS) 0xC000022FL) -#endif - -#ifndef STATUS_PROPSET_NOT_FOUND -# define STATUS_PROPSET_NOT_FOUND ((NTSTATUS) 0xC0000230L) -#endif - -#ifndef STATUS_MARSHALL_OVERFLOW -# define STATUS_MARSHALL_OVERFLOW ((NTSTATUS) 0xC0000231L) -#endif - -#ifndef STATUS_INVALID_VARIANT -# define STATUS_INVALID_VARIANT ((NTSTATUS) 0xC0000232L) -#endif - -#ifndef STATUS_DOMAIN_CONTROLLER_NOT_FOUND -# define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS) 0xC0000233L) -#endif - -#ifndef STATUS_ACCOUNT_LOCKED_OUT -# define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS) 0xC0000234L) -#endif - -#ifndef STATUS_HANDLE_NOT_CLOSABLE -# define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS) 0xC0000235L) -#endif - -#ifndef STATUS_CONNECTION_REFUSED -# define STATUS_CONNECTION_REFUSED ((NTSTATUS) 0xC0000236L) -#endif - -#ifndef STATUS_GRACEFUL_DISCONNECT -# define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS) 0xC0000237L) -#endif - -#ifndef STATUS_ADDRESS_ALREADY_ASSOCIATED -# define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS) 0xC0000238L) -#endif - -#ifndef STATUS_ADDRESS_NOT_ASSOCIATED -# define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS) 0xC0000239L) -#endif - -#ifndef STATUS_CONNECTION_INVALID -# define STATUS_CONNECTION_INVALID ((NTSTATUS) 0xC000023AL) -#endif - -#ifndef STATUS_CONNECTION_ACTIVE -# define STATUS_CONNECTION_ACTIVE ((NTSTATUS) 0xC000023BL) -#endif - -#ifndef STATUS_NETWORK_UNREACHABLE -# define STATUS_NETWORK_UNREACHABLE ((NTSTATUS) 0xC000023CL) -#endif - -#ifndef STATUS_HOST_UNREACHABLE -# define STATUS_HOST_UNREACHABLE ((NTSTATUS) 0xC000023DL) -#endif - -#ifndef STATUS_PROTOCOL_UNREACHABLE -# define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS) 0xC000023EL) -#endif - -#ifndef STATUS_PORT_UNREACHABLE -# define STATUS_PORT_UNREACHABLE ((NTSTATUS) 0xC000023FL) -#endif - -#ifndef STATUS_REQUEST_ABORTED -# define STATUS_REQUEST_ABORTED ((NTSTATUS) 0xC0000240L) -#endif - -#ifndef STATUS_CONNECTION_ABORTED -# define STATUS_CONNECTION_ABORTED ((NTSTATUS) 0xC0000241L) -#endif - -#ifndef STATUS_BAD_COMPRESSION_BUFFER -# define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS) 0xC0000242L) -#endif - -#ifndef STATUS_USER_MAPPED_FILE -# define STATUS_USER_MAPPED_FILE ((NTSTATUS) 0xC0000243L) -#endif - -#ifndef STATUS_AUDIT_FAILED -# define STATUS_AUDIT_FAILED ((NTSTATUS) 0xC0000244L) -#endif - -#ifndef STATUS_TIMER_RESOLUTION_NOT_SET -# define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS) 0xC0000245L) -#endif - -#ifndef STATUS_CONNECTION_COUNT_LIMIT -# define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS) 0xC0000246L) -#endif - -#ifndef STATUS_LOGIN_TIME_RESTRICTION -# define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS) 0xC0000247L) -#endif - -#ifndef STATUS_LOGIN_WKSTA_RESTRICTION -# define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS) 0xC0000248L) -#endif - -#ifndef STATUS_IMAGE_MP_UP_MISMATCH -# define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS) 0xC0000249L) -#endif - -#ifndef STATUS_INSUFFICIENT_LOGON_INFO -# define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS) 0xC0000250L) -#endif - -#ifndef STATUS_BAD_DLL_ENTRYPOINT -# define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS) 0xC0000251L) -#endif - -#ifndef STATUS_BAD_SERVICE_ENTRYPOINT -# define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS) 0xC0000252L) -#endif - -#ifndef STATUS_LPC_REPLY_LOST -# define STATUS_LPC_REPLY_LOST ((NTSTATUS) 0xC0000253L) -#endif - -#ifndef STATUS_IP_ADDRESS_CONFLICT1 -# define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS) 0xC0000254L) -#endif - -#ifndef STATUS_IP_ADDRESS_CONFLICT2 -# define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS) 0xC0000255L) -#endif - -#ifndef STATUS_REGISTRY_QUOTA_LIMIT -# define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS) 0xC0000256L) -#endif - -#ifndef STATUS_PATH_NOT_COVERED -# define STATUS_PATH_NOT_COVERED ((NTSTATUS) 0xC0000257L) -#endif - -#ifndef STATUS_NO_CALLBACK_ACTIVE -# define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS) 0xC0000258L) -#endif - -#ifndef STATUS_LICENSE_QUOTA_EXCEEDED -# define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000259L) -#endif - -#ifndef STATUS_PWD_TOO_SHORT -# define STATUS_PWD_TOO_SHORT ((NTSTATUS) 0xC000025AL) -#endif - -#ifndef STATUS_PWD_TOO_RECENT -# define STATUS_PWD_TOO_RECENT ((NTSTATUS) 0xC000025BL) -#endif - -#ifndef STATUS_PWD_HISTORY_CONFLICT -# define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS) 0xC000025CL) -#endif - -#ifndef STATUS_PLUGPLAY_NO_DEVICE -# define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS) 0xC000025EL) -#endif - -#ifndef STATUS_UNSUPPORTED_COMPRESSION -# define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS) 0xC000025FL) -#endif - -#ifndef STATUS_INVALID_HW_PROFILE -# define STATUS_INVALID_HW_PROFILE ((NTSTATUS) 0xC0000260L) -#endif - -#ifndef STATUS_INVALID_PLUGPLAY_DEVICE_PATH -# define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS) 0xC0000261L) -#endif - -#ifndef STATUS_DRIVER_ORDINAL_NOT_FOUND -# define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000262L) -#endif - -#ifndef STATUS_DRIVER_ENTRYPOINT_NOT_FOUND -# define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000263L) -#endif - -#ifndef STATUS_RESOURCE_NOT_OWNED -# define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS) 0xC0000264L) -#endif - -#ifndef STATUS_TOO_MANY_LINKS -# define STATUS_TOO_MANY_LINKS ((NTSTATUS) 0xC0000265L) -#endif - -#ifndef STATUS_QUOTA_LIST_INCONSISTENT -# define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS) 0xC0000266L) -#endif - -#ifndef STATUS_FILE_IS_OFFLINE -# define STATUS_FILE_IS_OFFLINE ((NTSTATUS) 0xC0000267L) -#endif - -#ifndef STATUS_EVALUATION_EXPIRATION -# define STATUS_EVALUATION_EXPIRATION ((NTSTATUS) 0xC0000268L) -#endif - -#ifndef STATUS_ILLEGAL_DLL_RELOCATION -# define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xC0000269L) -#endif - -#ifndef STATUS_LICENSE_VIOLATION -# define STATUS_LICENSE_VIOLATION ((NTSTATUS) 0xC000026AL) -#endif - -#ifndef STATUS_DLL_INIT_FAILED_LOGOFF -# define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS) 0xC000026BL) -#endif - -#ifndef STATUS_DRIVER_UNABLE_TO_LOAD -# define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS) 0xC000026CL) -#endif - -#ifndef STATUS_DFS_UNAVAILABLE -# define STATUS_DFS_UNAVAILABLE ((NTSTATUS) 0xC000026DL) -#endif - -#ifndef STATUS_VOLUME_DISMOUNTED -# define STATUS_VOLUME_DISMOUNTED ((NTSTATUS) 0xC000026EL) -#endif - -#ifndef STATUS_WX86_INTERNAL_ERROR -# define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS) 0xC000026FL) -#endif - -#ifndef STATUS_WX86_FLOAT_STACK_CHECK -# define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000270L) -#endif - -#ifndef STATUS_VALIDATE_CONTINUE -# define STATUS_VALIDATE_CONTINUE ((NTSTATUS) 0xC0000271L) -#endif - -#ifndef STATUS_NO_MATCH -# define STATUS_NO_MATCH ((NTSTATUS) 0xC0000272L) -#endif - -#ifndef STATUS_NO_MORE_MATCHES -# define STATUS_NO_MORE_MATCHES ((NTSTATUS) 0xC0000273L) -#endif - -#ifndef STATUS_NOT_A_REPARSE_POINT -# define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS) 0xC0000275L) -#endif - -#ifndef STATUS_IO_REPARSE_TAG_INVALID -# define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS) 0xC0000276L) -#endif - -#ifndef STATUS_IO_REPARSE_TAG_MISMATCH -# define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS) 0xC0000277L) -#endif - -#ifndef STATUS_IO_REPARSE_DATA_INVALID -# define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS) 0xC0000278L) -#endif - -#ifndef STATUS_IO_REPARSE_TAG_NOT_HANDLED -# define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS) 0xC0000279L) -#endif - -#ifndef STATUS_REPARSE_POINT_NOT_RESOLVED -# define STATUS_REPARSE_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000280L) -#endif - -#ifndef STATUS_DIRECTORY_IS_A_REPARSE_POINT -# define STATUS_DIRECTORY_IS_A_REPARSE_POINT ((NTSTATUS) 0xC0000281L) -#endif - -#ifndef STATUS_RANGE_LIST_CONFLICT -# define STATUS_RANGE_LIST_CONFLICT ((NTSTATUS) 0xC0000282L) -#endif - -#ifndef STATUS_SOURCE_ELEMENT_EMPTY -# define STATUS_SOURCE_ELEMENT_EMPTY ((NTSTATUS) 0xC0000283L) -#endif - -#ifndef STATUS_DESTINATION_ELEMENT_FULL -# define STATUS_DESTINATION_ELEMENT_FULL ((NTSTATUS) 0xC0000284L) -#endif - -#ifndef STATUS_ILLEGAL_ELEMENT_ADDRESS -# define STATUS_ILLEGAL_ELEMENT_ADDRESS ((NTSTATUS) 0xC0000285L) -#endif - -#ifndef STATUS_MAGAZINE_NOT_PRESENT -# define STATUS_MAGAZINE_NOT_PRESENT ((NTSTATUS) 0xC0000286L) -#endif - -#ifndef STATUS_REINITIALIZATION_NEEDED -# define STATUS_REINITIALIZATION_NEEDED ((NTSTATUS) 0xC0000287L) -#endif - -#ifndef STATUS_DEVICE_REQUIRES_CLEANING -# define STATUS_DEVICE_REQUIRES_CLEANING ((NTSTATUS) 0x80000288L) -#endif - -#ifndef STATUS_DEVICE_DOOR_OPEN -# define STATUS_DEVICE_DOOR_OPEN ((NTSTATUS) 0x80000289L) -#endif - -#ifndef STATUS_ENCRYPTION_FAILED -# define STATUS_ENCRYPTION_FAILED ((NTSTATUS) 0xC000028AL) -#endif - -#ifndef STATUS_DECRYPTION_FAILED -# define STATUS_DECRYPTION_FAILED ((NTSTATUS) 0xC000028BL) -#endif - -#ifndef STATUS_RANGE_NOT_FOUND -# define STATUS_RANGE_NOT_FOUND ((NTSTATUS) 0xC000028CL) -#endif - -#ifndef STATUS_NO_RECOVERY_POLICY -# define STATUS_NO_RECOVERY_POLICY ((NTSTATUS) 0xC000028DL) -#endif - -#ifndef STATUS_NO_EFS -# define STATUS_NO_EFS ((NTSTATUS) 0xC000028EL) -#endif - -#ifndef STATUS_WRONG_EFS -# define STATUS_WRONG_EFS ((NTSTATUS) 0xC000028FL) -#endif - -#ifndef STATUS_NO_USER_KEYS -# define STATUS_NO_USER_KEYS ((NTSTATUS) 0xC0000290L) -#endif - -#ifndef STATUS_FILE_NOT_ENCRYPTED -# define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS) 0xC0000291L) -#endif - -#ifndef STATUS_NOT_EXPORT_FORMAT -# define STATUS_NOT_EXPORT_FORMAT ((NTSTATUS) 0xC0000292L) -#endif - -#ifndef STATUS_FILE_ENCRYPTED -# define STATUS_FILE_ENCRYPTED ((NTSTATUS) 0xC0000293L) -#endif - -#ifndef STATUS_WAKE_SYSTEM -# define STATUS_WAKE_SYSTEM ((NTSTATUS) 0x40000294L) -#endif - -#ifndef STATUS_WMI_GUID_NOT_FOUND -# define STATUS_WMI_GUID_NOT_FOUND ((NTSTATUS) 0xC0000295L) -#endif - -#ifndef STATUS_WMI_INSTANCE_NOT_FOUND -# define STATUS_WMI_INSTANCE_NOT_FOUND ((NTSTATUS) 0xC0000296L) -#endif - -#ifndef STATUS_WMI_ITEMID_NOT_FOUND -# define STATUS_WMI_ITEMID_NOT_FOUND ((NTSTATUS) 0xC0000297L) -#endif - -#ifndef STATUS_WMI_TRY_AGAIN -# define STATUS_WMI_TRY_AGAIN ((NTSTATUS) 0xC0000298L) -#endif - -#ifndef STATUS_SHARED_POLICY -# define STATUS_SHARED_POLICY ((NTSTATUS) 0xC0000299L) -#endif - -#ifndef STATUS_POLICY_OBJECT_NOT_FOUND -# define STATUS_POLICY_OBJECT_NOT_FOUND ((NTSTATUS) 0xC000029AL) -#endif - -#ifndef STATUS_POLICY_ONLY_IN_DS -# define STATUS_POLICY_ONLY_IN_DS ((NTSTATUS) 0xC000029BL) -#endif - -#ifndef STATUS_VOLUME_NOT_UPGRADED -# define STATUS_VOLUME_NOT_UPGRADED ((NTSTATUS) 0xC000029CL) -#endif - -#ifndef STATUS_REMOTE_STORAGE_NOT_ACTIVE -# define STATUS_REMOTE_STORAGE_NOT_ACTIVE ((NTSTATUS) 0xC000029DL) -#endif - -#ifndef STATUS_REMOTE_STORAGE_MEDIA_ERROR -# define STATUS_REMOTE_STORAGE_MEDIA_ERROR ((NTSTATUS) 0xC000029EL) -#endif - -#ifndef STATUS_NO_TRACKING_SERVICE -# define STATUS_NO_TRACKING_SERVICE ((NTSTATUS) 0xC000029FL) -#endif - -#ifndef STATUS_SERVER_SID_MISMATCH -# define STATUS_SERVER_SID_MISMATCH ((NTSTATUS) 0xC00002A0L) -#endif - -#ifndef STATUS_DS_NO_ATTRIBUTE_OR_VALUE -# define STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((NTSTATUS) 0xC00002A1L) -#endif - -#ifndef STATUS_DS_INVALID_ATTRIBUTE_SYNTAX -# define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((NTSTATUS) 0xC00002A2L) -#endif - -#ifndef STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED -# define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((NTSTATUS) 0xC00002A3L) -#endif - -#ifndef STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS -# define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((NTSTATUS) 0xC00002A4L) -#endif - -#ifndef STATUS_DS_BUSY -# define STATUS_DS_BUSY ((NTSTATUS) 0xC00002A5L) -#endif - -#ifndef STATUS_DS_UNAVAILABLE -# define STATUS_DS_UNAVAILABLE ((NTSTATUS) 0xC00002A6L) -#endif - -#ifndef STATUS_DS_NO_RIDS_ALLOCATED -# define STATUS_DS_NO_RIDS_ALLOCATED ((NTSTATUS) 0xC00002A7L) -#endif - -#ifndef STATUS_DS_NO_MORE_RIDS -# define STATUS_DS_NO_MORE_RIDS ((NTSTATUS) 0xC00002A8L) -#endif - -#ifndef STATUS_DS_INCORRECT_ROLE_OWNER -# define STATUS_DS_INCORRECT_ROLE_OWNER ((NTSTATUS) 0xC00002A9L) -#endif - -#ifndef STATUS_DS_RIDMGR_INIT_ERROR -# define STATUS_DS_RIDMGR_INIT_ERROR ((NTSTATUS) 0xC00002AAL) -#endif - -#ifndef STATUS_DS_OBJ_CLASS_VIOLATION -# define STATUS_DS_OBJ_CLASS_VIOLATION ((NTSTATUS) 0xC00002ABL) -#endif - -#ifndef STATUS_DS_CANT_ON_NON_LEAF -# define STATUS_DS_CANT_ON_NON_LEAF ((NTSTATUS) 0xC00002ACL) -#endif - -#ifndef STATUS_DS_CANT_ON_RDN -# define STATUS_DS_CANT_ON_RDN ((NTSTATUS) 0xC00002ADL) -#endif - -#ifndef STATUS_DS_CANT_MOD_OBJ_CLASS -# define STATUS_DS_CANT_MOD_OBJ_CLASS ((NTSTATUS) 0xC00002AEL) -#endif - -#ifndef STATUS_DS_CROSS_DOM_MOVE_FAILED -# define STATUS_DS_CROSS_DOM_MOVE_FAILED ((NTSTATUS) 0xC00002AFL) -#endif - -#ifndef STATUS_DS_GC_NOT_AVAILABLE -# define STATUS_DS_GC_NOT_AVAILABLE ((NTSTATUS) 0xC00002B0L) -#endif - -#ifndef STATUS_DIRECTORY_SERVICE_REQUIRED -# define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS) 0xC00002B1L) -#endif - -#ifndef STATUS_REPARSE_ATTRIBUTE_CONFLICT -# define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS) 0xC00002B2L) -#endif - -#ifndef STATUS_CANT_ENABLE_DENY_ONLY -# define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS) 0xC00002B3L) -#endif - -#ifndef STATUS_FLOAT_MULTIPLE_FAULTS -# define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS) 0xC00002B4L) -#endif - -#ifndef STATUS_FLOAT_MULTIPLE_TRAPS -# define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS) 0xC00002B5L) -#endif - -#ifndef STATUS_DEVICE_REMOVED -# define STATUS_DEVICE_REMOVED ((NTSTATUS) 0xC00002B6L) -#endif - -#ifndef STATUS_JOURNAL_DELETE_IN_PROGRESS -# define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS) 0xC00002B7L) -#endif - -#ifndef STATUS_JOURNAL_NOT_ACTIVE -# define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS) 0xC00002B8L) -#endif - -#ifndef STATUS_NOINTERFACE -# define STATUS_NOINTERFACE ((NTSTATUS) 0xC00002B9L) -#endif - -#ifndef STATUS_DS_ADMIN_LIMIT_EXCEEDED -# define STATUS_DS_ADMIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00002C1L) -#endif - -#ifndef STATUS_DRIVER_FAILED_SLEEP -# define STATUS_DRIVER_FAILED_SLEEP ((NTSTATUS) 0xC00002C2L) -#endif - -#ifndef STATUS_MUTUAL_AUTHENTICATION_FAILED -# define STATUS_MUTUAL_AUTHENTICATION_FAILED ((NTSTATUS) 0xC00002C3L) -#endif - -#ifndef STATUS_CORRUPT_SYSTEM_FILE -# define STATUS_CORRUPT_SYSTEM_FILE ((NTSTATUS) 0xC00002C4L) -#endif - -#ifndef STATUS_DATATYPE_MISALIGNMENT_ERROR -# define STATUS_DATATYPE_MISALIGNMENT_ERROR ((NTSTATUS) 0xC00002C5L) -#endif - -#ifndef STATUS_WMI_READ_ONLY -# define STATUS_WMI_READ_ONLY ((NTSTATUS) 0xC00002C6L) -#endif - -#ifndef STATUS_WMI_SET_FAILURE -# define STATUS_WMI_SET_FAILURE ((NTSTATUS) 0xC00002C7L) -#endif - -#ifndef STATUS_COMMITMENT_MINIMUM -# define STATUS_COMMITMENT_MINIMUM ((NTSTATUS) 0xC00002C8L) -#endif - -#ifndef STATUS_REG_NAT_CONSUMPTION -# define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS) 0xC00002C9L) -#endif - -#ifndef STATUS_TRANSPORT_FULL -# define STATUS_TRANSPORT_FULL ((NTSTATUS) 0xC00002CAL) -#endif - -#ifndef STATUS_DS_SAM_INIT_FAILURE -# define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002CBL) -#endif - -#ifndef STATUS_ONLY_IF_CONNECTED -# define STATUS_ONLY_IF_CONNECTED ((NTSTATUS) 0xC00002CCL) -#endif - -#ifndef STATUS_DS_SENSITIVE_GROUP_VIOLATION -# define STATUS_DS_SENSITIVE_GROUP_VIOLATION ((NTSTATUS) 0xC00002CDL) -#endif - -#ifndef STATUS_PNP_RESTART_ENUMERATION -# define STATUS_PNP_RESTART_ENUMERATION ((NTSTATUS) 0xC00002CEL) -#endif - -#ifndef STATUS_JOURNAL_ENTRY_DELETED -# define STATUS_JOURNAL_ENTRY_DELETED ((NTSTATUS) 0xC00002CFL) -#endif - -#ifndef STATUS_DS_CANT_MOD_PRIMARYGROUPID -# define STATUS_DS_CANT_MOD_PRIMARYGROUPID ((NTSTATUS) 0xC00002D0L) -#endif - -#ifndef STATUS_SYSTEM_IMAGE_BAD_SIGNATURE -# define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((NTSTATUS) 0xC00002D1L) -#endif - -#ifndef STATUS_PNP_REBOOT_REQUIRED -# define STATUS_PNP_REBOOT_REQUIRED ((NTSTATUS) 0xC00002D2L) -#endif - -#ifndef STATUS_POWER_STATE_INVALID -# define STATUS_POWER_STATE_INVALID ((NTSTATUS) 0xC00002D3L) -#endif - -#ifndef STATUS_DS_INVALID_GROUP_TYPE -# define STATUS_DS_INVALID_GROUP_TYPE ((NTSTATUS) 0xC00002D4L) -#endif - -#ifndef STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN -# define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D5L) -#endif - -#ifndef STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN -# define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D6L) -#endif - -#ifndef STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER -# define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D7L) -#endif - -#ifndef STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER -# define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC00002D8L) -#endif - -#ifndef STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER -# define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D9L) -#endif - -#ifndef STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER -# define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((NTSTATUS) 0xC00002DAL) -#endif - -#ifndef STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER -# define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((NTSTATUS) 0xC00002DBL) -#endif - -#ifndef STATUS_DS_HAVE_PRIMARY_MEMBERS -# define STATUS_DS_HAVE_PRIMARY_MEMBERS ((NTSTATUS) 0xC00002DCL) -#endif - -#ifndef STATUS_WMI_NOT_SUPPORTED -# define STATUS_WMI_NOT_SUPPORTED ((NTSTATUS) 0xC00002DDL) -#endif - -#ifndef STATUS_INSUFFICIENT_POWER -# define STATUS_INSUFFICIENT_POWER ((NTSTATUS) 0xC00002DEL) -#endif - -#ifndef STATUS_SAM_NEED_BOOTKEY_PASSWORD -# define STATUS_SAM_NEED_BOOTKEY_PASSWORD ((NTSTATUS) 0xC00002DFL) -#endif - -#ifndef STATUS_SAM_NEED_BOOTKEY_FLOPPY -# define STATUS_SAM_NEED_BOOTKEY_FLOPPY ((NTSTATUS) 0xC00002E0L) -#endif - -#ifndef STATUS_DS_CANT_START -# define STATUS_DS_CANT_START ((NTSTATUS) 0xC00002E1L) -#endif - -#ifndef STATUS_DS_INIT_FAILURE -# define STATUS_DS_INIT_FAILURE ((NTSTATUS) 0xC00002E2L) -#endif - -#ifndef STATUS_SAM_INIT_FAILURE -# define STATUS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002E3L) -#endif - -#ifndef STATUS_DS_GC_REQUIRED -# define STATUS_DS_GC_REQUIRED ((NTSTATUS) 0xC00002E4L) -#endif - -#ifndef STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY -# define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((NTSTATUS) 0xC00002E5L) -#endif - -#ifndef STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS -# define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((NTSTATUS) 0xC00002E6L) -#endif - -#ifndef STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED -# define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((NTSTATUS) 0xC00002E7L) -#endif - -#ifndef STATUS_MULTIPLE_FAULT_VIOLATION -# define STATUS_MULTIPLE_FAULT_VIOLATION ((NTSTATUS) 0xC00002E8L) -#endif - -#ifndef STATUS_CURRENT_DOMAIN_NOT_ALLOWED -# define STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((NTSTATUS) 0xC00002E9L) -#endif - -#ifndef STATUS_CANNOT_MAKE -# define STATUS_CANNOT_MAKE ((NTSTATUS) 0xC00002EAL) -#endif - -#ifndef STATUS_SYSTEM_SHUTDOWN -# define STATUS_SYSTEM_SHUTDOWN ((NTSTATUS) 0xC00002EBL) -#endif - -#ifndef STATUS_DS_INIT_FAILURE_CONSOLE -# define STATUS_DS_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002ECL) -#endif - -#ifndef STATUS_DS_SAM_INIT_FAILURE_CONSOLE -# define STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002EDL) -#endif - -#ifndef STATUS_UNFINISHED_CONTEXT_DELETED -# define STATUS_UNFINISHED_CONTEXT_DELETED ((NTSTATUS) 0xC00002EEL) -#endif - -#ifndef STATUS_NO_TGT_REPLY -# define STATUS_NO_TGT_REPLY ((NTSTATUS) 0xC00002EFL) -#endif - -#ifndef STATUS_OBJECTID_NOT_FOUND -# define STATUS_OBJECTID_NOT_FOUND ((NTSTATUS) 0xC00002F0L) -#endif - -#ifndef STATUS_NO_IP_ADDRESSES -# define STATUS_NO_IP_ADDRESSES ((NTSTATUS) 0xC00002F1L) -#endif - -#ifndef STATUS_WRONG_CREDENTIAL_HANDLE -# define STATUS_WRONG_CREDENTIAL_HANDLE ((NTSTATUS) 0xC00002F2L) -#endif - -#ifndef STATUS_CRYPTO_SYSTEM_INVALID -# define STATUS_CRYPTO_SYSTEM_INVALID ((NTSTATUS) 0xC00002F3L) -#endif - -#ifndef STATUS_MAX_REFERRALS_EXCEEDED -# define STATUS_MAX_REFERRALS_EXCEEDED ((NTSTATUS) 0xC00002F4L) -#endif - -#ifndef STATUS_MUST_BE_KDC -# define STATUS_MUST_BE_KDC ((NTSTATUS) 0xC00002F5L) -#endif - -#ifndef STATUS_STRONG_CRYPTO_NOT_SUPPORTED -# define STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((NTSTATUS) 0xC00002F6L) -#endif - -#ifndef STATUS_TOO_MANY_PRINCIPALS -# define STATUS_TOO_MANY_PRINCIPALS ((NTSTATUS) 0xC00002F7L) -#endif - -#ifndef STATUS_NO_PA_DATA -# define STATUS_NO_PA_DATA ((NTSTATUS) 0xC00002F8L) -#endif - -#ifndef STATUS_PKINIT_NAME_MISMATCH -# define STATUS_PKINIT_NAME_MISMATCH ((NTSTATUS) 0xC00002F9L) -#endif - -#ifndef STATUS_SMARTCARD_LOGON_REQUIRED -# define STATUS_SMARTCARD_LOGON_REQUIRED ((NTSTATUS) 0xC00002FAL) -#endif - -#ifndef STATUS_KDC_INVALID_REQUEST -# define STATUS_KDC_INVALID_REQUEST ((NTSTATUS) 0xC00002FBL) -#endif - -#ifndef STATUS_KDC_UNABLE_TO_REFER -# define STATUS_KDC_UNABLE_TO_REFER ((NTSTATUS) 0xC00002FCL) -#endif - -#ifndef STATUS_KDC_UNKNOWN_ETYPE -# define STATUS_KDC_UNKNOWN_ETYPE ((NTSTATUS) 0xC00002FDL) -#endif - -#ifndef STATUS_SHUTDOWN_IN_PROGRESS -# define STATUS_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FEL) -#endif - -#ifndef STATUS_SERVER_SHUTDOWN_IN_PROGRESS -# define STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FFL) -#endif - -#ifndef STATUS_NOT_SUPPORTED_ON_SBS -# define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS) 0xC0000300L) -#endif - -#ifndef STATUS_WMI_GUID_DISCONNECTED -# define STATUS_WMI_GUID_DISCONNECTED ((NTSTATUS) 0xC0000301L) -#endif - -#ifndef STATUS_WMI_ALREADY_DISABLED -# define STATUS_WMI_ALREADY_DISABLED ((NTSTATUS) 0xC0000302L) -#endif - -#ifndef STATUS_WMI_ALREADY_ENABLED -# define STATUS_WMI_ALREADY_ENABLED ((NTSTATUS) 0xC0000303L) -#endif - -#ifndef STATUS_MFT_TOO_FRAGMENTED -# define STATUS_MFT_TOO_FRAGMENTED ((NTSTATUS) 0xC0000304L) -#endif - -#ifndef STATUS_COPY_PROTECTION_FAILURE -# define STATUS_COPY_PROTECTION_FAILURE ((NTSTATUS) 0xC0000305L) -#endif - -#ifndef STATUS_CSS_AUTHENTICATION_FAILURE -# define STATUS_CSS_AUTHENTICATION_FAILURE ((NTSTATUS) 0xC0000306L) -#endif - -#ifndef STATUS_CSS_KEY_NOT_PRESENT -# define STATUS_CSS_KEY_NOT_PRESENT ((NTSTATUS) 0xC0000307L) -#endif - -#ifndef STATUS_CSS_KEY_NOT_ESTABLISHED -# define STATUS_CSS_KEY_NOT_ESTABLISHED ((NTSTATUS) 0xC0000308L) -#endif - -#ifndef STATUS_CSS_SCRAMBLED_SECTOR -# define STATUS_CSS_SCRAMBLED_SECTOR ((NTSTATUS) 0xC0000309L) -#endif - -#ifndef STATUS_CSS_REGION_MISMATCH -# define STATUS_CSS_REGION_MISMATCH ((NTSTATUS) 0xC000030AL) -#endif - -#ifndef STATUS_CSS_RESETS_EXHAUSTED -# define STATUS_CSS_RESETS_EXHAUSTED ((NTSTATUS) 0xC000030BL) -#endif - -#ifndef STATUS_PKINIT_FAILURE -# define STATUS_PKINIT_FAILURE ((NTSTATUS) 0xC0000320L) -#endif - -#ifndef STATUS_SMARTCARD_SUBSYSTEM_FAILURE -# define STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((NTSTATUS) 0xC0000321L) -#endif - -#ifndef STATUS_NO_KERB_KEY -# define STATUS_NO_KERB_KEY ((NTSTATUS) 0xC0000322L) -#endif - -#ifndef STATUS_HOST_DOWN -# define STATUS_HOST_DOWN ((NTSTATUS) 0xC0000350L) -#endif - -#ifndef STATUS_UNSUPPORTED_PREAUTH -# define STATUS_UNSUPPORTED_PREAUTH ((NTSTATUS) 0xC0000351L) -#endif - -#ifndef STATUS_EFS_ALG_BLOB_TOO_BIG -# define STATUS_EFS_ALG_BLOB_TOO_BIG ((NTSTATUS) 0xC0000352L) -#endif - -#ifndef STATUS_PORT_NOT_SET -# define STATUS_PORT_NOT_SET ((NTSTATUS) 0xC0000353L) -#endif - -#ifndef STATUS_DEBUGGER_INACTIVE -# define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354L) -#endif - -#ifndef STATUS_DS_VERSION_CHECK_FAILURE -# define STATUS_DS_VERSION_CHECK_FAILURE ((NTSTATUS) 0xC0000355L) -#endif - -#ifndef STATUS_AUDITING_DISABLED -# define STATUS_AUDITING_DISABLED ((NTSTATUS) 0xC0000356L) -#endif - -#ifndef STATUS_PRENT4_MACHINE_ACCOUNT -# define STATUS_PRENT4_MACHINE_ACCOUNT ((NTSTATUS) 0xC0000357L) -#endif - -#ifndef STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER -# define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC0000358L) -#endif - -#ifndef STATUS_INVALID_IMAGE_WIN_32 -# define STATUS_INVALID_IMAGE_WIN_32 ((NTSTATUS) 0xC0000359L) -#endif - -#ifndef STATUS_INVALID_IMAGE_WIN_64 -# define STATUS_INVALID_IMAGE_WIN_64 ((NTSTATUS) 0xC000035AL) -#endif - -#ifndef STATUS_BAD_BINDINGS -# define STATUS_BAD_BINDINGS ((NTSTATUS) 0xC000035BL) -#endif - -#ifndef STATUS_NETWORK_SESSION_EXPIRED -# define STATUS_NETWORK_SESSION_EXPIRED ((NTSTATUS) 0xC000035CL) -#endif - -#ifndef STATUS_APPHELP_BLOCK -# define STATUS_APPHELP_BLOCK ((NTSTATUS) 0xC000035DL) -#endif - -#ifndef STATUS_ALL_SIDS_FILTERED -# define STATUS_ALL_SIDS_FILTERED ((NTSTATUS) 0xC000035EL) -#endif - -#ifndef STATUS_NOT_SAFE_MODE_DRIVER -# define STATUS_NOT_SAFE_MODE_DRIVER ((NTSTATUS) 0xC000035FL) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT -# define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((NTSTATUS) 0xC0000361L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PATH -# define STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((NTSTATUS) 0xC0000362L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER -# define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((NTSTATUS) 0xC0000363L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_OTHER -# define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((NTSTATUS) 0xC0000364L) -#endif - -#ifndef STATUS_FAILED_DRIVER_ENTRY -# define STATUS_FAILED_DRIVER_ENTRY ((NTSTATUS) 0xC0000365L) -#endif - -#ifndef STATUS_DEVICE_ENUMERATION_ERROR -# define STATUS_DEVICE_ENUMERATION_ERROR ((NTSTATUS) 0xC0000366L) -#endif - -#ifndef STATUS_MOUNT_POINT_NOT_RESOLVED -# define STATUS_MOUNT_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000368L) -#endif - -#ifndef STATUS_INVALID_DEVICE_OBJECT_PARAMETER -# define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS) 0xC0000369L) -#endif - -#ifndef STATUS_MCA_OCCURED -# define STATUS_MCA_OCCURED ((NTSTATUS) 0xC000036AL) -#endif - -#ifndef STATUS_DRIVER_BLOCKED_CRITICAL -# define STATUS_DRIVER_BLOCKED_CRITICAL ((NTSTATUS) 0xC000036BL) -#endif - -#ifndef STATUS_DRIVER_BLOCKED -# define STATUS_DRIVER_BLOCKED ((NTSTATUS) 0xC000036CL) -#endif - -#ifndef STATUS_DRIVER_DATABASE_ERROR -# define STATUS_DRIVER_DATABASE_ERROR ((NTSTATUS) 0xC000036DL) -#endif - -#ifndef STATUS_SYSTEM_HIVE_TOO_LARGE -# define STATUS_SYSTEM_HIVE_TOO_LARGE ((NTSTATUS) 0xC000036EL) -#endif - -#ifndef STATUS_INVALID_IMPORT_OF_NON_DLL -# define STATUS_INVALID_IMPORT_OF_NON_DLL ((NTSTATUS) 0xC000036FL) -#endif - -#ifndef STATUS_DS_SHUTTING_DOWN -# define STATUS_DS_SHUTTING_DOWN ((NTSTATUS) 0x40000370L) -#endif - -#ifndef STATUS_NO_SECRETS -# define STATUS_NO_SECRETS ((NTSTATUS) 0xC0000371L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY -# define STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY ((NTSTATUS) 0xC0000372L) -#endif - -#ifndef STATUS_FAILED_STACK_SWITCH -# define STATUS_FAILED_STACK_SWITCH ((NTSTATUS) 0xC0000373L) -#endif - -#ifndef STATUS_HEAP_CORRUPTION -# define STATUS_HEAP_CORRUPTION ((NTSTATUS) 0xC0000374L) -#endif - -#ifndef STATUS_SMARTCARD_WRONG_PIN -# define STATUS_SMARTCARD_WRONG_PIN ((NTSTATUS) 0xC0000380L) -#endif - -#ifndef STATUS_SMARTCARD_CARD_BLOCKED -# define STATUS_SMARTCARD_CARD_BLOCKED ((NTSTATUS) 0xC0000381L) -#endif - -#ifndef STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED -# define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((NTSTATUS) 0xC0000382L) -#endif - -#ifndef STATUS_SMARTCARD_NO_CARD -# define STATUS_SMARTCARD_NO_CARD ((NTSTATUS) 0xC0000383L) -#endif - -#ifndef STATUS_SMARTCARD_NO_KEY_CONTAINER -# define STATUS_SMARTCARD_NO_KEY_CONTAINER ((NTSTATUS) 0xC0000384L) -#endif - -#ifndef STATUS_SMARTCARD_NO_CERTIFICATE -# define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS) 0xC0000385L) -#endif - -#ifndef STATUS_SMARTCARD_NO_KEYSET -# define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS) 0xC0000386L) -#endif - -#ifndef STATUS_SMARTCARD_IO_ERROR -# define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS) 0xC0000387L) -#endif - -#ifndef STATUS_DOWNGRADE_DETECTED -# define STATUS_DOWNGRADE_DETECTED ((NTSTATUS) 0xC0000388L) -#endif - -#ifndef STATUS_SMARTCARD_CERT_REVOKED -# define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS) 0xC0000389L) -#endif - -#ifndef STATUS_ISSUING_CA_UNTRUSTED -# define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS) 0xC000038AL) -#endif - -#ifndef STATUS_REVOCATION_OFFLINE_C -# define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS) 0xC000038BL) -#endif - -#ifndef STATUS_PKINIT_CLIENT_FAILURE -# define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS) 0xC000038CL) -#endif - -#ifndef STATUS_SMARTCARD_CERT_EXPIRED -# define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS) 0xC000038DL) -#endif - -#ifndef STATUS_DRIVER_FAILED_PRIOR_UNLOAD -# define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS) 0xC000038EL) -#endif - -#ifndef STATUS_SMARTCARD_SILENT_CONTEXT -# define STATUS_SMARTCARD_SILENT_CONTEXT ((NTSTATUS) 0xC000038FL) -#endif - -#ifndef STATUS_PER_USER_TRUST_QUOTA_EXCEEDED -# define STATUS_PER_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000401L) -#endif - -#ifndef STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED -# define STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000402L) -#endif - -#ifndef STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED -# define STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000403L) -#endif - -#ifndef STATUS_DS_NAME_NOT_UNIQUE -# define STATUS_DS_NAME_NOT_UNIQUE ((NTSTATUS) 0xC0000404L) -#endif - -#ifndef STATUS_DS_DUPLICATE_ID_FOUND -# define STATUS_DS_DUPLICATE_ID_FOUND ((NTSTATUS) 0xC0000405L) -#endif - -#ifndef STATUS_DS_GROUP_CONVERSION_ERROR -# define STATUS_DS_GROUP_CONVERSION_ERROR ((NTSTATUS) 0xC0000406L) -#endif - -#ifndef STATUS_VOLSNAP_PREPARE_HIBERNATE -# define STATUS_VOLSNAP_PREPARE_HIBERNATE ((NTSTATUS) 0xC0000407L) -#endif - -#ifndef STATUS_USER2USER_REQUIRED -# define STATUS_USER2USER_REQUIRED ((NTSTATUS) 0xC0000408L) -#endif - -#ifndef STATUS_STACK_BUFFER_OVERRUN -# define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS) 0xC0000409L) -#endif - -#ifndef STATUS_NO_S4U_PROT_SUPPORT -# define STATUS_NO_S4U_PROT_SUPPORT ((NTSTATUS) 0xC000040AL) -#endif - -#ifndef STATUS_CROSSREALM_DELEGATION_FAILURE -# define STATUS_CROSSREALM_DELEGATION_FAILURE ((NTSTATUS) 0xC000040BL) -#endif - -#ifndef STATUS_REVOCATION_OFFLINE_KDC -# define STATUS_REVOCATION_OFFLINE_KDC ((NTSTATUS) 0xC000040CL) -#endif - -#ifndef STATUS_ISSUING_CA_UNTRUSTED_KDC -# define STATUS_ISSUING_CA_UNTRUSTED_KDC ((NTSTATUS) 0xC000040DL) -#endif - -#ifndef STATUS_KDC_CERT_EXPIRED -# define STATUS_KDC_CERT_EXPIRED ((NTSTATUS) 0xC000040EL) -#endif - -#ifndef STATUS_KDC_CERT_REVOKED -# define STATUS_KDC_CERT_REVOKED ((NTSTATUS) 0xC000040FL) -#endif - -#ifndef STATUS_PARAMETER_QUOTA_EXCEEDED -# define STATUS_PARAMETER_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000410L) -#endif - -#ifndef STATUS_HIBERNATION_FAILURE -# define STATUS_HIBERNATION_FAILURE ((NTSTATUS) 0xC0000411L) -#endif - -#ifndef STATUS_DELAY_LOAD_FAILED -# define STATUS_DELAY_LOAD_FAILED ((NTSTATUS) 0xC0000412L) -#endif - -#ifndef STATUS_AUTHENTICATION_FIREWALL_FAILED -# define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS) 0xC0000413L) -#endif - -#ifndef STATUS_VDM_DISALLOWED -# define STATUS_VDM_DISALLOWED ((NTSTATUS) 0xC0000414L) -#endif - -#ifndef STATUS_HUNG_DISPLAY_DRIVER_THREAD -# define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS) 0xC0000415L) -#endif - -#ifndef STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE -# define STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE ((NTSTATUS) 0xC0000416L) -#endif - -#ifndef STATUS_INVALID_CRUNTIME_PARAMETER -# define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS) 0xC0000417L) -#endif - -#ifndef STATUS_NTLM_BLOCKED -# define STATUS_NTLM_BLOCKED ((NTSTATUS) 0xC0000418L) -#endif - -#ifndef STATUS_DS_SRC_SID_EXISTS_IN_FOREST -# define STATUS_DS_SRC_SID_EXISTS_IN_FOREST ((NTSTATUS) 0xC0000419L) -#endif - -#ifndef STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST -# define STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041AL) -#endif - -#ifndef STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST -# define STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041BL) -#endif - -#ifndef STATUS_INVALID_USER_PRINCIPAL_NAME -# define STATUS_INVALID_USER_PRINCIPAL_NAME ((NTSTATUS) 0xC000041CL) -#endif - -#ifndef STATUS_FATAL_USER_CALLBACK_EXCEPTION -# define STATUS_FATAL_USER_CALLBACK_EXCEPTION ((NTSTATUS) 0xC000041DL) -#endif - -#ifndef STATUS_ASSERTION_FAILURE -# define STATUS_ASSERTION_FAILURE ((NTSTATUS) 0xC0000420L) -#endif - -#ifndef STATUS_VERIFIER_STOP -# define STATUS_VERIFIER_STOP ((NTSTATUS) 0xC0000421L) -#endif - -#ifndef STATUS_CALLBACK_POP_STACK -# define STATUS_CALLBACK_POP_STACK ((NTSTATUS) 0xC0000423L) -#endif - -#ifndef STATUS_INCOMPATIBLE_DRIVER_BLOCKED -# define STATUS_INCOMPATIBLE_DRIVER_BLOCKED ((NTSTATUS) 0xC0000424L) -#endif - -#ifndef STATUS_HIVE_UNLOADED -# define STATUS_HIVE_UNLOADED ((NTSTATUS) 0xC0000425L) -#endif - -#ifndef STATUS_COMPRESSION_DISABLED -# define STATUS_COMPRESSION_DISABLED ((NTSTATUS) 0xC0000426L) -#endif - -#ifndef STATUS_FILE_SYSTEM_LIMITATION -# define STATUS_FILE_SYSTEM_LIMITATION ((NTSTATUS) 0xC0000427L) -#endif - -#ifndef STATUS_INVALID_IMAGE_HASH -# define STATUS_INVALID_IMAGE_HASH ((NTSTATUS) 0xC0000428L) -#endif - -#ifndef STATUS_NOT_CAPABLE -# define STATUS_NOT_CAPABLE ((NTSTATUS) 0xC0000429L) -#endif - -#ifndef STATUS_REQUEST_OUT_OF_SEQUENCE -# define STATUS_REQUEST_OUT_OF_SEQUENCE ((NTSTATUS) 0xC000042AL) -#endif - -#ifndef STATUS_IMPLEMENTATION_LIMIT -# define STATUS_IMPLEMENTATION_LIMIT ((NTSTATUS) 0xC000042BL) -#endif - -#ifndef STATUS_ELEVATION_REQUIRED -# define STATUS_ELEVATION_REQUIRED ((NTSTATUS) 0xC000042CL) -#endif - -#ifndef STATUS_NO_SECURITY_CONTEXT -# define STATUS_NO_SECURITY_CONTEXT ((NTSTATUS) 0xC000042DL) -#endif - -#ifndef STATUS_PKU2U_CERT_FAILURE -# define STATUS_PKU2U_CERT_FAILURE ((NTSTATUS) 0xC000042FL) -#endif - -#ifndef STATUS_BEYOND_VDL -# define STATUS_BEYOND_VDL ((NTSTATUS) 0xC0000432L) -#endif - -#ifndef STATUS_ENCOUNTERED_WRITE_IN_PROGRESS -# define STATUS_ENCOUNTERED_WRITE_IN_PROGRESS ((NTSTATUS) 0xC0000433L) -#endif - -#ifndef STATUS_PTE_CHANGED -# define STATUS_PTE_CHANGED ((NTSTATUS) 0xC0000434L) -#endif - -#ifndef STATUS_PURGE_FAILED -# define STATUS_PURGE_FAILED ((NTSTATUS) 0xC0000435L) -#endif - -#ifndef STATUS_CRED_REQUIRES_CONFIRMATION -# define STATUS_CRED_REQUIRES_CONFIRMATION ((NTSTATUS) 0xC0000440L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE -# define STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE ((NTSTATUS) 0xC0000441L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER -# define STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER ((NTSTATUS) 0xC0000442L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE -# define STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE ((NTSTATUS) 0xC0000443L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE -# define STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE ((NTSTATUS) 0xC0000444L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_FILE_NOT_CSE -# define STATUS_CS_ENCRYPTION_FILE_NOT_CSE ((NTSTATUS) 0xC0000445L) -#endif - -#ifndef STATUS_INVALID_LABEL -# define STATUS_INVALID_LABEL ((NTSTATUS) 0xC0000446L) -#endif - -#ifndef STATUS_DRIVER_PROCESS_TERMINATED -# define STATUS_DRIVER_PROCESS_TERMINATED ((NTSTATUS) 0xC0000450L) -#endif - -#ifndef STATUS_AMBIGUOUS_SYSTEM_DEVICE -# define STATUS_AMBIGUOUS_SYSTEM_DEVICE ((NTSTATUS) 0xC0000451L) -#endif - -#ifndef STATUS_SYSTEM_DEVICE_NOT_FOUND -# define STATUS_SYSTEM_DEVICE_NOT_FOUND ((NTSTATUS) 0xC0000452L) -#endif - -#ifndef STATUS_RESTART_BOOT_APPLICATION -# define STATUS_RESTART_BOOT_APPLICATION ((NTSTATUS) 0xC0000453L) -#endif - -#ifndef STATUS_INSUFFICIENT_NVRAM_RESOURCES -# define STATUS_INSUFFICIENT_NVRAM_RESOURCES ((NTSTATUS) 0xC0000454L) -#endif - -#ifndef STATUS_INVALID_TASK_NAME -# define STATUS_INVALID_TASK_NAME ((NTSTATUS) 0xC0000500L) -#endif - -#ifndef STATUS_INVALID_TASK_INDEX -# define STATUS_INVALID_TASK_INDEX ((NTSTATUS) 0xC0000501L) -#endif - -#ifndef STATUS_THREAD_ALREADY_IN_TASK -# define STATUS_THREAD_ALREADY_IN_TASK ((NTSTATUS) 0xC0000502L) -#endif - -#ifndef STATUS_CALLBACK_BYPASS -# define STATUS_CALLBACK_BYPASS ((NTSTATUS) 0xC0000503L) -#endif - -#ifndef STATUS_FAIL_FAST_EXCEPTION -# define STATUS_FAIL_FAST_EXCEPTION ((NTSTATUS) 0xC0000602L) -#endif - -#ifndef STATUS_IMAGE_CERT_REVOKED -# define STATUS_IMAGE_CERT_REVOKED ((NTSTATUS) 0xC0000603L) -#endif - -#ifndef STATUS_PORT_CLOSED -# define STATUS_PORT_CLOSED ((NTSTATUS) 0xC0000700L) -#endif - -#ifndef STATUS_MESSAGE_LOST -# define STATUS_MESSAGE_LOST ((NTSTATUS) 0xC0000701L) -#endif - -#ifndef STATUS_INVALID_MESSAGE -# define STATUS_INVALID_MESSAGE ((NTSTATUS) 0xC0000702L) -#endif - -#ifndef STATUS_REQUEST_CANCELED -# define STATUS_REQUEST_CANCELED ((NTSTATUS) 0xC0000703L) -#endif - -#ifndef STATUS_RECURSIVE_DISPATCH -# define STATUS_RECURSIVE_DISPATCH ((NTSTATUS) 0xC0000704L) -#endif - -#ifndef STATUS_LPC_RECEIVE_BUFFER_EXPECTED -# define STATUS_LPC_RECEIVE_BUFFER_EXPECTED ((NTSTATUS) 0xC0000705L) -#endif - -#ifndef STATUS_LPC_INVALID_CONNECTION_USAGE -# define STATUS_LPC_INVALID_CONNECTION_USAGE ((NTSTATUS) 0xC0000706L) -#endif - -#ifndef STATUS_LPC_REQUESTS_NOT_ALLOWED -# define STATUS_LPC_REQUESTS_NOT_ALLOWED ((NTSTATUS) 0xC0000707L) -#endif - -#ifndef STATUS_RESOURCE_IN_USE -# define STATUS_RESOURCE_IN_USE ((NTSTATUS) 0xC0000708L) -#endif - -#ifndef STATUS_HARDWARE_MEMORY_ERROR -# define STATUS_HARDWARE_MEMORY_ERROR ((NTSTATUS) 0xC0000709L) -#endif - -#ifndef STATUS_THREADPOOL_HANDLE_EXCEPTION -# define STATUS_THREADPOOL_HANDLE_EXCEPTION ((NTSTATUS) 0xC000070AL) -#endif - -#ifndef STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070BL) -#endif - -#ifndef STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070CL) -#endif - -#ifndef STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070DL) -#endif - -#ifndef STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070EL) -#endif - -#ifndef STATUS_THREADPOOL_RELEASED_DURING_OPERATION -# define STATUS_THREADPOOL_RELEASED_DURING_OPERATION ((NTSTATUS) 0xC000070FL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING -# define STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000710L) -#endif - -#ifndef STATUS_APC_RETURNED_WHILE_IMPERSONATING -# define STATUS_APC_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000711L) -#endif - -#ifndef STATUS_PROCESS_IS_PROTECTED -# define STATUS_PROCESS_IS_PROTECTED ((NTSTATUS) 0xC0000712L) -#endif - -#ifndef STATUS_MCA_EXCEPTION -# define STATUS_MCA_EXCEPTION ((NTSTATUS) 0xC0000713L) -#endif - -#ifndef STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE -# define STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE ((NTSTATUS) 0xC0000714L) -#endif - -#ifndef STATUS_SYMLINK_CLASS_DISABLED -# define STATUS_SYMLINK_CLASS_DISABLED ((NTSTATUS) 0xC0000715L) -#endif - -#ifndef STATUS_INVALID_IDN_NORMALIZATION -# define STATUS_INVALID_IDN_NORMALIZATION ((NTSTATUS) 0xC0000716L) -#endif - -#ifndef STATUS_NO_UNICODE_TRANSLATION -# define STATUS_NO_UNICODE_TRANSLATION ((NTSTATUS) 0xC0000717L) -#endif - -#ifndef STATUS_ALREADY_REGISTERED -# define STATUS_ALREADY_REGISTERED ((NTSTATUS) 0xC0000718L) -#endif - -#ifndef STATUS_CONTEXT_MISMATCH -# define STATUS_CONTEXT_MISMATCH ((NTSTATUS) 0xC0000719L) -#endif - -#ifndef STATUS_PORT_ALREADY_HAS_COMPLETION_LIST -# define STATUS_PORT_ALREADY_HAS_COMPLETION_LIST ((NTSTATUS) 0xC000071AL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_THREAD_PRIORITY -# define STATUS_CALLBACK_RETURNED_THREAD_PRIORITY ((NTSTATUS) 0xC000071BL) -#endif - -#ifndef STATUS_INVALID_THREAD -# define STATUS_INVALID_THREAD ((NTSTATUS) 0xC000071CL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_TRANSACTION -# define STATUS_CALLBACK_RETURNED_TRANSACTION ((NTSTATUS) 0xC000071DL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_LDR_LOCK -# define STATUS_CALLBACK_RETURNED_LDR_LOCK ((NTSTATUS) 0xC000071EL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_LANG -# define STATUS_CALLBACK_RETURNED_LANG ((NTSTATUS) 0xC000071FL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_PRI_BACK -# define STATUS_CALLBACK_RETURNED_PRI_BACK ((NTSTATUS) 0xC0000720L) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_THREAD_AFFINITY -# define STATUS_CALLBACK_RETURNED_THREAD_AFFINITY ((NTSTATUS) 0xC0000721L) -#endif - -#ifndef STATUS_DISK_REPAIR_DISABLED -# define STATUS_DISK_REPAIR_DISABLED ((NTSTATUS) 0xC0000800L) -#endif - -#ifndef STATUS_DS_DOMAIN_RENAME_IN_PROGRESS -# define STATUS_DS_DOMAIN_RENAME_IN_PROGRESS ((NTSTATUS) 0xC0000801L) -#endif - -#ifndef STATUS_DISK_QUOTA_EXCEEDED -# define STATUS_DISK_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000802L) -#endif - -#ifndef STATUS_DATA_LOST_REPAIR -# define STATUS_DATA_LOST_REPAIR ((NTSTATUS) 0x80000803L) -#endif - -#ifndef STATUS_CONTENT_BLOCKED -# define STATUS_CONTENT_BLOCKED ((NTSTATUS) 0xC0000804L) -#endif - -#ifndef STATUS_BAD_CLUSTERS -# define STATUS_BAD_CLUSTERS ((NTSTATUS) 0xC0000805L) -#endif - -#ifndef STATUS_VOLUME_DIRTY -# define STATUS_VOLUME_DIRTY ((NTSTATUS) 0xC0000806L) -#endif - -#ifndef STATUS_FILE_CHECKED_OUT -# define STATUS_FILE_CHECKED_OUT ((NTSTATUS) 0xC0000901L) -#endif - -#ifndef STATUS_CHECKOUT_REQUIRED -# define STATUS_CHECKOUT_REQUIRED ((NTSTATUS) 0xC0000902L) -#endif - -#ifndef STATUS_BAD_FILE_TYPE -# define STATUS_BAD_FILE_TYPE ((NTSTATUS) 0xC0000903L) -#endif - -#ifndef STATUS_FILE_TOO_LARGE -# define STATUS_FILE_TOO_LARGE ((NTSTATUS) 0xC0000904L) -#endif - -#ifndef STATUS_FORMS_AUTH_REQUIRED -# define STATUS_FORMS_AUTH_REQUIRED ((NTSTATUS) 0xC0000905L) -#endif - -#ifndef STATUS_VIRUS_INFECTED -# define STATUS_VIRUS_INFECTED ((NTSTATUS) 0xC0000906L) -#endif - -#ifndef STATUS_VIRUS_DELETED -# define STATUS_VIRUS_DELETED ((NTSTATUS) 0xC0000907L) -#endif - -#ifndef STATUS_BAD_MCFG_TABLE -# define STATUS_BAD_MCFG_TABLE ((NTSTATUS) 0xC0000908L) -#endif - -#ifndef STATUS_CANNOT_BREAK_OPLOCK -# define STATUS_CANNOT_BREAK_OPLOCK ((NTSTATUS) 0xC0000909L) -#endif - -#ifndef STATUS_WOW_ASSERTION -# define STATUS_WOW_ASSERTION ((NTSTATUS) 0xC0009898L) -#endif - -#ifndef STATUS_INVALID_SIGNATURE -# define STATUS_INVALID_SIGNATURE ((NTSTATUS) 0xC000A000L) -#endif - -#ifndef STATUS_HMAC_NOT_SUPPORTED -# define STATUS_HMAC_NOT_SUPPORTED ((NTSTATUS) 0xC000A001L) -#endif - -#ifndef STATUS_AUTH_TAG_MISMATCH -# define STATUS_AUTH_TAG_MISMATCH ((NTSTATUS) 0xC000A002L) -#endif - -#ifndef STATUS_IPSEC_QUEUE_OVERFLOW -# define STATUS_IPSEC_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A010L) -#endif - -#ifndef STATUS_ND_QUEUE_OVERFLOW -# define STATUS_ND_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A011L) -#endif - -#ifndef STATUS_HOPLIMIT_EXCEEDED -# define STATUS_HOPLIMIT_EXCEEDED ((NTSTATUS) 0xC000A012L) -#endif - -#ifndef STATUS_PROTOCOL_NOT_SUPPORTED -# define STATUS_PROTOCOL_NOT_SUPPORTED ((NTSTATUS) 0xC000A013L) -#endif - -#ifndef STATUS_FASTPATH_REJECTED -# define STATUS_FASTPATH_REJECTED ((NTSTATUS) 0xC000A014L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED -# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED ((NTSTATUS) 0xC000A080L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR -# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR ((NTSTATUS) 0xC000A081L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR -# define STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR ((NTSTATUS) 0xC000A082L) -#endif - -#ifndef STATUS_XML_PARSE_ERROR -# define STATUS_XML_PARSE_ERROR ((NTSTATUS) 0xC000A083L) -#endif - -#ifndef STATUS_XMLDSIG_ERROR -# define STATUS_XMLDSIG_ERROR ((NTSTATUS) 0xC000A084L) -#endif - -#ifndef STATUS_WRONG_COMPARTMENT -# define STATUS_WRONG_COMPARTMENT ((NTSTATUS) 0xC000A085L) -#endif - -#ifndef STATUS_AUTHIP_FAILURE -# define STATUS_AUTHIP_FAILURE ((NTSTATUS) 0xC000A086L) -#endif - -#ifndef STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS -# define STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS ((NTSTATUS) 0xC000A087L) -#endif - -#ifndef STATUS_DS_OID_NOT_FOUND -# define STATUS_DS_OID_NOT_FOUND ((NTSTATUS) 0xC000A088L) -#endif - -#ifndef STATUS_HASH_NOT_SUPPORTED -# define STATUS_HASH_NOT_SUPPORTED ((NTSTATUS) 0xC000A100L) -#endif - -#ifndef STATUS_HASH_NOT_PRESENT -# define STATUS_HASH_NOT_PRESENT ((NTSTATUS) 0xC000A101L) -#endif - -/* This is not the NTSTATUS_FROM_WIN32 that the DDK provides, because the */ -/* DDK got it wrong! */ -#ifdef NTSTATUS_FROM_WIN32 -# undef NTSTATUS_FROM_WIN32 -#endif -#define NTSTATUS_FROM_WIN32(error) ((NTSTATUS) (error) <= 0 ? \ - ((NTSTATUS) (error)) : ((NTSTATUS) (((error) & 0x0000FFFF) | \ - (FACILITY_NTWIN32 << 16) | ERROR_SEVERITY_WARNING))) - -#ifndef JOB_OBJECT_LIMIT_PROCESS_MEMORY -# define JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x00000100 -#endif -#ifndef JOB_OBJECT_LIMIT_JOB_MEMORY -# define JOB_OBJECT_LIMIT_JOB_MEMORY 0x00000200 -#endif -#ifndef JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION -# define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400 -#endif -#ifndef JOB_OBJECT_LIMIT_BREAKAWAY_OK -# define JOB_OBJECT_LIMIT_BREAKAWAY_OK 0x00000800 -#endif -#ifndef JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK -# define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 0x00001000 -#endif -#ifndef JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE -# define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000 -#endif - -#ifndef DEVICE_TYPE -# define DEVICE_TYPE DWORD -#endif - -/* from ntifs.h */ -/* MinGW already has it, mingw-w64 does not. */ -#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR) - typedef struct _REPARSE_DATA_BUFFER { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; - } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; -#endif - -typedef struct _IO_STATUS_BLOCK { - union { - NTSTATUS Status; - PVOID Pointer; - } DUMMYUNIONNAME; - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - -typedef enum _FILE_INFORMATION_CLASS { - FileDirectoryInformation = 1, - FileFullDirectoryInformation, - FileBothDirectoryInformation, - FileBasicInformation, - FileStandardInformation, - FileInternalInformation, - FileEaInformation, - FileAccessInformation, - FileNameInformation, - FileRenameInformation, - FileLinkInformation, - FileNamesInformation, - FileDispositionInformation, - FilePositionInformation, - FileFullEaInformation, - FileModeInformation, - FileAlignmentInformation, - FileAllInformation, - FileAllocationInformation, - FileEndOfFileInformation, - FileAlternateNameInformation, - FileStreamInformation, - FilePipeInformation, - FilePipeLocalInformation, - FilePipeRemoteInformation, - FileMailslotQueryInformation, - FileMailslotSetInformation, - FileCompressionInformation, - FileObjectIdInformation, - FileCompletionInformation, - FileMoveClusterInformation, - FileQuotaInformation, - FileReparsePointInformation, - FileNetworkOpenInformation, - FileAttributeTagInformation, - FileTrackingInformation, - FileIdBothDirectoryInformation, - FileIdFullDirectoryInformation, - FileValidDataLengthInformation, - FileShortNameInformation, - FileIoCompletionNotificationInformation, - FileIoStatusBlockRangeInformation, - FileIoPriorityHintInformation, - FileSfioReserveInformation, - FileSfioVolumeInformation, - FileHardLinkInformation, - FileProcessIdsUsingFileInformation, - FileNormalizedNameInformation, - FileNetworkPhysicalNameInformation, - FileIdGlobalTxDirectoryInformation, - FileIsRemoteDeviceInformation, - FileAttributeCacheInformation, - FileNumaNodeInformation, - FileStandardLinkInformation, - FileRemoteProtocolInformation, - FileMaximumInformation -} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; - -typedef struct _FILE_BASIC_INFORMATION { - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - DWORD FileAttributes; -} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; - -typedef struct _FILE_STANDARD_INFORMATION { - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG NumberOfLinks; - BOOLEAN DeletePending; - BOOLEAN Directory; -} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; - -typedef struct _FILE_INTERNAL_INFORMATION { - LARGE_INTEGER IndexNumber; -} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; - -typedef struct _FILE_EA_INFORMATION { - ULONG EaSize; -} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; - -typedef struct _FILE_ACCESS_INFORMATION { - ACCESS_MASK AccessFlags; -} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; - -typedef struct _FILE_POSITION_INFORMATION { - LARGE_INTEGER CurrentByteOffset; -} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; - -typedef struct _FILE_MODE_INFORMATION { - ULONG Mode; -} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; - -typedef struct _FILE_ALIGNMENT_INFORMATION { - ULONG AlignmentRequirement; -} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; - -typedef struct _FILE_NAME_INFORMATION { - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; - -typedef struct _FILE_END_OF_FILE_INFORMATION { - LARGE_INTEGER EndOfFile; -} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; - -typedef struct _FILE_ALL_INFORMATION { - FILE_BASIC_INFORMATION BasicInformation; - FILE_STANDARD_INFORMATION StandardInformation; - FILE_INTERNAL_INFORMATION InternalInformation; - FILE_EA_INFORMATION EaInformation; - FILE_ACCESS_INFORMATION AccessInformation; - FILE_POSITION_INFORMATION PositionInformation; - FILE_MODE_INFORMATION ModeInformation; - FILE_ALIGNMENT_INFORMATION AlignmentInformation; - FILE_NAME_INFORMATION NameInformation; -} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; - -typedef struct _FILE_DISPOSITION_INFORMATION { - BOOLEAN DeleteFile; -} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; - -typedef struct _FILE_PIPE_LOCAL_INFORMATION { - ULONG NamedPipeType; - ULONG NamedPipeConfiguration; - ULONG MaximumInstances; - ULONG CurrentInstances; - ULONG InboundQuota; - ULONG ReadDataAvailable; - ULONG OutboundQuota; - ULONG WriteQuotaAvailable; - ULONG NamedPipeState; - ULONG NamedPipeEnd; -} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; - -#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 -#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 - -typedef enum _FS_INFORMATION_CLASS { - FileFsVolumeInformation = 1, - FileFsLabelInformation = 2, - FileFsSizeInformation = 3, - FileFsDeviceInformation = 4, - FileFsAttributeInformation = 5, - FileFsControlInformation = 6, - FileFsFullSizeInformation = 7, - FileFsObjectIdInformation = 8, - FileFsDriverPathInformation = 9, - FileFsVolumeFlagsInformation = 10, - FileFsSectorSizeInformation = 11 -} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; - -typedef struct _FILE_FS_VOLUME_INFORMATION { - LARGE_INTEGER VolumeCreationTime; - ULONG VolumeSerialNumber; - ULONG VolumeLabelLength; - BOOLEAN SupportsObjects; - WCHAR VolumeLabel[1]; -} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; - -typedef struct _FILE_FS_LABEL_INFORMATION { - ULONG VolumeLabelLength; - WCHAR VolumeLabel[1]; -} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; - -typedef struct _FILE_FS_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER AvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; - -typedef struct _FILE_FS_DEVICE_INFORMATION { - DEVICE_TYPE DeviceType; - ULONG Characteristics; -} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; - -typedef struct _FILE_FS_ATTRIBUTE_INFORMATION { - ULONG FileSystemAttributes; - LONG MaximumComponentNameLength; - ULONG FileSystemNameLength; - WCHAR FileSystemName[1]; -} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION; - -typedef struct _FILE_FS_CONTROL_INFORMATION { - LARGE_INTEGER FreeSpaceStartFiltering; - LARGE_INTEGER FreeSpaceThreshold; - LARGE_INTEGER FreeSpaceStopFiltering; - LARGE_INTEGER DefaultQuotaThreshold; - LARGE_INTEGER DefaultQuotaLimit; - ULONG FileSystemControlFlags; -} FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION; - -typedef struct _FILE_FS_FULL_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER CallerAvailableAllocationUnits; - LARGE_INTEGER ActualAvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION; - -typedef struct _FILE_FS_OBJECTID_INFORMATION { - UCHAR ObjectId[16]; - UCHAR ExtendedInfo[48]; -} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION; - -typedef struct _FILE_FS_DRIVER_PATH_INFORMATION { - BOOLEAN DriverInPath; - ULONG DriverNameLength; - WCHAR DriverName[1]; -} FILE_FS_DRIVER_PATH_INFORMATION, *PFILE_FS_DRIVER_PATH_INFORMATION; - -typedef struct _FILE_FS_VOLUME_FLAGS_INFORMATION { - ULONG Flags; -} FILE_FS_VOLUME_FLAGS_INFORMATION, *PFILE_FS_VOLUME_FLAGS_INFORMATION; - -typedef struct _FILE_FS_SECTOR_SIZE_INFORMATION { - ULONG LogicalBytesPerSector; - ULONG PhysicalBytesPerSectorForAtomicity; - ULONG PhysicalBytesPerSectorForPerformance; - ULONG FileSystemEffectivePhysicalBytesPerSectorForAtomicity; - ULONG Flags; - ULONG ByteOffsetForSectorAlignment; - ULONG ByteOffsetForPartitionAlignment; -} FILE_FS_SECTOR_SIZE_INFORMATION, *PFILE_FS_SECTOR_SIZE_INFORMATION; - -typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { - LARGE_INTEGER IdleTime; - LARGE_INTEGER KernelTime; - LARGE_INTEGER UserTime; - LARGE_INTEGER DpcTime; - LARGE_INTEGER InterruptTime; - ULONG InterruptCount; -} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; - -#ifndef SystemProcessorPerformanceInformation -# define SystemProcessorPerformanceInformation 8 -#endif - -#ifndef FILE_DEVICE_FILE_SYSTEM -# define FILE_DEVICE_FILE_SYSTEM 0x00000009 -#endif - -#ifndef FILE_DEVICE_NETWORK -# define FILE_DEVICE_NETWORK 0x00000012 -#endif - -#ifndef METHOD_BUFFERED -# define METHOD_BUFFERED 0 -#endif - -#ifndef METHOD_IN_DIRECT -# define METHOD_IN_DIRECT 1 -#endif - -#ifndef METHOD_OUT_DIRECT -# define METHOD_OUT_DIRECT 2 -#endif - -#ifndef METHOD_NEITHER -#define METHOD_NEITHER 3 -#endif - -#ifndef METHOD_DIRECT_TO_HARDWARE -# define METHOD_DIRECT_TO_HARDWARE METHOD_IN_DIRECT -#endif - -#ifndef METHOD_DIRECT_FROM_HARDWARE -# define METHOD_DIRECT_FROM_HARDWARE METHOD_OUT_DIRECT -#endif - -#ifndef FILE_ANY_ACCESS -# define FILE_ANY_ACCESS 0 -#endif - -#ifndef FILE_SPECIAL_ACCESS -# define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) -#endif - -#ifndef FILE_READ_ACCESS -# define FILE_READ_ACCESS 0x0001 -#endif - -#ifndef FILE_WRITE_ACCESS -# define FILE_WRITE_ACCESS 0x0002 -#endif - -#ifndef CTL_CODE -# define CTL_CODE(device_type, function, method, access) \ - (((device_type) << 16) | ((access) << 14) | ((function) << 2) | (method)) -#endif - -#ifndef FSCTL_SET_REPARSE_POINT -# define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ - 41, \ - METHOD_BUFFERED, \ - FILE_SPECIAL_ACCESS) -#endif - -#ifndef FSCTL_GET_REPARSE_POINT -# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ - 42, \ - METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#endif - -#ifndef FSCTL_DELETE_REPARSE_POINT -# define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ - 43, \ - METHOD_BUFFERED, \ - FILE_SPECIAL_ACCESS) -#endif - -#ifndef IO_REPARSE_TAG_SYMLINK -# define IO_REPARSE_TAG_SYMLINK (0xA000000CL) -#endif - -typedef VOID (NTAPI *PIO_APC_ROUTINE) - (PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - ULONG Reserved); - -typedef ULONG (NTAPI *sRtlNtStatusToDosError) - (NTSTATUS Status); - -typedef NTSTATUS (NTAPI *sNtDeviceIoControlFile) - (HANDLE FileHandle, - HANDLE Event, - PIO_APC_ROUTINE ApcRoutine, - PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - ULONG IoControlCode, - PVOID InputBuffer, - ULONG InputBufferLength, - PVOID OutputBuffer, - ULONG OutputBufferLength); - -typedef NTSTATUS (NTAPI *sNtQueryInformationFile) - (HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass); - -typedef NTSTATUS (NTAPI *sNtSetInformationFile) - (HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass); - -typedef NTSTATUS (NTAPI *sNtQueryVolumeInformationFile) - (HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FsInformation, - ULONG Length, - FS_INFORMATION_CLASS FsInformationClass); - -typedef NTSTATUS (NTAPI *sNtQuerySystemInformation) - (UINT SystemInformationClass, - PVOID SystemInformation, - ULONG SystemInformationLength, - PULONG ReturnLength); - - -/* - * Kernel32 headers - */ -#ifndef FILE_SKIP_COMPLETION_PORT_ON_SUCCESS -# define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1 -#endif - -#ifndef FILE_SKIP_SET_EVENT_ON_HANDLE -# define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2 -#endif - -#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY -# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1 -#endif - -#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) - typedef struct _OVERLAPPED_ENTRY { - ULONG_PTR lpCompletionKey; - LPOVERLAPPED lpOverlapped; - ULONG_PTR Internal; - DWORD dwNumberOfBytesTransferred; - } OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY; -#endif - -/* from wincon.h */ -#ifndef ENABLE_INSERT_MODE -# define ENABLE_INSERT_MODE 0x20 -#endif - -#ifndef ENABLE_QUICK_EDIT_MODE -# define ENABLE_QUICK_EDIT_MODE 0x40 -#endif - -#ifndef ENABLE_EXTENDED_FLAGS -# define ENABLE_EXTENDED_FLAGS 0x80 -#endif - -/* from winerror.h */ -#ifndef ERROR_SYMLINK_NOT_SUPPORTED -# define ERROR_SYMLINK_NOT_SUPPORTED 1464 -#endif - -typedef BOOL (WINAPI *sGetQueuedCompletionStatusEx) - (HANDLE CompletionPort, - LPOVERLAPPED_ENTRY lpCompletionPortEntries, - ULONG ulCount, - PULONG ulNumEntriesRemoved, - DWORD dwMilliseconds, - BOOL fAlertable); - -typedef BOOL (WINAPI* sSetFileCompletionNotificationModes) - (HANDLE FileHandle, - UCHAR Flags); - -typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW) - (LPCWSTR lpSymlinkFileName, - LPCWSTR lpTargetFileName, - DWORD dwFlags); - -typedef BOOL (WINAPI* sCancelIoEx) - (HANDLE hFile, - LPOVERLAPPED lpOverlapped); - -typedef VOID (WINAPI* sInitializeSRWLock) - (PSRWLOCK SRWLock); - -typedef VOID (WINAPI* sAcquireSRWLockShared) - (PSRWLOCK SRWLock); - -typedef VOID (WINAPI* sAcquireSRWLockExclusive) - (PSRWLOCK SRWLock); - -typedef BOOL (WINAPI* sTryAcquireSRWLockShared) - (PSRWLOCK SRWLock); - -typedef BOOL (WINAPI* sTryAcquireSRWLockExclusive) - (PSRWLOCK SRWLock); - -typedef VOID (WINAPI* sReleaseSRWLockShared) - (PSRWLOCK SRWLock); - -typedef VOID (WINAPI* sReleaseSRWLockExclusive) - (PSRWLOCK SRWLock); - -typedef VOID (WINAPI* sInitializeConditionVariable) - (PCONDITION_VARIABLE ConditionVariable); - -typedef BOOL (WINAPI* sSleepConditionVariableCS) - (PCONDITION_VARIABLE ConditionVariable, - PCRITICAL_SECTION CriticalSection, - DWORD dwMilliseconds); - -typedef BOOL (WINAPI* sSleepConditionVariableSRW) - (PCONDITION_VARIABLE ConditionVariable, - PSRWLOCK SRWLock, - DWORD dwMilliseconds, - ULONG Flags); - -typedef VOID (WINAPI* sWakeAllConditionVariable) - (PCONDITION_VARIABLE ConditionVariable); - -typedef VOID (WINAPI* sWakeConditionVariable) - (PCONDITION_VARIABLE ConditionVariable); - - -/* Ntdll function pointers */ -extern sRtlNtStatusToDosError pRtlNtStatusToDosError; -extern sNtDeviceIoControlFile pNtDeviceIoControlFile; -extern sNtQueryInformationFile pNtQueryInformationFile; -extern sNtSetInformationFile pNtSetInformationFile; -extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; -extern sNtQuerySystemInformation pNtQuerySystemInformation; - - -/* Kernel32 function pointers */ -extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; -extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes; -extern sCreateSymbolicLinkW pCreateSymbolicLinkW; -extern sCancelIoEx pCancelIoEx; -extern sInitializeSRWLock pInitializeSRWLock; -extern sAcquireSRWLockShared pAcquireSRWLockShared; -extern sAcquireSRWLockExclusive pAcquireSRWLockExclusive; -extern sTryAcquireSRWLockShared pTryAcquireSRWLockShared; -extern sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive; -extern sReleaseSRWLockShared pReleaseSRWLockShared; -extern sReleaseSRWLockExclusive pReleaseSRWLockExclusive; -extern sInitializeConditionVariable pInitializeConditionVariable; -extern sSleepConditionVariableCS pSleepConditionVariableCS; -extern sSleepConditionVariableSRW pSleepConditionVariableSRW; -extern sWakeAllConditionVariable pWakeAllConditionVariable; -extern sWakeConditionVariable pWakeConditionVariable; - -#endif /* UV_WIN_WINAPI_H_ */ diff --git a/third-party/libuv/src/win/winsock.c b/third-party/libuv/src/win/winsock.c deleted file mode 100644 index 938b6d031a..0000000000 --- a/third-party/libuv/src/win/winsock.c +++ /dev/null @@ -1,560 +0,0 @@ -/* 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 - * 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 <assert.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" - - -/* Whether there are any non-IFS LSPs stacked on TCP */ -int uv_tcp_non_ifs_lsp_ipv4; -int uv_tcp_non_ifs_lsp_ipv6; - -/* Ip address used to bind to any port at any interface */ -struct sockaddr_in uv_addr_ip4_any_; -struct sockaddr_in6 uv_addr_ip6_any_; - - -/* - * Retrieves the pointer to a winsock extension function. - */ -static BOOL uv_get_extension_function(SOCKET socket, GUID guid, - void **target) { - DWORD result, bytes; - - result = WSAIoctl(socket, - SIO_GET_EXTENSION_FUNCTION_POINTER, - &guid, - sizeof(guid), - (void*)target, - sizeof(*target), - &bytes, - NULL, - NULL); - - if (result == SOCKET_ERROR) { - *target = NULL; - return FALSE; - } else { - return TRUE; - } -} - - -BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target) { - const GUID wsaid_acceptex = WSAID_ACCEPTEX; - return uv_get_extension_function(socket, wsaid_acceptex, (void**)target); -} - - -BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) { - const GUID wsaid_connectex = WSAID_CONNECTEX; - return uv_get_extension_function(socket, wsaid_connectex, (void**)target); -} - - -static int error_means_no_support(DWORD error) { - return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT || - error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT; -} - - -void uv_winsock_init() { - WSADATA wsa_data; - int errorno; - SOCKET dummy; - WSAPROTOCOL_INFOW protocol_info; - int opt_len; - - /* Initialize winsock */ - errorno = WSAStartup(MAKEWORD(2, 2), &wsa_data); - if (errorno != 0) { - uv_fatal_error(errorno, "WSAStartup"); - } - - /* Set implicit binding address used by connectEx */ - if (uv_ip4_addr("0.0.0.0", 0, &uv_addr_ip4_any_)) { - abort(); - } - - if (uv_ip6_addr("::", 0, &uv_addr_ip6_any_)) { - abort(); - } - - /* Detect non-IFS LSPs */ - dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); - - if (dummy != INVALID_SOCKET) { - opt_len = (int) sizeof protocol_info; - if (getsockopt(dummy, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "getsockopt"); - - if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) - uv_tcp_non_ifs_lsp_ipv4 = 1; - - if (closesocket(dummy) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "closesocket"); - - } else if (!error_means_no_support(WSAGetLastError())) { - /* Any error other than "socket type not supported" is fatal. */ - uv_fatal_error(WSAGetLastError(), "socket"); - } - - /* Detect IPV6 support and non-IFS LSPs */ - dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); - - if (dummy != INVALID_SOCKET) { - opt_len = (int) sizeof protocol_info; - if (getsockopt(dummy, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "getsockopt"); - - if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) - uv_tcp_non_ifs_lsp_ipv6 = 1; - - if (closesocket(dummy) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "closesocket"); - - } else if (!error_means_no_support(WSAGetLastError())) { - /* Any error other than "socket type not supported" is fatal. */ - uv_fatal_error(WSAGetLastError(), "socket"); - } -} - - -int uv_ntstatus_to_winsock_error(NTSTATUS status) { - switch (status) { - case STATUS_SUCCESS: - return ERROR_SUCCESS; - - case STATUS_PENDING: - return ERROR_IO_PENDING; - - case STATUS_INVALID_HANDLE: - case STATUS_OBJECT_TYPE_MISMATCH: - return WSAENOTSOCK; - - case STATUS_INSUFFICIENT_RESOURCES: - case STATUS_PAGEFILE_QUOTA: - case STATUS_COMMITMENT_LIMIT: - case STATUS_WORKING_SET_QUOTA: - case STATUS_NO_MEMORY: - case STATUS_CONFLICTING_ADDRESSES: - case STATUS_QUOTA_EXCEEDED: - case STATUS_TOO_MANY_PAGING_FILES: - case STATUS_REMOTE_RESOURCES: - case STATUS_TOO_MANY_ADDRESSES: - return WSAENOBUFS; - - case STATUS_SHARING_VIOLATION: - case STATUS_ADDRESS_ALREADY_EXISTS: - return WSAEADDRINUSE; - - case STATUS_LINK_TIMEOUT: - case STATUS_IO_TIMEOUT: - case STATUS_TIMEOUT: - return WSAETIMEDOUT; - - case STATUS_GRACEFUL_DISCONNECT: - return WSAEDISCON; - - case STATUS_REMOTE_DISCONNECT: - case STATUS_CONNECTION_RESET: - case STATUS_LINK_FAILED: - case STATUS_CONNECTION_DISCONNECTED: - case STATUS_PORT_UNREACHABLE: - case STATUS_HOPLIMIT_EXCEEDED: - return WSAECONNRESET; - - case STATUS_LOCAL_DISCONNECT: - case STATUS_TRANSACTION_ABORTED: - case STATUS_CONNECTION_ABORTED: - return WSAECONNABORTED; - - case STATUS_BAD_NETWORK_PATH: - case STATUS_NETWORK_UNREACHABLE: - case STATUS_PROTOCOL_UNREACHABLE: - return WSAENETUNREACH; - - case STATUS_HOST_UNREACHABLE: - return WSAEHOSTUNREACH; - - case STATUS_CANCELLED: - case STATUS_REQUEST_ABORTED: - return WSAEINTR; - - case STATUS_BUFFER_OVERFLOW: - case STATUS_INVALID_BUFFER_SIZE: - return WSAEMSGSIZE; - - case STATUS_BUFFER_TOO_SMALL: - case STATUS_ACCESS_VIOLATION: - return WSAEFAULT; - - case STATUS_DEVICE_NOT_READY: - case STATUS_REQUEST_NOT_ACCEPTED: - return WSAEWOULDBLOCK; - - case STATUS_INVALID_NETWORK_RESPONSE: - case STATUS_NETWORK_BUSY: - case STATUS_NO_SUCH_DEVICE: - case STATUS_NO_SUCH_FILE: - case STATUS_OBJECT_PATH_NOT_FOUND: - case STATUS_OBJECT_NAME_NOT_FOUND: - case STATUS_UNEXPECTED_NETWORK_ERROR: - return WSAENETDOWN; - - case STATUS_INVALID_CONNECTION: - return WSAENOTCONN; - - case STATUS_REMOTE_NOT_LISTENING: - case STATUS_CONNECTION_REFUSED: - return WSAECONNREFUSED; - - case STATUS_PIPE_DISCONNECTED: - return WSAESHUTDOWN; - - case STATUS_INVALID_ADDRESS: - case STATUS_INVALID_ADDRESS_COMPONENT: - return WSAEADDRNOTAVAIL; - - case STATUS_NOT_SUPPORTED: - case STATUS_NOT_IMPLEMENTED: - return WSAEOPNOTSUPP; - - case STATUS_ACCESS_DENIED: - return WSAEACCES; - - default: - if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) && - (status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) { - /* It's a windows error that has been previously mapped to an */ - /* ntstatus code. */ - return (DWORD) (status & 0xffff); - } else { - /* The default fallback for unmappable ntstatus codes. */ - return WSAEINVAL; - } - } -} - - -/* - * This function provides a workaround for a bug in the winsock implementation - * of WSARecv. The problem is that when SetFileCompletionNotificationModes is - * used to avoid IOCP notifications of completed reads, WSARecv does not - * reliably indicate whether we can expect a completion package to be posted - * when the receive buffer is smaller than the received datagram. - * - * However it is desirable to use SetFileCompletionNotificationModes because - * it yields a massive performance increase. - * - * This function provides a workaround for that bug, but it only works for the - * specific case that we need it for. E.g. it assumes that the "avoid iocp" - * bit has been set, and supports only overlapped operation. It also requires - * the user to use the default msafd driver, doesn't work when other LSPs are - * stacked on top of it. - */ -int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) { - NTSTATUS status; - void* apc_context; - IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal; - AFD_RECV_INFO info; - DWORD error; - - if (overlapped == NULL || completion_routine != NULL) { - WSASetLastError(WSAEINVAL); - return SOCKET_ERROR; - } - - info.BufferArray = buffers; - info.BufferCount = buffer_count; - info.AfdFlags = AFD_OVERLAPPED; - info.TdiFlags = TDI_RECEIVE_NORMAL; - - if (*flags & MSG_PEEK) { - info.TdiFlags |= TDI_RECEIVE_PEEK; - } - - if (*flags & MSG_PARTIAL) { - info.TdiFlags |= TDI_RECEIVE_PARTIAL; - } - - if (!((intptr_t) overlapped->hEvent & 1)) { - apc_context = (void*) overlapped; - } else { - apc_context = NULL; - } - - iosb->Status = STATUS_PENDING; - iosb->Pointer = 0; - - status = pNtDeviceIoControlFile((HANDLE) socket, - overlapped->hEvent, - NULL, - apc_context, - iosb, - IOCTL_AFD_RECEIVE, - &info, - sizeof(info), - NULL, - 0); - - *flags = 0; - *bytes = (DWORD) iosb->Information; - - switch (status) { - case STATUS_SUCCESS: - error = ERROR_SUCCESS; - break; - - case STATUS_PENDING: - error = WSA_IO_PENDING; - break; - - case STATUS_BUFFER_OVERFLOW: - error = WSAEMSGSIZE; - break; - - case STATUS_RECEIVE_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL | MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL; - break; - - default: - error = uv_ntstatus_to_winsock_error(status); - break; - } - - WSASetLastError(error); - - if (error == ERROR_SUCCESS) { - return 0; - } else { - return SOCKET_ERROR; - } -} - - -/* See description of uv_wsarecv_workaround. */ -int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr, - int* addr_len, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) { - NTSTATUS status; - void* apc_context; - IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal; - AFD_RECV_DATAGRAM_INFO info; - DWORD error; - - if (overlapped == NULL || addr == NULL || addr_len == NULL || - completion_routine != NULL) { - WSASetLastError(WSAEINVAL); - return SOCKET_ERROR; - } - - info.BufferArray = buffers; - info.BufferCount = buffer_count; - info.AfdFlags = AFD_OVERLAPPED; - info.TdiFlags = TDI_RECEIVE_NORMAL; - info.Address = addr; - info.AddressLength = addr_len; - - if (*flags & MSG_PEEK) { - info.TdiFlags |= TDI_RECEIVE_PEEK; - } - - if (*flags & MSG_PARTIAL) { - info.TdiFlags |= TDI_RECEIVE_PARTIAL; - } - - if (!((intptr_t) overlapped->hEvent & 1)) { - apc_context = (void*) overlapped; - } else { - apc_context = NULL; - } - - iosb->Status = STATUS_PENDING; - iosb->Pointer = 0; - - status = pNtDeviceIoControlFile((HANDLE) socket, - overlapped->hEvent, - NULL, - apc_context, - iosb, - IOCTL_AFD_RECEIVE_DATAGRAM, - &info, - sizeof(info), - NULL, - 0); - - *flags = 0; - *bytes = (DWORD) iosb->Information; - - switch (status) { - case STATUS_SUCCESS: - error = ERROR_SUCCESS; - break; - - case STATUS_PENDING: - error = WSA_IO_PENDING; - break; - - case STATUS_BUFFER_OVERFLOW: - error = WSAEMSGSIZE; - break; - - case STATUS_RECEIVE_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL | MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL; - break; - - default: - error = uv_ntstatus_to_winsock_error(status); - break; - } - - WSASetLastError(error); - - if (error == ERROR_SUCCESS) { - return 0; - } else { - return SOCKET_ERROR; - } -} - - -int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info, - OVERLAPPED* overlapped) { - IO_STATUS_BLOCK iosb; - IO_STATUS_BLOCK* iosb_ptr; - HANDLE event = NULL; - void* apc_context; - NTSTATUS status; - DWORD error; - - if (overlapped != NULL) { - /* Overlapped operation. */ - iosb_ptr = (IO_STATUS_BLOCK*) &overlapped->Internal; - event = overlapped->hEvent; - - /* Do not report iocp completion if hEvent is tagged. */ - if ((uintptr_t) event & 1) { - event = (HANDLE)((uintptr_t) event & ~(uintptr_t) 1); - apc_context = NULL; - } else { - apc_context = overlapped; - } - - } else { - /* Blocking operation. */ - iosb_ptr = &iosb; - event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (event == NULL) { - return SOCKET_ERROR; - } - apc_context = NULL; - } - - iosb_ptr->Status = STATUS_PENDING; - status = pNtDeviceIoControlFile((HANDLE) socket, - event, - NULL, - apc_context, - iosb_ptr, - IOCTL_AFD_POLL, - info, - sizeof *info, - info, - sizeof *info); - - if (overlapped == NULL) { - /* If this is a blocking operation, wait for the event to become */ - /* signaled, and then grab the real status from the io status block. */ - if (status == STATUS_PENDING) { - DWORD r = WaitForSingleObject(event, INFINITE); - - if (r == WAIT_FAILED) { - DWORD saved_error = GetLastError(); - CloseHandle(event); - WSASetLastError(saved_error); - return SOCKET_ERROR; - } - - status = iosb.Status; - } - - CloseHandle(event); - } - - switch (status) { - case STATUS_SUCCESS: - error = ERROR_SUCCESS; - break; - - case STATUS_PENDING: - error = WSA_IO_PENDING; - break; - - default: - error = uv_ntstatus_to_winsock_error(status); - break; - } - - WSASetLastError(error); - - if (error == ERROR_SUCCESS) { - return 0; - } else { - return SOCKET_ERROR; - } -} diff --git a/third-party/libuv/src/win/winsock.h b/third-party/libuv/src/win/winsock.h deleted file mode 100644 index 957d08ec19..0000000000 --- a/third-party/libuv/src/win/winsock.h +++ /dev/null @@ -1,171 +0,0 @@ -/* 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 - * 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. - */ - -#ifndef UV_WIN_WINSOCK_H_ -#define UV_WIN_WINSOCK_H_ - -#include <winsock2.h> -#include <iptypes.h> -#include <mswsock.h> -#include <ws2tcpip.h> -#include <windows.h> - -#include "winapi.h" - - -/* - * MinGW is missing these too - */ -#ifndef SO_UPDATE_CONNECT_CONTEXT -# define SO_UPDATE_CONNECT_CONTEXT 0x7010 -#endif - -#ifndef TCP_KEEPALIVE -# define TCP_KEEPALIVE 3 -#endif - -#ifndef IPV6_V6ONLY -# define IPV6_V6ONLY 27 -#endif - -#ifndef IPV6_HOPLIMIT -# define IPV6_HOPLIMIT 21 -#endif - -#ifndef SIO_BASE_HANDLE -# define SIO_BASE_HANDLE 0x48000022 -#endif - -/* - * TDI defines that are only in the DDK. - * We only need receive flags so far. - */ -#ifndef TDI_RECEIVE_NORMAL - #define TDI_RECEIVE_BROADCAST 0x00000004 - #define TDI_RECEIVE_MULTICAST 0x00000008 - #define TDI_RECEIVE_PARTIAL 0x00000010 - #define TDI_RECEIVE_NORMAL 0x00000020 - #define TDI_RECEIVE_EXPEDITED 0x00000040 - #define TDI_RECEIVE_PEEK 0x00000080 - #define TDI_RECEIVE_NO_RESPONSE_EXP 0x00000100 - #define TDI_RECEIVE_COPY_LOOKAHEAD 0x00000200 - #define TDI_RECEIVE_ENTIRE_MESSAGE 0x00000400 - #define TDI_RECEIVE_AT_DISPATCH_LEVEL 0x00000800 - #define TDI_RECEIVE_CONTROL_INFO 0x00001000 - #define TDI_RECEIVE_FORCE_INDICATION 0x00002000 - #define TDI_RECEIVE_NO_PUSH 0x00004000 -#endif - -/* - * The "Auxiliary Function Driver" is the windows kernel-mode driver that does - * TCP, UDP etc. Winsock is just a layer that dispatches requests to it. - * Having these definitions allows us to bypass winsock and make an AFD kernel - * call directly, avoiding a bug in winsock's recvfrom implementation. - */ - -#define AFD_NO_FAST_IO 0x00000001 -#define AFD_OVERLAPPED 0x00000002 -#define AFD_IMMEDIATE 0x00000004 - -#define AFD_POLL_RECEIVE_BIT 0 -#define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT) -#define AFD_POLL_RECEIVE_EXPEDITED_BIT 1 -#define AFD_POLL_RECEIVE_EXPEDITED (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT) -#define AFD_POLL_SEND_BIT 2 -#define AFD_POLL_SEND (1 << AFD_POLL_SEND_BIT) -#define AFD_POLL_DISCONNECT_BIT 3 -#define AFD_POLL_DISCONNECT (1 << AFD_POLL_DISCONNECT_BIT) -#define AFD_POLL_ABORT_BIT 4 -#define AFD_POLL_ABORT (1 << AFD_POLL_ABORT_BIT) -#define AFD_POLL_LOCAL_CLOSE_BIT 5 -#define AFD_POLL_LOCAL_CLOSE (1 << AFD_POLL_LOCAL_CLOSE_BIT) -#define AFD_POLL_CONNECT_BIT 6 -#define AFD_POLL_CONNECT (1 << AFD_POLL_CONNECT_BIT) -#define AFD_POLL_ACCEPT_BIT 7 -#define AFD_POLL_ACCEPT (1 << AFD_POLL_ACCEPT_BIT) -#define AFD_POLL_CONNECT_FAIL_BIT 8 -#define AFD_POLL_CONNECT_FAIL (1 << AFD_POLL_CONNECT_FAIL_BIT) -#define AFD_POLL_QOS_BIT 9 -#define AFD_POLL_QOS (1 << AFD_POLL_QOS_BIT) -#define AFD_POLL_GROUP_QOS_BIT 10 -#define AFD_POLL_GROUP_QOS (1 << AFD_POLL_GROUP_QOS_BIT) - -#define AFD_NUM_POLL_EVENTS 11 -#define AFD_POLL_ALL ((1 << AFD_NUM_POLL_EVENTS) - 1) - -typedef struct _AFD_RECV_DATAGRAM_INFO { - LPWSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - ULONG TdiFlags; - struct sockaddr* Address; - int* AddressLength; -} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO; - -typedef struct _AFD_RECV_INFO { - LPWSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - ULONG TdiFlags; -} AFD_RECV_INFO, *PAFD_RECV_INFO; - - -#define _AFD_CONTROL_CODE(operation, method) \ - ((FSCTL_AFD_BASE) << 12 | (operation << 2) | method) - -#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK - -#define AFD_RECEIVE 5 -#define AFD_RECEIVE_DATAGRAM 6 -#define AFD_POLL 9 - -#define IOCTL_AFD_RECEIVE \ - _AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER) - -#define IOCTL_AFD_RECEIVE_DATAGRAM \ - _AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER) - -#define IOCTL_AFD_POLL \ - _AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED) - -#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) -typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP { - /* FIXME: __C89_NAMELESS was removed */ - /* __C89_NAMELESS */ union { - ULONGLONG Alignment; - /* __C89_NAMELESS */ struct { - ULONG Length; - DWORD Flags; - }; - }; - struct _IP_ADAPTER_UNICAST_ADDRESS_XP *Next; - SOCKET_ADDRESS Address; - IP_PREFIX_ORIGIN PrefixOrigin; - IP_SUFFIX_ORIGIN SuffixOrigin; - IP_DAD_STATE DadState; - ULONG ValidLifetime; - ULONG PreferredLifetime; - ULONG LeaseLifetime; -} IP_ADAPTER_UNICAST_ADDRESS_XP,*PIP_ADAPTER_UNICAST_ADDRESS_XP; - -#endif - -#endif /* UV_WIN_WINSOCK_H_ */ |