diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index a0e3dd46f092f4..bbb8f4d8cdcadb 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -197,3 +197,6 @@ Daryl Haresign Rui Abreu Ferreira João Reis farblue68 +Jason Williams +Igor Soarez +Miodrag Milanovic diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index e5c79808d2e1cc..5d3a4cad46b383 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,41 @@ +2015.06.06, Version 1.6.1 (Stable), 30c8be07bb78a66fdee5141626bf53a49a17094a + +Changes since version 1.6.0: + +* unix: handle invalid _SC_GETPW_R_SIZE_MAX values (cjihrig) + + +2015.06.04, Version 1.6.0 (Stable), adfccad76456061dfcf79b8df8e7dbfee51791d7 + +Changes since version 1.5.0: + +* aix: fix setsockopt for multicast options (Michael) + +* unix: don't block for io if any io handle is primed (Saúl Ibarra Corretgé) + +* windows: MSVC 2015 has snprintf() (Rui Abreu Ferreira) + +* windows: Add VS2015 support to vcbuild.bat (Jason Williams) + +* doc: fix typo in tcp.rst (Igor Soarez) + +* linux: work around epoll bug in kernels < 2.6.37 (Ben Noordhuis) + +* unix,win: add uv_os_homedir() (cjihrig) + +* stream: fix `select()` race condition (Fedor Indutny) + +* unix: prevent infinite loop in uv__run_pending (Saúl Ibarra Corretgé) + +* unix: make sure UDP send callbacks are asynchronous (Saúl Ibarra Corretgé) + +* test: fix `platform_output` netmask printing. (Andrew Paprocki) + +* aix: add ahafs autoconf detection and README notes (Andrew Paprocki) + +* core: add ability to customize memory allocator (Saúl Ibarra Corretgé) + + 2015.05.07, Version 1.5.0 (Stable), 4e77f74c7b95b639b3397095db1bc5bcc016c203 Changes since version 1.4.2: diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index b9fb80c6738b52..e9814d7b703e14 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -45,7 +45,7 @@ include_HEADERS += include/uv-win.h include/tree.h AM_CPPFLAGS += -I$(top_srcdir)/src/win \ -DWIN32_LEAN_AND_MEAN \ -D_WIN32_WINNT=0x0600 -LIBS += -lws2_32 -lpsapi -liphlpapi -lshell32 +LIBS += -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv libuv_la_SOURCES += src/win/async.c \ src/win/atomicops-inl.h \ src/win/core.c \ @@ -165,6 +165,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-getnameinfo.c \ test/test-getsockname.c \ test/test-handle-fileno.c \ + test/test-homedir.c \ test/test-hrtime.c \ test/test-idle.c \ test/test-ip4-addr.c \ @@ -185,6 +186,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-ping-pong.c \ test/test-pipe-bind-error.c \ test/test-pipe-connect-error.c \ + test/test-pipe-connect-prepare.c \ test/test-pipe-getsockname.c \ test/test-pipe-sendmsg.c \ test/test-pipe-server-close.c \ diff --git a/deps/uv/README.md b/deps/uv/README.md index a7da8b898c581d..f9a7a1e62e4d3f 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -185,6 +185,18 @@ OS X using the GCC or XCode toolchain. Solaris 121 and later using GCC toolchain. +AIX 6 and later using GCC toolchain (see notes). + +### AIX Notes + +AIX support for filesystem events requires the non-default IBM `bos.ahafs` +package to be installed. This package provides the AIX Event Infrastructure +that is detected by `autoconf`. +[IBM documentation](http://www.ibm.com/developerworks/aix/library/au-aix_event_infrastructure/) +describes the package in more detail. + +AIX support for filesystem events is not compiled when building with `gyp`. + ## Patches See the [guidelines for contributing][]. diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh index 9442c202eabe68..619cf6f8b672d8 100755 --- a/deps/uv/checksparse.sh +++ b/deps/uv/checksparse.sh @@ -103,6 +103,7 @@ test/test-get-loadavg.c test/test-get-memory.c test/test-getaddrinfo.c test/test-getsockname.c +test/test-homedir.c test/test-hrtime.c test/test-idle.c test/test-ip6-addr.c diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 71cb4704138c57..fe7228e2b726c2 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.5.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.6.1], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) @@ -58,6 +58,7 @@ AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false]) AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os],[openbsd*], [true], [false])]) AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os],[solaris*], [true], [false])]) AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false])]) +AC_CHECK_HEADERS([sys/ahafs_evProds.h]) AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes) AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" != "x"]) AS_IF([test "x$PKG_CONFIG" != "x"], [ diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index bb97a260057fc8..9708c5dea476cf 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -26,6 +26,26 @@ Data types .. note:: On Windows this field is ULONG. +.. c:type:: void* (*uv_malloc_func)(size_t size) + + Replacement function for :man:`malloc(3)`. + See :c:func:`uv_replace_allocator`. + +.. c:type:: void* (*uv_realloc_func)(void* ptr, size_t size) + + Replacement function for :man:`realloc(3)`. + See :c:func:`uv_replace_allocator`. + +.. c:type:: void* (*uv_calloc_func)(size_t count, size_t size) + + Replacement function for :man:`calloc(3)`. + See :c:func:`uv_replace_allocator`. + +.. c:type:: void (*uv_free_func)(void* ptr) + + Replacement function for :man:`free(3)`. + See :c:func:`uv_replace_allocator`. + .. c:type:: uv_file Cross platform representation of a file handle. @@ -126,6 +146,26 @@ API Returns the libuv version number as a string. For non-release versions "-pre" is appended, so the version number could be "1.2.3-pre". +.. c:function:: int uv_replace_allocator(uv_malloc_func malloc_func, uv_realloc_func realloc_func, uv_calloc_func calloc_func, uv_free_func free_func) + + .. versionadded:: 1.6.0 + + Override the use of the standard library's :man:`malloc(3)`, + :man:`calloc(3)`, :man:`realloc(3)`, :man:`free(3)`, memory allocation + functions. + + This function must be called before any other libuv function is called or + after all resources have been freed and thus libuv doesn't reference + any allocated memory chunk. + + On success, it returns 0, if any of the function pointers is NULL it + returns UV_EINVAL. + + .. warning:: There is no protection against changing the allocator multiple + times. If the user changes it they are responsible for making + sure the allocator is changed while no memory was allocated with + the previous allocator, or that they are compatible. + .. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len) Constructor for :c:type:`uv_buf_t`. @@ -227,6 +267,23 @@ API Changes the current working directory. +.. c:function:: int uv_os_homedir(char* buffer, size_t* size) + + Gets the current user's home directory. On Windows, `uv_os_homedir()` first + checks the `USERPROFILE` environment variable using + `GetEnvironmentVariableW()`. If `USERPROFILE` is not set, + `GetUserProfileDirectoryW()` is called. On all other operating systems, + `uv_os_homedir()` first checks the `HOME` environment variable using + :man:`getenv(3)`. If `HOME` is not set, :man:`getpwuid_r(3)` is called. The + user's home directory is stored in `buffer`. When `uv_os_homedir()` is + called, `size` indicates the maximum size of `buffer`. On success or + `UV_ENOBUFS` failure, `size` is set to the string length of `buffer`. + + .. warning:: + `uv_os_homedir()` is not thread safe. + + .. versionadded:: 1.6.0 + .. uint64_t uv_get_free_memory(void) .. c:function:: uint64_t uv_get_total_memory(void) diff --git a/deps/uv/docs/src/tcp.rst b/deps/uv/docs/src/tcp.rst index 2b5d268ddd86e6..dd746fe87fba76 100644 --- a/deps/uv/docs/src/tcp.rst +++ b/deps/uv/docs/src/tcp.rst @@ -72,7 +72,7 @@ API not guarantee that the call to :c:func:`uv_listen` or :c:func:`uv_tcp_connect` will succeed as well. - `flags` con contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support + `flags` can contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support is disabled and only IPv6 is used. .. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen) diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h index 0b4e6d781c35f6..3372212c8c7cee 100644 --- a/deps/uv/include/uv-version.h +++ b/deps/uv/include/uv-version.h @@ -31,8 +31,8 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 5 -#define UV_VERSION_PATCH 0 +#define UV_VERSION_MINOR 6 +#define UV_VERSION_PATCH 1 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 75b3a4a5d2f8bf..564af5fad600c6 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -244,6 +244,16 @@ typedef enum { UV_EXTERN unsigned int uv_version(void); UV_EXTERN const char* uv_version_string(void); +typedef void* (*uv_malloc_func)(size_t size); +typedef void* (*uv_realloc_func)(void* ptr, size_t size); +typedef void* (*uv_calloc_func)(size_t count, size_t size); +typedef void (*uv_free_func)(void* ptr); + +UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func, + uv_realloc_func realloc_func, + uv_calloc_func calloc_func, + uv_free_func free_func); + UV_EXTERN uv_loop_t* uv_default_loop(void); UV_EXTERN int uv_loop_init(uv_loop_t* loop); UV_EXTERN int uv_loop_close(uv_loop_t* loop); @@ -1028,6 +1038,8 @@ typedef struct { UV_EXTERN int uv_getrusage(uv_rusage_t* rusage); +UV_EXTERN int uv_os_homedir(char* buffer, size_t* size); + UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count); UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count); diff --git a/deps/uv/src/fs-poll.c b/deps/uv/src/fs-poll.c index 1145e5fc3443ce..44d47b88ed22e7 100644 --- a/deps/uv/src/fs-poll.c +++ b/deps/uv/src/fs-poll.c @@ -67,7 +67,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle, loop = handle->loop; len = strlen(path); - ctx = calloc(1, sizeof(*ctx) + len); + ctx = uv__calloc(1, sizeof(*ctx) + len); if (ctx == NULL) return UV_ENOMEM; @@ -96,7 +96,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle, return 0; error: - free(ctx); + uv__free(ctx); return err; } @@ -219,7 +219,7 @@ static void poll_cb(uv_fs_t* req) { static void timer_close_cb(uv_handle_t* handle) { - free(container_of(handle, struct poll_ctx, timer_handle)); + uv__free(container_of(handle, struct poll_ctx, timer_handle)); } diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c index 33890f02b5e834..debaf5ca965847 100644 --- a/deps/uv/src/threadpool.c +++ b/deps/uv/src/threadpool.c @@ -122,7 +122,7 @@ UV_DESTRUCTOR(static void cleanup(void)) { abort(); if (threads != default_threads) - free(threads); + uv__free(threads); uv_mutex_destroy(&mutex); uv_cond_destroy(&cond); @@ -149,7 +149,7 @@ static void init_once(void) { threads = default_threads; if (nthreads > ARRAY_SIZE(default_threads)) { - threads = malloc(nthreads * sizeof(threads[0])); + threads = uv__malloc(nthreads * sizeof(threads[0])); if (threads == NULL) { nthreads = ARRAY_SIZE(default_threads); threads = default_threads; diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c index e21a9cc78b6979..a2b0744a04729d 100644 --- a/deps/uv/src/unix/aix.c +++ b/deps/uv/src/unix/aix.c @@ -50,7 +50,9 @@ #include #include +#ifdef HAVE_SYS_AHAFS_EVPRODS_H #include +#endif #include #include @@ -501,6 +503,7 @@ void uv_loadavg(double avg[3]) { } +#ifdef HAVE_SYS_AHAFS_EVPRODS_H static char *uv__rawname(char *cp) { static char rawbuf[FILENAME_MAX+1]; char *dp = rindex(cp, '/'); @@ -550,7 +553,7 @@ static int uv__is_ahafs_mounted(void){ const char *dev = "/aha"; char *obj, *stub; - p = malloc(siz); + p = uv__malloc(siz); if (p == NULL) return -errno; @@ -561,8 +564,8 @@ static int uv__is_ahafs_mounted(void){ if (rv == 0) { /* buffer was not large enough, reallocate to correct size */ siz = *(int*)p; - free(p); - p = malloc(siz); + uv__free(p); + p = uv__malloc(siz); if (p == NULL) return -errno; rv = mntctl(MCTL_QUERY, siz, (char*)p); @@ -576,7 +579,7 @@ static int uv__is_ahafs_mounted(void){ stub = vmt2dataptr(vmt, VMT_STUB); /* mount point */ if (EQ(obj, dev) || EQ(uv__rawname(obj), dev) || EQ(stub, dev)) { - free(p); /* Found a match */ + uv__free(p); /* Found a match */ return 0; } vmt = (struct vmount *) ((char *) vmt + vmt->vmt_length); @@ -781,7 +784,7 @@ static int uv__parse_data(char *buf, int *events, uv_fs_event_t* handle) { /* Scan out the name of the file that triggered the event*/ if (sscanf(p, "BEGIN_EVPROD_INFO\n%sEND_EVPROD_INFO", filename) == 1) { - handle->dir_filename = strdup((const char*)&filename); + handle->dir_filename = uv__strdup((const char*)&filename); } else return -1; } @@ -859,11 +862,16 @@ static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int else /* Call the actual JavaScript callback function */ handle->cb(handle, (const char*)&fname, events, 0); } +#endif int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { +#ifdef HAVE_SYS_AHAFS_EVPRODS_H uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); return 0; +#else + return -ENOSYS; +#endif } @@ -871,6 +879,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* filename, unsigned int flags) { +#ifdef HAVE_SYS_AHAFS_EVPRODS_H int fd, rc, i = 0, res = 0; char cwd[PATH_MAX]; char absolute_path[PATH_MAX]; @@ -931,17 +940,20 @@ int uv_fs_event_start(uv_fs_event_t* handle, /* Setup/Initialize all the libuv routines */ uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__ahafs_event, fd); - handle->path = strdup((const char*)&absolute_path); + handle->path = uv__strdup((const char*)&absolute_path); handle->cb = cb; uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN); return 0; +#else + return -ENOSYS; +#endif } int uv_fs_event_stop(uv_fs_event_t* handle) { - +#ifdef HAVE_SYS_AHAFS_EVPRODS_H if (!uv__is_active(handle)) return 0; @@ -949,21 +961,28 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { uv__handle_stop(handle); if (uv__path_is_a_directory(handle->path) == 0) { - free(handle->dir_filename); + uv__free(handle->dir_filename); handle->dir_filename = NULL; } - free(handle->path); + uv__free(handle->path); handle->path = NULL; uv__close(handle->event_watcher.fd); handle->event_watcher.fd = -1; return 0; +#else + return -ENOSYS; +#endif } void uv__fs_event_close(uv_fs_event_t* handle) { +#ifdef HAVE_SYS_AHAFS_EVPRODS_H uv_fs_event_stop(handle); +#else + UNREACHABLE(); +#endif } @@ -1052,7 +1071,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { return -ENOSYS; } - ps_cpus = (perfstat_cpu_t*) malloc(ncpus * sizeof(perfstat_cpu_t)); + ps_cpus = (perfstat_cpu_t*) uv__malloc(ncpus * sizeof(perfstat_cpu_t)); if (!ps_cpus) { return -ENOMEM; } @@ -1060,13 +1079,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { strcpy(cpu_id.name, FIRST_CPU); result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus); if (result == -1) { - free(ps_cpus); + uv__free(ps_cpus); return -ENOSYS; } - *cpu_infos = (uv_cpu_info_t*) malloc(ncpus * sizeof(uv_cpu_info_t)); + *cpu_infos = (uv_cpu_info_t*) uv__malloc(ncpus * sizeof(uv_cpu_info_t)); if (!*cpu_infos) { - free(ps_cpus); + uv__free(ps_cpus); return -ENOMEM; } @@ -1075,7 +1094,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { cpu_info = *cpu_infos; while (idx < ncpus) { cpu_info->speed = (int)(ps_total.processorHZ / 1000000); - cpu_info->model = strdup(ps_total.description); + cpu_info->model = uv__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; @@ -1085,7 +1104,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { idx++; } - free(ps_cpus); + uv__free(ps_cpus); return 0; } @@ -1094,10 +1113,10 @@ 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); + uv__free(cpu_infos[i].model); } - free(cpu_infos); + uv__free(cpu_infos); } @@ -1119,7 +1138,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, return -errno; } - ifc.ifc_req = (struct ifreq*)malloc(size); + ifc.ifc_req = (struct ifreq*)uv__malloc(size); ifc.ifc_len = size; if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { SAVE_ERRNO(uv__close(sockfd)); @@ -1153,7 +1172,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* Alloc the return interface structs */ *addresses = (uv_interface_address_t*) - malloc(*count * sizeof(uv_interface_address_t)); + uv__malloc(*count * sizeof(uv_interface_address_t)); if (!(*addresses)) { uv__close(sockfd); return -ENOMEM; @@ -1181,7 +1200,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* All conditions above must match count loop */ - address->name = strdup(p->ifr_name); + address->name = uv__strdup(p->ifr_name); if (p->ifr_addr.sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); @@ -1208,10 +1227,10 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int i; for (i = 0; i < count; ++i) { - free(addresses[i].name); + uv__free(addresses[i].name); } - free(addresses); + uv__free(addresses); } void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { diff --git a/deps/uv/src/unix/android-ifaddrs.c b/deps/uv/src/unix/android-ifaddrs.c index a99b0191d54808..71f7290b3263e0 100644 --- a/deps/uv/src/unix/android-ifaddrs.c +++ b/deps/uv/src/unix/android-ifaddrs.c @@ -137,8 +137,8 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don { int l_read; - free(l_buffer); - l_buffer = malloc(l_size); + uv__free(l_buffer); + l_buffer = uv__malloc(l_size); if (l_buffer == NULL) { return NULL; @@ -148,7 +148,7 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don *p_size = l_read; if(l_read == -2) { - free(l_buffer); + uv__free(l_buffer); return NULL; } if(l_read >= 0) @@ -170,7 +170,7 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don if(l_hdr->nlmsg_type == NLMSG_ERROR) { - free(l_buffer); + uv__free(l_buffer); return NULL; } } @@ -183,7 +183,7 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size) { - NetlinkList *l_item = malloc(sizeof(NetlinkList)); + NetlinkList *l_item = uv__malloc(sizeof(NetlinkList)); if (l_item == NULL) { return NULL; @@ -202,8 +202,8 @@ static void freeResultList(NetlinkList *p_list) { l_cur = p_list; p_list = p_list->m_next; - free(l_cur->m_data); - free(l_cur); + uv__free(l_cur->m_data); + uv__free(l_cur); } } @@ -349,7 +349,7 @@ static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList) } } - l_entry = malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize); + l_entry = uv__malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize); if (l_entry == NULL) { return -1; @@ -478,7 +478,7 @@ static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, } } - l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize); + l_entry = uv__malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize); if (l_entry == NULL) { return -1; @@ -698,6 +698,6 @@ void freeifaddrs(struct ifaddrs *ifa) { l_cur = ifa; ifa = ifa->ifa_next; - free(l_cur); + uv__free(l_cur); } } diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 6f284ffa7aea31..826b4113b2a1f4 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -38,6 +38,7 @@ #include /* INT_MAX, PATH_MAX */ #include /* writev */ #include /* getrusage */ +#include #ifdef __linux__ # include @@ -282,6 +283,9 @@ int uv_backend_timeout(const uv_loop_t* loop) { if (!QUEUE_EMPTY(&loop->idle_handles)) return 0; + if (!QUEUE_EMPTY(&loop->pending_queue)) + return 0; + if (loop->closing_handles) return 0; @@ -696,16 +700,20 @@ int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) { static int uv__run_pending(uv_loop_t* loop) { QUEUE* q; + QUEUE pq; uv__io_t* w; if (QUEUE_EMPTY(&loop->pending_queue)) return 0; - while (!QUEUE_EMPTY(&loop->pending_queue)) { - q = QUEUE_HEAD(&loop->pending_queue); + QUEUE_INIT(&pq); + q = QUEUE_HEAD(&loop->pending_queue); + QUEUE_SPLIT(&loop->pending_queue, q, &pq); + + while (!QUEUE_EMPTY(&pq)) { + q = QUEUE_HEAD(&pq); QUEUE_REMOVE(q); QUEUE_INIT(q); - w = QUEUE_DATA(q, uv__io_t, pending_queue); w->cb(loop, w, UV__POLLOUT); } @@ -745,8 +753,8 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) { } nwatchers = next_power_of_two(len + 2) - 2; - watchers = realloc(loop->watchers, - (nwatchers + 2) * sizeof(loop->watchers[0])); + watchers = uv__realloc(loop->watchers, + (nwatchers + 2) * sizeof(loop->watchers[0])); if (watchers == NULL) abort(); @@ -983,3 +991,85 @@ int uv__dup2_cloexec(int oldfd, int newfd) { return r; } } + + +int uv_os_homedir(char* buffer, size_t* size) { + struct passwd pw; + struct passwd* result; + char* buf; + uid_t uid; + size_t bufsize; + size_t len; + long initsize; + int r; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + /* Check if the HOME environment variable is set first */ + buf = getenv("HOME"); + + if (buf != NULL) { + len = strlen(buf); + + if (len >= *size) { + *size = len; + return -ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + + return 0; + } + + /* HOME is not set, so call getpwuid() */ + initsize = sysconf(_SC_GETPW_R_SIZE_MAX); + + if (initsize <= 0) + bufsize = 4096; + else + bufsize = (size_t) initsize; + + uid = getuid(); + buf = NULL; + + for (;;) { + uv__free(buf); + buf = uv__malloc(bufsize); + + if (buf == NULL) + return -ENOMEM; + + r = getpwuid_r(uid, &pw, buf, bufsize, &result); + + if (r != ERANGE) + break; + + bufsize *= 2; + } + + if (r != 0) { + uv__free(buf); + return -r; + } + + if (result == NULL) { + uv__free(buf); + return -ENOENT; + } + + len = strlen(pw.pw_dir); + + if (len >= *size) { + *size = len; + uv__free(buf); + return -ENOBUFS; + } + + memcpy(buffer, pw.pw_dir, len + 1); + *size = len; + uv__free(buf); + + return 0; +} diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c index d276adac2e7fa4..718a81e4c1f998 100644 --- a/deps/uv/src/unix/darwin.c +++ b/deps/uv/src/unix/darwin.c @@ -198,7 +198,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { return -EINVAL; /* FIXME(bnoordhuis) Translate error. */ } - *cpu_infos = malloc(numcpus * sizeof(**cpu_infos)); + *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); if (!(*cpu_infos)) return -ENOMEM; /* FIXME(bnoordhuis) Deallocate info? */ @@ -213,7 +213,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { 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->model = uv__strdup(model); cpu_info->speed = cpuspeed/1000000; } vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); @@ -226,10 +226,10 @@ 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); + uv__free(cpu_infos[i].model); } - free(cpu_infos); + uv__free(cpu_infos); } @@ -255,7 +255,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { (*count)++; } - *addresses = malloc(*count * sizeof(**addresses)); + *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) return -ENOMEM; @@ -275,7 +275,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { if (ent->ifa_addr->sa_family == AF_LINK) continue; - address->name = strdup(ent->ifa_name); + address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); @@ -324,8 +324,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int i; for (i = 0; i < count; i++) { - free(addresses[i].name); + uv__free(addresses[i].name); } - free(addresses); + uv__free(addresses); } diff --git a/deps/uv/src/unix/dl.c b/deps/uv/src/unix/dl.c index ad45fc832d4dff..7c6d41c969b25f 100644 --- a/deps/uv/src/unix/dl.c +++ b/deps/uv/src/unix/dl.c @@ -40,7 +40,7 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) { void uv_dlclose(uv_lib_t* lib) { if (lib->errmsg) { - free(lib->errmsg); + uv__free(lib->errmsg); lib->errmsg = NULL; } @@ -68,12 +68,12 @@ static int uv__dlerror(uv_lib_t* lib) { const char* errmsg; if (lib->errmsg) - free(lib->errmsg); + uv__free(lib->errmsg); errmsg = dlerror(); if (errmsg) { - lib->errmsg = strdup(errmsg); + lib->errmsg = uv__strdup(errmsg); return -1; } else { diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index 2dbb1ec169a64e..44976f7fe2a3a4 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -151,7 +151,7 @@ void uv_loadavg(double avg[3]) { char** uv_setup_args(int argc, char** argv) { - process_title = argc ? strdup(argv[0]) : NULL; + process_title = argc ? uv__strdup(argv[0]) : NULL; return argv; } @@ -159,8 +159,8 @@ char** uv_setup_args(int argc, char** argv) { int uv_set_process_title(const char* title) { int oid[4]; - if (process_title) free(process_title); - process_title = strdup(title); + if (process_title) uv__free(process_title); + process_title = uv__strdup(title); oid[0] = CTL_KERN; oid[1] = KERN_PROC; @@ -271,7 +271,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) return -errno; - *cpu_infos = malloc(numcpus * sizeof(**cpu_infos)); + *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); if (!(*cpu_infos)) return -ENOMEM; @@ -279,7 +279,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { size = sizeof(cpuspeed); if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) { - SAVE_ERRNO(free(*cpu_infos)); + SAVE_ERRNO(uv__free(*cpu_infos)); return -errno; } @@ -288,21 +288,21 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { */ size = sizeof(maxcpus); if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) { - SAVE_ERRNO(free(*cpu_infos)); + SAVE_ERRNO(uv__free(*cpu_infos)); return -errno; } size = maxcpus * CPUSTATES * sizeof(long); - cp_times = malloc(size); + cp_times = uv__malloc(size); if (cp_times == NULL) { - free(*cpu_infos); + uv__free(*cpu_infos); return -ENOMEM; } if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) { - SAVE_ERRNO(free(cp_times)); - SAVE_ERRNO(free(*cpu_infos)); + SAVE_ERRNO(uv__free(cp_times)); + SAVE_ERRNO(uv__free(*cpu_infos)); return -errno; } @@ -315,13 +315,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { 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->model = uv__strdup(model); cpu_info->speed = cpuspeed; cur+=CPUSTATES; } - free(cp_times); + uv__free(cp_times); return 0; } @@ -330,10 +330,10 @@ 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); + uv__free(cpu_infos[i].model); } - free(cpu_infos); + uv__free(cpu_infos); } @@ -359,7 +359,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { (*count)++; } - *addresses = malloc(*count * sizeof(**addresses)); + *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) return -ENOMEM; @@ -379,7 +379,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { if (ent->ifa_addr->sa_family == AF_LINK) continue; - address->name = strdup(ent->ifa_name); + address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); @@ -428,8 +428,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int i; for (i = 0; i < count; i++) { - free(addresses[i].name); + uv__free(addresses[i].name); } - free(addresses); + uv__free(addresses); } diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index 7792801e9b6fd6..9dab202dd76f8e 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -73,7 +73,7 @@ #define PATH \ do { \ - (req)->path = strdup(path); \ + (req)->path = uv__strdup(path); \ if ((req)->path == NULL) \ return -ENOMEM; \ } \ @@ -85,7 +85,7 @@ 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); \ + (req)->path = uv__malloc(path_len + new_path_len); \ if ((req)->path == NULL) \ return -ENOMEM; \ (req)->new_path = (req)->path + path_len; \ @@ -310,7 +310,7 @@ static ssize_t uv__fs_read(uv_fs_t* req) { done: if (req->bufs != req->bufsml) - free(req->bufs); + uv__free(req->bufs); return result; } @@ -350,8 +350,8 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) { int i; for (i = 0; i < n; i++) - free(dents[i]); - free(dents); + uv__free(dents[i]); + uv__free(dents); } errno = saved_errno; @@ -375,7 +375,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { #endif } - buf = malloc(len + 1); + buf = uv__malloc(len + 1); if (buf == NULL) { errno = ENOMEM; @@ -385,7 +385,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { len = readlink(req->path, buf, len); if (len == -1) { - free(buf); + uv__free(buf); return -1; } @@ -671,7 +671,7 @@ static ssize_t uv__fs_write(uv_fs_t* req) { #endif if (req->bufs != req->bufsml) - free(req->bufs); + uv__free(req->bufs); return r; } @@ -1008,7 +1008,7 @@ int uv_fs_mkdtemp(uv_loop_t* loop, const char* tpl, uv_fs_cb cb) { INIT(MKDTEMP); - req->path = strdup(tpl); + req->path = uv__strdup(tpl); if (req->path == NULL) return -ENOMEM; POST; @@ -1041,7 +1041,7 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, req->nbufs = nbufs; req->bufs = req->bufsml; if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = malloc(nbufs * sizeof(*bufs)); + req->bufs = uv__malloc(nbufs * sizeof(*bufs)); if (req->bufs == NULL) return -ENOMEM; @@ -1163,7 +1163,7 @@ int uv_fs_write(uv_loop_t* loop, req->nbufs = nbufs; req->bufs = req->bufsml; if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = malloc(nbufs * sizeof(*bufs)); + req->bufs = uv__malloc(nbufs * sizeof(*bufs)); if (req->bufs == NULL) return -ENOMEM; @@ -1176,7 +1176,7 @@ int uv_fs_write(uv_loop_t* loop, void uv_fs_req_cleanup(uv_fs_t* req) { - free((void*) req->path); + uv__free((void*)req->path); req->path = NULL; req->new_path = NULL; @@ -1184,6 +1184,6 @@ void uv_fs_req_cleanup(uv_fs_t* req) { uv__fs_scandir_cleanup(req); if (req->ptr != &req->statbuf) - free(req->ptr); + uv__free(req->ptr); req->ptr = NULL; } diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c index 49085306b90f83..8143f7c1f018db 100644 --- a/deps/uv/src/unix/fsevents.c +++ b/deps/uv/src/unix/fsevents.c @@ -169,7 +169,7 @@ static void (*pFSEventStreamStop)(FSEventStreamRef); if (!uv__is_closing((handle)) && uv__is_active((handle))) \ block \ /* Free allocated data */ \ - free(event); \ + uv__free(event); \ } \ if (err != 0 && !uv__is_closing((handle)) && uv__is_active((handle))) \ (handle)->cb((handle), NULL, 0, err); \ @@ -280,7 +280,7 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef, len = 0; #endif /* MAC_OS_X_VERSION_10_7 */ - event = malloc(sizeof(*event) + len); + event = uv__malloc(sizeof(*event) + len); if (event == NULL) break; @@ -425,7 +425,7 @@ static void uv__fsevents_reschedule(uv_fs_event_t* handle) { uv_mutex_lock(&state->fsevent_mutex); path_count = state->fsevent_handle_count; if (path_count != 0) { - paths = malloc(sizeof(*paths) * path_count); + paths = uv__malloc(sizeof(*paths) * path_count); if (paths == NULL) { uv_mutex_unlock(&state->fsevent_mutex); goto final; @@ -465,7 +465,7 @@ static void uv__fsevents_reschedule(uv_fs_event_t* handle) { if (cf_paths == NULL) { while (i != 0) pCFRelease(paths[--i]); - free(paths); + uv__free(paths); } else { /* CFArray takes ownership of both strings and original C-array */ pCFRelease(cf_paths); @@ -584,7 +584,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) { if (err) return err; - state = calloc(1, sizeof(*state)); + state = uv__calloc(1, sizeof(*state)); if (state == NULL) return -ENOMEM; @@ -662,7 +662,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) { uv_mutex_destroy(&loop->cf_mutex); fail_mutex_init: - free(state); + uv__free(state); return err; } @@ -688,7 +688,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) { q = QUEUE_HEAD(&loop->cf_signals); s = QUEUE_DATA(q, uv__cf_loop_signal_t, member); QUEUE_REMOVE(q); - free(s); + uv__free(s); } /* Destroy state */ @@ -696,7 +696,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) { uv_sem_destroy(&state->fsevent_sem); uv_mutex_destroy(&state->fsevent_mutex); pCFRelease(state->signal_source); - free(state); + uv__free(state); loop->cf_state = NULL; } @@ -756,7 +756,7 @@ static void uv__cf_loop_cb(void* arg) { uv__fsevents_reschedule(s->handle); QUEUE_REMOVE(item); - free(s); + uv__free(s); } } @@ -766,7 +766,7 @@ 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)); + item = uv__malloc(sizeof(*item)); if (item == NULL) return -ENOMEM; @@ -808,7 +808,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) { * 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)); + handle->cf_cb = uv__malloc(sizeof(*handle->cf_cb)); if (handle->cf_cb == NULL) { err = -ENOMEM; goto fail_cf_cb_malloc; @@ -843,11 +843,11 @@ int uv__fsevents_init(uv_fs_event_t* handle) { uv_mutex_destroy(&handle->cf_mutex); fail_cf_mutex_init: - free(handle->cf_cb); + uv__free(handle->cf_cb); handle->cf_cb = NULL; fail_cf_cb_malloc: - free(handle->realpath); + uv__free(handle->realpath); handle->realpath = NULL; handle->realpath_len = 0; @@ -880,7 +880,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) { /* Wait for deinitialization */ uv_sem_wait(&state->fsevent_sem); - uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free); + uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) uv__free); handle->cf_cb = NULL; /* Free data in queue */ @@ -889,7 +889,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) { }); uv_mutex_destroy(&handle->cf_mutex); - free(handle->realpath); + uv__free(handle->realpath); handle->realpath = NULL; handle->realpath_len = 0; diff --git a/deps/uv/src/unix/getaddrinfo.c b/deps/uv/src/unix/getaddrinfo.c index 0d684e24e1a55f..2049aea2f38fd8 100644 --- a/deps/uv/src/unix/getaddrinfo.c +++ b/deps/uv/src/unix/getaddrinfo.c @@ -112,11 +112,11 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { /* See initialization in uv_getaddrinfo(). */ if (req->hints) - free(req->hints); + uv__free(req->hints); else if (req->service) - free(req->service); + uv__free(req->service); else if (req->hostname) - free(req->hostname); + uv__free(req->hostname); else assert(0); @@ -152,7 +152,7 @@ int uv_getaddrinfo(uv_loop_t* loop, 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); + buf = uv__malloc(hostname_len + service_len + hints_len); if (buf == NULL) return -ENOMEM; diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 31db5e29ea68b8..c31e54992d3e4f 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -143,7 +143,8 @@ enum { UV_TCP_NODELAY = 0x400, /* Disable Nagle. */ UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */ UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */ - UV_HANDLE_IPV6 = 0x10000 /* Handle is bound to a IPv6 socket. */ + UV_HANDLE_IPV6 = 0x10000, /* Handle is bound to a IPv6 socket. */ + UV_UDP_PROCESSING = 0x20000 /* Handle is running the send callback queue. */ }; /* loop flags */ diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index aaadcd8419a3f3..424236a6ef5937 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -363,7 +363,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__fs_event, fd); - handle->path = strdup(path); + handle->path = uv__strdup(path); handle->cb = cb; #if defined(__APPLE__) @@ -403,7 +403,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { uv__io_close(handle->loop, &handle->event_watcher); } - free(handle->path); + uv__free(handle->path); handle->path = NULL; uv__close(handle->event_watcher.fd); diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index d07494dd654bb3..e6e68283d58d07 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -141,17 +141,26 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { void uv__io_poll(uv_loop_t* loop, int timeout) { + /* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes + * effectively infinite on 32 bits architectures. To avoid blocking + * indefinitely, we cap the timeout and poll again if necessary. + * + * Note that "30 minutes" is a simplification because it depends on + * the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200, + * that being the largest value I have seen in the wild (and only once.) + */ + static const int max_safe_timeout = 1789569; static int no_epoll_pwait; static int no_epoll_wait; struct uv__epoll_event events[1024]; struct uv__epoll_event* pe; struct uv__epoll_event e; + int real_timeout; QUEUE* q; uv__io_t* w; sigset_t sigset; uint64_t sigmask; uint64_t base; - uint64_t diff; int nevents; int count; int nfds; @@ -209,8 +218,15 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { assert(timeout >= -1); base = loop->time; count = 48; /* Benchmarks suggest this gives the best throughput. */ + real_timeout = timeout; for (;;) { + /* See the comment for max_safe_timeout for an explanation of why + * this is necessary. Executive summary: kernel bug workaround. + */ + if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) + timeout = max_safe_timeout; + if (sigmask != 0 && no_epoll_pwait != 0) if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) abort(); @@ -244,6 +260,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (nfds == 0) { assert(timeout != -1); + + timeout = real_timeout - timeout; + if (timeout > 0) + continue; + return; } @@ -346,11 +367,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { update_timeout: assert(timeout > 0); - diff = loop->time - base; - if (diff >= (uint64_t) timeout) + real_timeout -= (loop->time - base); + if (real_timeout <= 0) return; - timeout -= diff; + timeout = real_timeout; } } @@ -523,7 +544,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { assert(numcpus != (unsigned int) -1); assert(numcpus != 0); - ci = calloc(numcpus, sizeof(*ci)); + ci = uv__calloc(numcpus, sizeof(*ci)); if (ci == NULL) return -ENOMEM; @@ -595,7 +616,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { 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. */ + model = uv__strndup(model, strlen(model) - 1); /* Strip newline. */ if (model == NULL) { fclose(fp); return -ENOMEM; @@ -614,7 +635,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { #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. */ + model = uv__strndup(model, strlen(model) - 1); /* Strip newline. */ if (model == NULL) { fclose(fp); return -ENOMEM; @@ -645,7 +666,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { inferred_model = ci[model_idx - 1].model; while (model_idx < numcpus) { - model = strndup(inferred_model, strlen(inferred_model)); + model = uv__strndup(inferred_model, strlen(inferred_model)); if (model == NULL) return -ENOMEM; ci[model_idx++].model = model; @@ -755,10 +776,10 @@ 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); + uv__free(cpu_infos[i].model); } - free(cpu_infos); + uv__free(cpu_infos); } @@ -792,7 +813,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, if (*count == 0) return 0; - *addresses = malloc(*count * sizeof(**addresses)); + *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) return -ENOMEM; @@ -812,7 +833,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, if (ent->ifa_addr->sa_family == PF_PACKET) continue; - address->name = strdup(ent->ifa_name); + address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); @@ -862,10 +883,10 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int i; for (i = 0; i < count; i++) { - free(addresses[i].name); + uv__free(addresses[i].name); } - free(addresses); + uv__free(addresses); } diff --git a/deps/uv/src/unix/linux-inotify.c b/deps/uv/src/unix/linux-inotify.c index 2ecc5ebfb6c61d..d9ed9f4b24512b 100644 --- a/deps/uv/src/unix/linux-inotify.c +++ b/deps/uv/src/unix/linux-inotify.c @@ -207,7 +207,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, if (w) goto no_insert; - w = malloc(sizeof(*w) + strlen(path) + 1); + w = uv__malloc(sizeof(*w) + strlen(path) + 1); if (w == NULL) return -ENOMEM; @@ -245,7 +245,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { /* 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); + uv__free(w); } return 0; diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c index 7e167d049e4f70..aa9146bf9aa9df 100644 --- a/deps/uv/src/unix/loop.c +++ b/deps/uv/src/unix/loop.c @@ -117,7 +117,7 @@ void uv__loop_close(uv_loop_t* loop) { assert(loop->nfds == 0); #endif - free(loop->watchers); + uv__free(loop->watchers); loop->watchers = NULL; loop->nwatchers = 0; } diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c index 9eb0679de98f27..29f2a4dec63831 100644 --- a/deps/uv/src/unix/netbsd.c +++ b/deps/uv/src/unix/netbsd.c @@ -131,15 +131,15 @@ uint64_t uv_get_total_memory(void) { char** uv_setup_args(int argc, char** argv) { - process_title = argc ? strdup(argv[0]) : NULL; + process_title = argc ? uv__strdup(argv[0]) : NULL; return argv; } int uv_set_process_title(const char* title) { - if (process_title) free(process_title); + if (process_title) uv__free(process_title); - process_title = strdup(title); + process_title = uv__strdup(title); setproctitle("%s", title); return 0; @@ -234,17 +234,17 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { cpuspeed = 0; size = numcpus * CPUSTATES * sizeof(*cp_times); - cp_times = malloc(size); + cp_times = uv__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)); + *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); if (!(*cpu_infos)) { - free(cp_times); - free(*cpu_infos); + uv__free(cp_times); + uv__free(*cpu_infos); return -ENOMEM; } @@ -255,11 +255,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { 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->model = uv__strdup(model); cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6); cur += CPUSTATES; } - free(cp_times); + uv__free(cp_times); return 0; } @@ -268,10 +268,10 @@ 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); + uv__free(cpu_infos[i].model); } - free(cpu_infos); + uv__free(cpu_infos); } @@ -296,7 +296,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { (*count)++; } - *addresses = malloc(*count * sizeof(**addresses)); + *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) return -ENOMEM; @@ -313,7 +313,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { if (ent->ifa_addr->sa_family != PF_INET) continue; - address->name = strdup(ent->ifa_name); + address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); @@ -361,8 +361,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { int i; for (i = 0; i < count; i++) { - free(addresses[i].name); + uv__free(addresses[i].name); } - free(addresses); + uv__free(addresses); } diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c index 859bc0ccb18748..c8d54599386efe 100644 --- a/deps/uv/src/unix/openbsd.c +++ b/deps/uv/src/unix/openbsd.c @@ -91,7 +91,7 @@ int uv_exepath(char* buffer, size_t* size) { mypid = getpid(); for (;;) { err = -ENOMEM; - argsbuf_tmp = realloc(argsbuf, argsbuf_size); + argsbuf_tmp = uv__realloc(argsbuf, argsbuf_size); if (argsbuf_tmp == NULL) goto out; argsbuf = argsbuf_tmp; @@ -124,7 +124,7 @@ int uv_exepath(char* buffer, size_t* size) { err = 0; out: - free(argsbuf); + uv__free(argsbuf); return err; } @@ -155,14 +155,14 @@ uint64_t uv_get_total_memory(void) { char** uv_setup_args(int argc, char** argv) { - process_title = argc ? strdup(argv[0]) : NULL; + process_title = argc ? uv__strdup(argv[0]) : NULL; return argv; } int uv_set_process_title(const char* title) { - if (process_title) free(process_title); - process_title = strdup(title); + if (process_title) uv__free(process_title); + process_title = uv__strdup(title); setproctitle(title); return 0; } @@ -238,7 +238,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { if (sysctl(which, 2, &numcpus, &size, NULL, 0)) return -errno; - *cpu_infos = malloc(numcpus * sizeof(**cpu_infos)); + *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); if (!(*cpu_infos)) return -ENOMEM; @@ -247,7 +247,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { which[1] = HW_CPUSPEED; size = sizeof(cpuspeed); if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) { - SAVE_ERRNO(free(*cpu_infos)); + SAVE_ERRNO(uv__free(*cpu_infos)); return -errno; } @@ -258,7 +258,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { which[2] = i; size = sizeof(info); if (sysctl(which, 3, &info, &size, NULL, 0)) { - SAVE_ERRNO(free(*cpu_infos)); + SAVE_ERRNO(uv__free(*cpu_infos)); return -errno; } @@ -270,7 +270,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { 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->model = uv__strdup(model); cpu_info->speed = cpuspeed; } @@ -282,10 +282,10 @@ 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); + uv__free(cpu_infos[i].model); } - free(cpu_infos); + uv__free(cpu_infos); } @@ -311,7 +311,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, (*count)++; } - *addresses = malloc(*count * sizeof(**addresses)); + *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) return -ENOMEM; @@ -328,7 +328,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, if (ent->ifa_addr->sa_family != PF_INET) continue; - address->name = strdup(ent->ifa_name); + address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); @@ -377,8 +377,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int i; for (i = 0; i < count; i++) { - free(addresses[i].name); + uv__free(addresses[i].name); } - free(addresses); + uv__free(addresses); } diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c index bc8b856337bb76..7f87a713bf40fe 100644 --- a/deps/uv/src/unix/pipe.c +++ b/deps/uv/src/unix/pipe.c @@ -54,7 +54,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { return -EINVAL; /* Make a copy of the file name, it outlives this function's scope. */ - pipe_fname = strdup(name); + pipe_fname = uv__strdup(name); if (pipe_fname == NULL) return -ENOMEM; @@ -88,7 +88,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { uv__close(sockfd); err_socket: - free((void*)pipe_fname); + uv__free((void*)pipe_fname); return err; } @@ -116,7 +116,7 @@ void uv__pipe_close(uv_pipe_t* handle) { * another thread or process. */ unlink(handle->pipe_fname); - free((void*)handle->pipe_fname); + uv__free((void*)handle->pipe_fname); handle->pipe_fname = NULL; } diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 380f3db1dce7f4..f2a83753ee3a88 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -404,7 +404,7 @@ int uv_spawn(uv_loop_t* loop, stdio_count = 3; err = -ENOMEM; - pipes = malloc(stdio_count * sizeof(*pipes)); + pipes = uv__malloc(stdio_count * sizeof(*pipes)); if (pipes == NULL) goto error; @@ -509,7 +509,7 @@ int uv_spawn(uv_loop_t* loop, process->pid = pid; process->exit_cb = options->exit_cb; - free(pipes); + uv__free(pipes); return exec_errorno; error: @@ -523,7 +523,7 @@ int uv_spawn(uv_loop_t* loop, if (pipes[i][1] != -1) close(pipes[i][1]); } - free(pipes); + uv__free(pipes); } return err; diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c index 16b052373194f9..19214e5ec9743d 100644 --- a/deps/uv/src/unix/proctitle.c +++ b/deps/uv/src/unix/proctitle.c @@ -55,7 +55,7 @@ char** uv_setup_args(int argc, char** argv) { /* Add space for the argv pointers. */ size += (argc + 1) * sizeof(char*); - new_argv = malloc(size); + new_argv = uv__malloc(size); if (new_argv == NULL) return argv; args_mem = new_argv; @@ -97,6 +97,6 @@ int uv_get_process_title(char* buffer, size_t size) { UV_DESTRUCTOR(static void free_args_mem(void)) { - free(args_mem); /* Keep valgrind happy. */ + uv__free(args_mem); /* Keep valgrind happy. */ args_mem = NULL; } diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 48827b65d36dee..7ad1658cf8d65e 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -231,7 +231,6 @@ static void uv__stream_osx_select_cb(uv_async_t* handle) { /* 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))); @@ -242,6 +241,14 @@ static void uv__stream_osx_select_cb(uv_async_t* handle) { if ((events & UV__POLLOUT) && uv__io_active(&stream->io_watcher, UV__POLLOUT)) uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLOUT); + + if (stream->flags & UV_CLOSING) + return; + + /* NOTE: It is important to do it here, otherwise `select()` might be called + * before the actual `uv__read()`, leading to the blocking syscall + */ + uv_sem_post(&s->async_sem); } @@ -249,7 +256,7 @@ 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); + uv__free(s); } @@ -309,7 +316,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) { sread_sz = ROUND_UP(max_fd + 1, sizeof(uint32_t) * NBBY) / NBBY; swrite_sz = sread_sz; - s = malloc(sizeof(*s) + sread_sz + swrite_sz); + s = uv__malloc(sizeof(*s) + sread_sz + swrite_sz); if (s == NULL) { err = -ENOMEM; goto failed_malloc; @@ -368,7 +375,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) { return err; failed_async_init: - free(s); + uv__free(s); failed_malloc: uv__close(fds[0]); @@ -605,7 +612,7 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) { /* All read, free */ assert(queued_fds->offset > 0); if (--queued_fds->offset == 0) { - free(queued_fds); + uv__free(queued_fds); server->queued_fds = NULL; } else { /* Shift rest */ @@ -703,7 +710,7 @@ static void uv__write_req_finish(uv_write_t* req) { */ if (req->error == 0) { if (req->bufs != req->bufsml) - free(req->bufs); + uv__free(req->bufs); req->bufs = NULL; } @@ -914,7 +921,7 @@ static void uv__write_callbacks(uv_stream_t* stream) { if (req->bufs != NULL) { stream->write_queue_size -= uv__write_req_size(req); if (req->bufs != req->bufsml) - free(req->bufs); + uv__free(req->bufs); req->bufs = NULL; } @@ -979,8 +986,8 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) { queued_fds = stream->queued_fds; if (queued_fds == NULL) { queue_size = 8; - queued_fds = malloc((queue_size - 1) * sizeof(*queued_fds->fds) + - sizeof(*queued_fds)); + queued_fds = uv__malloc((queue_size - 1) * sizeof(*queued_fds->fds) + + sizeof(*queued_fds)); if (queued_fds == NULL) return -ENOMEM; queued_fds->size = queue_size; @@ -990,9 +997,9 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) { /* Grow */ } else if (queued_fds->size == queued_fds->offset) { queue_size = queued_fds->size + 8; - queued_fds = realloc(queued_fds, - (queue_size - 1) * sizeof(*queued_fds->fds) + - sizeof(*queued_fds)); + queued_fds = uv__realloc(queued_fds, + (queue_size - 1) * sizeof(*queued_fds->fds) + + sizeof(*queued_fds)); /* * Allocation failure, report back. @@ -1357,7 +1364,7 @@ int uv_write2(uv_write_t* req, req->bufs = req->bufsml; if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = malloc(nbufs * sizeof(bufs[0])); + req->bufs = uv__malloc(nbufs * sizeof(bufs[0])); if (req->bufs == NULL) return -ENOMEM; @@ -1445,7 +1452,7 @@ int uv_try_write(uv_stream_t* stream, QUEUE_REMOVE(&req.queue); uv__req_unregister(stream->loop, &req); if (req.bufs != req.bufsml) - free(req.bufs); + uv__free(req.bufs); req.bufs = NULL; /* Do not poll for writable, if we wasn't before calling this */ @@ -1582,7 +1589,7 @@ void uv__stream_close(uv_stream_t* handle) { queued_fds = handle->queued_fds; for (i = 0; i < queued_fds->offset; i++) uv__close(queued_fds->fds[i]); - free(handle->queued_fds); + uv__free(handle->queued_fds); handle->queued_fds = NULL; } diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c index c41d0f0e52bd2b..05b7a114031178 100644 --- a/deps/uv/src/unix/sunos.c +++ b/deps/uv/src/unix/sunos.c @@ -433,7 +433,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, } uv__handle_start(handle); - handle->path = strdup(path); + handle->path = uv__strdup(path); handle->fd = PORT_UNUSED; handle->cb = cb; @@ -463,7 +463,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { } handle->fd = PORT_DELETED; - free(handle->path); + uv__free(handle->path); handle->path = NULL; handle->fo.fo_name = NULL; uv__handle_stop(handle); @@ -582,7 +582,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { lookup_instance++; } - *cpu_infos = malloc(lookup_instance * sizeof(**cpu_infos)); + *cpu_infos = uv__malloc(lookup_instance * sizeof(**cpu_infos)); if (!(*cpu_infos)) { kstat_close(kc); return -ENOMEM; @@ -605,7 +605,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { knp = kstat_data_lookup(ksp, (char*) "brand"); assert(knp->data_type == KSTAT_DATA_STRING); - cpu_info->model = strdup(KSTAT_NAMED_STR_PTR(knp)); + cpu_info->model = uv__strdup(KSTAT_NAMED_STR_PTR(knp)); } lookup_instance++; @@ -659,10 +659,10 @@ 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); + uv__free(cpu_infos[i].model); } - free(cpu_infos); + uv__free(cpu_infos); } @@ -692,7 +692,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { (*count)++; } - *addresses = malloc(*count * sizeof(**addresses)); + *addresses = uv__malloc(*count * sizeof(**addresses)); if (!(*addresses)) return -ENOMEM; @@ -705,7 +705,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { if (ent->ifa_addr == NULL) continue; - address->name = strdup(ent->ifa_name); + address->name = uv__strdup(ent->ifa_name); if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); @@ -756,8 +756,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int i; for (i = 0; i < count; i++) { - free(addresses[i].name); + uv__free(addresses[i].name); } - free(addresses); + uv__free(addresses); } diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c index ea8563fecf95b6..6080cf5f73cb4b 100644 --- a/deps/uv/src/unix/thread.c +++ b/deps/uv/src/unix/thread.c @@ -45,7 +45,7 @@ static void* uv__thread_start(void *arg) ctx_p = arg; ctx = *ctx_p; - free(ctx_p); + uv__free(ctx_p); ctx.entry(ctx.arg); return 0; @@ -56,7 +56,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { struct thread_ctx* ctx; int err; - ctx = malloc(sizeof(*ctx)); + ctx = uv__malloc(sizeof(*ctx)); if (ctx == NULL) return UV_ENOMEM; @@ -66,7 +66,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { err = pthread_create(tid, NULL, uv__thread_start, ctx); if (err) - free(ctx); + uv__free(ctx); return -err; } diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 22c2e1388e14ac..f85ab1473a944f 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -89,6 +89,9 @@ static void uv__udp_run_completed(uv_udp_t* handle) { uv_udp_send_t* req; QUEUE* q; + assert(!(handle->flags & UV_UDP_PROCESSING)); + handle->flags |= UV_UDP_PROCESSING; + while (!QUEUE_EMPTY(&handle->write_completed_queue)) { q = QUEUE_HEAD(&handle->write_completed_queue); QUEUE_REMOVE(q); @@ -100,7 +103,7 @@ static void uv__udp_run_completed(uv_udp_t* handle) { handle->send_queue_count--; if (req->bufs != req->bufsml) - free(req->bufs); + uv__free(req->bufs); req->bufs = NULL; if (req->send_cb == NULL) @@ -121,6 +124,8 @@ static void uv__udp_run_completed(uv_udp_t* handle) { if (!uv__io_active(&handle->io_watcher, UV__POLLIN)) uv__handle_stop(handle); } + + handle->flags &= ~UV_UDP_PROCESSING; } @@ -399,7 +404,7 @@ int uv__udp_send(uv_udp_send_t* req, req->bufs = req->bufsml; if (nbufs > ARRAY_SIZE(req->bufsml)) - req->bufs = malloc(nbufs * sizeof(bufs[0])); + req->bufs = uv__malloc(nbufs * sizeof(bufs[0])); if (req->bufs == NULL) return -ENOMEM; @@ -410,10 +415,11 @@ int uv__udp_send(uv_udp_send_t* req, QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue); uv__handle_start(handle); - if (empty_queue) + if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) { uv__udp_sendmsg(handle); - else + } else { uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT); + } return 0; } @@ -666,13 +672,13 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { * so hardcode the size of these options on this platform, * and use the general uv__setsockopt_maybe_char call on other platforms. */ -#if defined(__sun) +#if defined(__sun) || defined(_AIX) return uv__setsockopt(handle, IP_TTL, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)); -#endif /* defined(__sun) */ +#endif /* defined(__sun) || defined(_AIX) */ return uv__setsockopt_maybe_char(handle, IP_TTL, @@ -688,14 +694,14 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { * IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case, * and use the general uv__setsockopt_maybe_char call otherwise. */ -#if defined(__sun) +#if defined(__sun) || defined(_AIX) if (handle->flags & UV_HANDLE_IPV6) return uv__setsockopt(handle, IP_MULTICAST_TTL, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)); -#endif /* defined(__sun) */ +#endif /* defined(__sun) || defined(_AIX) */ return uv__setsockopt_maybe_char(handle, IP_MULTICAST_TTL, @@ -711,14 +717,14 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) { * IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case, * and use the general uv__setsockopt_maybe_char call otherwise. */ -#if defined(__sun) +#if defined(__sun) || defined(_AIX) if (handle->flags & UV_HANDLE_IPV6) return uv__setsockopt(handle, IP_MULTICAST_LOOP, IPV6_MULTICAST_LOOP, &on, sizeof(on)); -#endif /* defined(__sun) */ +#endif /* defined(__sun) || defined(_AIX) */ return uv__setsockopt_maybe_char(handle, IP_MULTICAST_LOOP, diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c index 02341f8b95d9c0..77879b9a6c1686 100644 --- a/deps/uv/src/uv-common.c +++ b/deps/uv/src/uv-common.c @@ -33,6 +33,74 @@ # include /* if_nametoindex */ #endif + +typedef struct { + uv_malloc_func local_malloc; + uv_realloc_func local_realloc; + uv_calloc_func local_calloc; + uv_free_func local_free; +} uv__allocator_t; + +static uv__allocator_t uv__allocator = { + malloc, + realloc, + calloc, + free, +}; + +char* uv__strdup(const char* s) { + size_t len = strlen(s) + 1; + char* m = uv__malloc(len); + if (m == NULL) + return NULL; + return memcpy(m, s, len); +} + +char* uv__strndup(const char* s, size_t n) { + char* m; + size_t len = strlen(s); + if (n < len) + len = n; + m = uv__malloc(len + 1); + if (m == NULL) + return NULL; + m[len] = '\0'; + return memcpy(m, s, len); +} + +void* uv__malloc(size_t size) { + return uv__allocator.local_malloc(size); +} + +void uv__free(void* ptr) { + uv__allocator.local_free(ptr); +} + +void* uv__calloc(size_t count, size_t size) { + return uv__allocator.local_calloc(count, size); +} + +void* uv__realloc(void* ptr, size_t size) { + return uv__allocator.local_realloc(ptr, size); +} + +int uv_replace_allocator(uv_malloc_func malloc_func, + uv_realloc_func realloc_func, + uv_calloc_func calloc_func, + uv_free_func free_func) { + if (malloc_func == NULL || realloc_func == NULL || + calloc_func == NULL || free_func == NULL) { + return UV_EINVAL; + } + + uv__allocator.local_malloc = malloc_func; + uv__allocator.local_realloc = realloc_func; + uv__allocator.local_calloc = calloc_func; + uv__allocator.local_free = free_func; + + return 0; +} + #define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t); size_t uv_handle_size(uv_handle_type type) { @@ -400,7 +468,7 @@ void uv__fs_scandir_cleanup(uv_fs_t* req) { if (*nbufs > 0 && *nbufs != (unsigned int) req->result) (*nbufs)--; for (; *nbufs < (unsigned int) req->result; (*nbufs)++) - free(dents[*nbufs]); + uv__free(dents[*nbufs]); } @@ -414,11 +482,11 @@ int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) { /* Free previous entity */ if (*nbufs > 0) - free(dents[*nbufs - 1]); + uv__free(dents[*nbufs - 1]); /* End was already reached */ if (*nbufs == (unsigned int) req->result) { - free(dents); + uv__free(dents); req->ptr = NULL; return UV_EOF; } @@ -492,12 +560,12 @@ uv_loop_t* uv_default_loop(void) { uv_loop_t* uv_loop_new(void) { uv_loop_t* loop; - loop = malloc(sizeof(*loop)); + loop = uv__malloc(sizeof(*loop)); if (loop == NULL) return NULL; if (uv_loop_init(loop)) { - free(loop); + uv__free(loop); return NULL; } @@ -540,5 +608,5 @@ void uv_loop_delete(uv_loop_t* loop) { (void) err; /* Squelch compiler warnings. */ assert(err == 0); if (loop != default_loop) - free(loop); + uv__free(loop); } diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index 463cabac29d5ac..8258d7a1387d26 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -211,4 +211,13 @@ void uv__fs_scandir_cleanup(uv_fs_t* req); } \ while (0) + +/* Allocator prototypes */ +void *uv__calloc(size_t count, size_t size); +char *uv__strdup(const char* s); +char *uv__strndup(const char* s, size_t n); +void* uv__malloc(size_t size); +void uv__free(void* ptr); +void* uv__realloc(void* ptr, size_t size); + #endif /* UV_COMMON_H_ */ diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c index 640651b6c9634b..eb205d3921d797 100644 --- a/deps/uv/src/win/fs-event.c +++ b/deps/uv/src/win/fs-event.c @@ -72,13 +72,13 @@ static int uv_split_path(const WCHAR* filename, WCHAR** dir, if (i == 0) { if (dir) { - *dir = (WCHAR*)malloc((MAX_PATH + 1) * sizeof(WCHAR)); + *dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR)); if (!*dir) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } if (!GetCurrentDirectoryW(MAX_PATH, *dir)) { - free(*dir); + uv__free(*dir); *dir = NULL; return -1; } @@ -87,17 +87,17 @@ static int uv_split_path(const WCHAR* filename, WCHAR** dir, *file = wcsdup(filename); } else { if (dir) { - *dir = (WCHAR*)malloc((i + 1) * sizeof(WCHAR)); + *dir = (WCHAR*)uv__malloc((i + 1) * sizeof(WCHAR)); if (!*dir) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } wcsncpy(*dir, filename, i); (*dir)[i] = L'\0'; } - *file = (WCHAR*)malloc((len - i) * sizeof(WCHAR)); + *file = (WCHAR*)uv__malloc((len - i) * sizeof(WCHAR)); if (!*file) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } wcsncpy(*file, filename + i + 1, len - i - 1); (*file)[len - i - 1] = L'\0'; @@ -137,18 +137,18 @@ int uv_fs_event_start(uv_fs_event_t* handle, return UV_EINVAL; handle->cb = cb; - handle->path = strdup(path); + handle->path = uv__strdup(path); if (!handle->path) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } uv__handle_start(handle); /* Convert name to UTF16. */ name_size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(WCHAR); - pathw = (WCHAR*)malloc(name_size); + pathw = (WCHAR*)uv__malloc(name_size); if (!pathw) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } if (!uv_utf8_to_utf16(path, pathw, @@ -192,7 +192,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, } dir_to_watch = dir; - free(pathw); + uv__free(pathw); pathw = NULL; } @@ -207,7 +207,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, NULL); if (dir) { - free(dir); + uv__free(dir); dir = NULL; } @@ -225,11 +225,10 @@ int uv_fs_event_start(uv_fs_event_t* handle, } if (!handle->buffer) { - handle->buffer = (char*)_aligned_malloc(uv_directory_watcher_buffer_size, - sizeof(DWORD)); + handle->buffer = (char*)uv__malloc(uv_directory_watcher_buffer_size); } if (!handle->buffer) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } memset(&(handle->req.u.io.overlapped), 0, @@ -259,21 +258,21 @@ int uv_fs_event_start(uv_fs_event_t* handle, error: if (handle->path) { - free(handle->path); + uv__free(handle->path); handle->path = NULL; } if (handle->filew) { - free(handle->filew); + uv__free(handle->filew); handle->filew = NULL; } if (handle->short_filew) { - free(handle->short_filew); + uv__free(handle->short_filew); handle->short_filew = NULL; } - free(pathw); + uv__free(pathw); if (handle->dir_handle != INVALID_HANDLE_VALUE) { CloseHandle(handle->dir_handle); @@ -281,7 +280,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, } if (handle->buffer) { - _aligned_free(handle->buffer); + uv__free(handle->buffer); handle->buffer = NULL; } @@ -301,22 +300,22 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { uv__handle_stop(handle); if (handle->filew) { - free(handle->filew); + uv__free(handle->filew); handle->filew = NULL; } if (handle->short_filew) { - free(handle->short_filew); + uv__free(handle->short_filew); handle->short_filew = NULL; } if (handle->path) { - free(handle->path); + uv__free(handle->path); handle->path = NULL; } if (handle->dirw) { - free(handle->dirw); + uv__free(handle->dirw); handle->dirw = NULL; } @@ -378,9 +377,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, size = wcslen(handle->dirw) + file_info->FileNameLength / sizeof(WCHAR) + 2; - filenamew = (WCHAR*)malloc(size * sizeof(WCHAR)); + filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); if (!filenamew) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw, @@ -393,26 +392,26 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, size = GetLongPathNameW(filenamew, NULL, 0); if (size) { - long_filenamew = (WCHAR*)malloc(size * sizeof(WCHAR)); + long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); if (!long_filenamew) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } size = GetLongPathNameW(filenamew, long_filenamew, size); if (size) { long_filenamew[size] = '\0'; } else { - free(long_filenamew); + uv__free(long_filenamew); long_filenamew = NULL; } } - free(filenamew); + uv__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); + uv__free(long_filenamew); if (result == 0) { long_filenamew = filenamew; @@ -447,9 +446,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, NULL, 0); if (size) { - filename = (char*)malloc(size + 1); + filename = (char*)uv__malloc(size + 1); if (!filename) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } size = uv_utf16_to_utf8(filenamew, @@ -459,7 +458,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, if (size) { filename[size] = '\0'; } else { - free(filename); + uv__free(filename); filename = NULL; } } @@ -478,9 +477,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, break; } - free(filename); + uv__free(filename); filename = NULL; - free(long_filenamew); + uv__free(long_filenamew); long_filenamew = NULL; } @@ -519,7 +518,7 @@ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) { assert(!(handle->flags & UV_HANDLE_CLOSED)); if (handle->buffer) { - _aligned_free(handle->buffer); + uv__free(handle->buffer); handle->buffer = NULL; } diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index af7ec74276f995..00d0197a541483 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -166,7 +166,7 @@ INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req, return 0; } - buf = (char*) malloc(buf_sz); + buf = (char*) uv__malloc(buf_sz); if (buf == NULL) { return ERROR_OUTOFMEMORY; } @@ -352,7 +352,7 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr, /* If requested, allocate memory and convert to UTF8. */ if (target_ptr != NULL) { int r; - target = (char*) malloc(target_len + 1); + target = (char*) uv__malloc(target_len + 1); if (target == NULL) { SetLastError(ERROR_OUTOFMEMORY); return -1; @@ -896,7 +896,7 @@ void fs__scandir(uv_fs_t* req) { size_t new_dirents_size = dirents_size == 0 ? dirents_initial_size : dirents_size << 1; uv__dirent_t** new_dirents = - realloc(dirents, new_dirents_size * sizeof *dirents); + uv__realloc(dirents, new_dirents_size * sizeof *dirents); if (new_dirents == NULL) goto out_of_memory_error; @@ -909,7 +909,7 @@ void fs__scandir(uv_fs_t* req) { * includes room for the first character of the filename, but `utf8_len` * doesn't count the NULL terminator at this point. */ - dirent = malloc(sizeof *dirent + utf8_len); + dirent = uv__malloc(sizeof *dirent + utf8_len); if (dirent == NULL) goto out_of_memory_error; @@ -998,9 +998,9 @@ void fs__scandir(uv_fs_t* req) { if (dir_handle != INVALID_HANDLE_VALUE) CloseHandle(dir_handle); while (dirents_used > 0) - free(dirents[--dirents_used]); + uv__free(dirents[--dirents_used]); if (dirents != NULL) - free(dirents); + uv__free(dirents); } @@ -1281,9 +1281,9 @@ static void fs__sendfile(uv_fs_t* req) { 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); + char* buf = (char*) uv__malloc(buf_size); if (!buf) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } if (offset != -1) { @@ -1314,7 +1314,7 @@ static void fs__sendfile(uv_fs_t* req) { } } - free(buf); + uv__free(buf); SET_REQ_RESULT(req, result); } @@ -1504,9 +1504,9 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path, 2 * (target_len + 2) * sizeof(WCHAR); /* Allocate the buffer */ - buffer = (REPARSE_DATA_BUFFER*)malloc(needed_buf_size); + buffer = (REPARSE_DATA_BUFFER*)uv__malloc(needed_buf_size); if (!buffer) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } /* Grab a pointer to the part of the buffer where filenames go */ @@ -1620,13 +1620,13 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path, /* Clean up */ CloseHandle(handle); - free(buffer); + uv__free(buffer); SET_REQ_RESULT(req, 0); return; error: - free(buffer); + uv__free(buffer); if (handle != INVALID_HANDLE_VALUE) { CloseHandle(handle); @@ -1764,10 +1764,10 @@ void uv_fs_req_cleanup(uv_fs_t* req) { return; if (req->flags & UV_FS_FREE_PATHS) - free(req->file.pathw); + uv__free(req->file.pathw); if (req->flags & UV_FS_FREE_PTR) - free(req->ptr); + uv__free(req->ptr); req->path = NULL; req->file.pathw = NULL; @@ -1830,7 +1830,7 @@ int uv_fs_read(uv_loop_t* loop, req->fs.info.nbufs = nbufs; req->fs.info.bufs = req->fs.info.bufsml; if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) - req->fs.info.bufs = malloc(nbufs * sizeof(*bufs)); + req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs)); if (req->fs.info.bufs == NULL) return UV_ENOMEM; @@ -1863,7 +1863,7 @@ int uv_fs_write(uv_loop_t* loop, req->fs.info.nbufs = nbufs; req->fs.info.bufs = req->fs.info.bufsml; if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) - req->fs.info.bufs = malloc(nbufs * sizeof(*bufs)); + req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs)); if (req->fs.info.bufs == NULL) return UV_ENOMEM; diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c index f3802cd5829208..3d23660e884c5d 100644 --- a/deps/uv/src/win/getaddrinfo.c +++ b/deps/uv/src/win/getaddrinfo.c @@ -110,7 +110,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { /* release input parameter memory */ if (req->alloc != NULL) { - free(req->alloc); + uv__free(req->alloc); req->alloc = NULL; } @@ -139,7 +139,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { } /* allocate memory for addrinfo results */ - alloc_ptr = (char*)malloc(addrinfo_len); + alloc_ptr = (char*)uv__malloc(addrinfo_len); /* do conversions */ if (alloc_ptr != NULL) { @@ -220,7 +220,7 @@ void uv_freeaddrinfo(struct addrinfo* ai) { /* release copied result memory */ if (alloc_ptr != NULL) { - free(alloc_ptr); + uv__free(alloc_ptr); } } @@ -285,7 +285,7 @@ int uv_getaddrinfo(uv_loop_t* loop, } /* allocate memory for inputs, and partition it as needed */ - alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize); + alloc_ptr = (char*)uv__malloc(nodesize + servicesize + hintssize); if (!alloc_ptr) { err = WSAENOBUFS; goto error; @@ -355,7 +355,7 @@ int uv_getaddrinfo(uv_loop_t* loop, error: if (req != NULL && req->alloc != NULL) { - free(req->alloc); + uv__free(req->alloc); } return uv_translate_sys_error(err); } diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 5a0e5420847b12..d232efae3aab5c 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -423,7 +423,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { &item->socket_info_ex.socket_info, 0, WSA_FLAG_OVERLAPPED); - free(item); + uv__free(item); if (socket != INVALID_SOCKET) closesocket(socket); @@ -444,7 +444,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { if (handle->flags & UV_HANDLE_PIPESERVER) { assert(handle->pipe.serv.accept_reqs); - free(handle->pipe.serv.accept_reqs); + uv__free(handle->pipe.serv.accept_reqs); handle->pipe.serv.accept_reqs = NULL; } @@ -478,9 +478,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { } handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*) - malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances); + uv__malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances); if (!handle->pipe.serv.accept_reqs) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } for (i = 0; i < handle->pipe.serv.pending_instances; i++) { @@ -494,9 +494,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { /* Convert name to UTF16. */ nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR); - handle->name = (WCHAR*)malloc(nameSize); + handle->name = (WCHAR*)uv__malloc(nameSize); if (!handle->name) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) { @@ -540,7 +540,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { error: if (handle->name) { - free(handle->name); + uv__free(handle->name); handle->name = NULL; } @@ -607,9 +607,9 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, /* Convert name to UTF16. */ nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR); - handle->name = (WCHAR*)malloc(nameSize); + handle->name = (WCHAR*)uv__malloc(nameSize); if (!handle->name) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) { @@ -656,7 +656,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, error: if (handle->name) { - free(handle->name); + uv__free(handle->name); handle->name = NULL; } @@ -717,7 +717,7 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) { uv__pipe_stop_read(handle); if (handle->name) { - free(handle->name); + uv__free(handle->name); handle->name = NULL; } @@ -845,7 +845,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) { if (err != 0) return err; - free(item); + uv__free(item); } else { pipe_client = (uv_pipe_t*)client; @@ -1261,9 +1261,9 @@ static int uv_pipe_write_impl(uv_loop_t* loop, if (handle->pipe.conn.ipc_header_write_req.type != UV_WRITE) { ipc_header_req = (uv_write_t*)&handle->pipe.conn.ipc_header_write_req; } else { - ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t)); + ipc_header_req = (uv_write_t*)uv__malloc(sizeof(uv_write_t)); if (!ipc_header_req) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } } @@ -1498,9 +1498,9 @@ void uv__pipe_insert_pending_socket(uv_pipe_t* handle, int tcp_connection) { uv__ipc_queue_item_t* item; - item = (uv__ipc_queue_item_t*) malloc(sizeof(*item)); + item = (uv__ipc_queue_item_t*) uv__malloc(sizeof(*item)); if (item == NULL) - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); memcpy(&item->socket_info_ex, info, sizeof(item->socket_info_ex)); item->tcp_connection = tcp_connection; @@ -1667,7 +1667,7 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, if (req == &handle->pipe.conn.ipc_header_write_req) { req->type = UV_UNKNOWN_REQ; } else { - free(req); + uv__free(req); } } else { if (req->cb) { @@ -1788,7 +1788,7 @@ static void eof_timer_init(uv_pipe_t* pipe) { assert(pipe->pipe.conn.eof_timer == NULL); assert(pipe->flags & UV_HANDLE_CONNECTION); - pipe->pipe.conn.eof_timer = (uv_timer_t*) malloc(sizeof *pipe->pipe.conn.eof_timer); + pipe->pipe.conn.eof_timer = (uv_timer_t*) uv__malloc(sizeof *pipe->pipe.conn.eof_timer); r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer); assert(r == 0); /* timers can't fail */ @@ -1863,7 +1863,7 @@ static void eof_timer_destroy(uv_pipe_t* pipe) { static void eof_timer_close_cb(uv_handle_t* handle) { assert(handle->type == UV_TIMER); - free(handle); + uv__free(handle); } @@ -1941,7 +1941,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) FileNameInformation); if (nt_status == STATUS_BUFFER_OVERFLOW) { name_size = sizeof(*name_info) + tmp_name_info.FileNameLength; - name_info = malloc(name_size); + name_info = uv__malloc(name_size); if (!name_info) { *size = 0; err = UV_ENOMEM; @@ -2020,7 +2020,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) goto cleanup; error: - free(name_info); + uv__free(name_info); cleanup: uv__pipe_unpause_read((uv_pipe_t*)handle); /* cast away const warning */ diff --git a/deps/uv/src/win/process-stdio.c b/deps/uv/src/win/process-stdio.c index 98566da6516fe0..e81f799f0b8355 100644 --- a/deps/uv/src/win/process-stdio.c +++ b/deps/uv/src/win/process-stdio.c @@ -279,7 +279,7 @@ int uv__stdio_create(uv_loop_t* loop, } /* Allocate the child stdio buffer */ - buffer = (BYTE*) malloc(CHILD_STDIO_SIZE(count)); + buffer = (BYTE*) uv__malloc(CHILD_STDIO_SIZE(count)); if (buffer == NULL) { return ERROR_OUTOFMEMORY; } @@ -459,7 +459,7 @@ void uv__stdio_destroy(BYTE* buffer) { } } - free(buffer); + uv__free(buffer); } diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index 887595f89cc9b6..855c3740816db2 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include /* alloca */ #include "uv.h" #include "internal.h" @@ -120,7 +120,7 @@ static int uv_utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) { return GetLastError(); } - ws = (WCHAR*) malloc(ws_len * sizeof(WCHAR)); + ws = (WCHAR*) uv__malloc(ws_len * sizeof(WCHAR)); if (ws == NULL) { return ERROR_OUTOFMEMORY; } @@ -197,7 +197,7 @@ static WCHAR* search_path_join_test(const WCHAR* dir, } /* Allocate buffer for output */ - result = result_pos = (WCHAR*)malloc(sizeof(WCHAR) * + result = result_pos = (WCHAR*)uv__malloc(sizeof(WCHAR) * (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1)); /* Copy cwd */ @@ -246,7 +246,7 @@ static WCHAR* search_path_join_test(const WCHAR* dir, return result; } - free(result); + uv__free(result); return NULL; } @@ -555,14 +555,14 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { dst_len = dst_len * 2 + arg_count * 2; /* Allocate buffer for the final command line. */ - dst = (WCHAR*) malloc(dst_len * sizeof(WCHAR)); + dst = (WCHAR*) uv__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)); + temp_buffer = (WCHAR*) uv__malloc(temp_buffer_len * sizeof(WCHAR)); if (temp_buffer == NULL) { err = ERROR_OUTOFMEMORY; goto error; @@ -596,14 +596,14 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { *pos++ = *(arg + 1) ? L' ' : L'\0'; } - free(temp_buffer); + uv__free(temp_buffer); *dst_ptr = dst; return 0; error: - free(dst); - free(temp_buffer); + uv__free(dst); + uv__free(temp_buffer); return err; } @@ -707,7 +707,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { } /* second pass: copy to UTF-16 environment block */ - dst_copy = malloc(env_len * sizeof(WCHAR)); + dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR)); if (!dst_copy) { return ERROR_OUTOFMEMORY; } @@ -725,7 +725,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { (int) (env_len - (ptr - dst_copy))); if (len <= 0) { DWORD err = GetLastError(); - free(dst_copy); + uv__free(dst_copy); return err; } *ptr_copy++ = ptr; @@ -765,9 +765,9 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { } /* final pass: copy, in sort order, and inserting required variables */ - dst = malloc((1+env_len) * sizeof(WCHAR)); + dst = uv__malloc((1+env_len) * sizeof(WCHAR)); if (!dst) { - free(dst_copy); + uv__free(dst_copy); return ERROR_OUTOFMEMORY; } @@ -812,7 +812,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { assert(env_len == (ptr - dst)); *ptr = L'\0'; - free(dst_copy); + uv__free(dst_copy); *dst_ptr = dst; return 0; } @@ -988,7 +988,7 @@ int uv_spawn(uv_loop_t* loop, goto done; } - cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR)); + cwd = (WCHAR*) uv__malloc(cwd_len * sizeof(WCHAR)); if (cwd == NULL) { err = ERROR_OUTOFMEMORY; goto done; @@ -1012,7 +1012,7 @@ int uv_spawn(uv_loop_t* loop, goto done; } - alloc_path = (WCHAR*) malloc(path_len * sizeof(WCHAR)); + alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR)); if (alloc_path == NULL) { err = ERROR_OUTOFMEMORY; goto done; @@ -1146,12 +1146,12 @@ int uv_spawn(uv_loop_t* loop, /* Cleanup, whether we succeeded or failed. */ done: - free(application); - free(application_path); - free(arguments); - free(cwd); - free(env); - free(alloc_path); + uv__free(application); + uv__free(application_path); + uv__free(arguments); + uv__free(cwd); + uv__free(env); + uv__free(alloc_path); if (process->child_stdio_buffer != NULL) { /* Clean up child stdio handles. */ diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index 8b0e18c7cf3256..da89f28d161e7a 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -215,7 +215,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { } } - free(handle->tcp.serv.accept_reqs); + uv__free(handle->tcp.serv.accept_reqs); handle->tcp.serv.accept_reqs = NULL; } @@ -564,9 +564,9 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { if(!handle->tcp.serv.accept_reqs) { handle->tcp.serv.accept_reqs = (uv_tcp_accept_t*) - malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t)); + uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t)); if (!handle->tcp.serv.accept_reqs) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } for (i = 0; i < simultaneous_accepts; i++) { diff --git a/deps/uv/src/win/thread.c b/deps/uv/src/win/thread.c index 9d273a56e700f5..e91ae9b13852d2 100644 --- a/deps/uv/src/win/thread.c +++ b/deps/uv/src/win/thread.c @@ -134,7 +134,7 @@ static UINT __stdcall uv__thread_start(void* arg) { ctx_p = arg; ctx = *ctx_p; - free(ctx_p); + uv__free(ctx_p); uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); uv_key_set(&uv__current_thread_key, (void*) ctx.self); @@ -150,7 +150,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { int err; HANDLE thread; - ctx = malloc(sizeof(*ctx)); + ctx = uv__malloc(sizeof(*ctx)); if (ctx == NULL) return UV_ENOMEM; @@ -167,7 +167,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { NULL); if (thread == NULL) { err = errno; - free(ctx); + uv__free(ctx); } else { err = 0; *tid = thread; diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 3697d5aa6aaf20..a0d1307f8a2590 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -36,6 +36,7 @@ #include #include #include +#include /* @@ -72,7 +73,7 @@ void uv__util_init() { InitializeCriticalSection(&process_title_lock); /* Retrieve high-resolution timer frequency - * and precompute its reciprocal. + * and precompute its reciprocal. */ if (QueryPerformanceFrequency(&perf_frequency)) { hrtime_interval_ = 1.0 / perf_frequency.QuadPart; @@ -122,7 +123,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) { utf16_buffer_len = (int) *size_ptr; } - utf16_buffer = (WCHAR*) malloc(sizeof(WCHAR) * utf16_buffer_len); + utf16_buffer = (WCHAR*) uv__malloc(sizeof(WCHAR) * utf16_buffer_len); if (!utf16_buffer) { return UV_ENOMEM; } @@ -151,7 +152,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) { goto error; } - free(utf16_buffer); + uv__free(utf16_buffer); /* utf8_len *does* include the terminating null at this point, but the */ /* returned size shouldn't. */ @@ -159,7 +160,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) { return 0; error: - free(utf16_buffer); + uv__free(utf16_buffer); return uv_translate_sys_error(err); } @@ -378,9 +379,9 @@ int uv_set_process_title(const char* title) { } /* Convert to wide-char string */ - title_w = (WCHAR*)malloc(sizeof(WCHAR) * length); + title_w = (WCHAR*)uv__malloc(sizeof(WCHAR) * length); if (!title_w) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } length = uv_utf8_to_utf16(title, title_w, length); @@ -400,14 +401,14 @@ int uv_set_process_title(const char* title) { } EnterCriticalSection(&process_title_lock); - free(process_title); - process_title = strdup(title); + uv__free(process_title); + process_title = uv__strdup(title); LeaveCriticalSection(&process_title_lock); err = 0; done: - free(title_w); + uv__free(title_w); return uv_translate_sys_error(err); } @@ -427,14 +428,14 @@ static int uv__get_process_title() { } assert(!process_title); - process_title = (char*)malloc(length); + process_title = (char*)uv__malloc(length); if (!process_title) { - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } /* Do utf16 -> utf8 conversion here */ if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) { - free(process_title); + uv__free(process_title); return -1; } @@ -540,9 +541,9 @@ int uv_uptime(double* uptime) { goto internalError; } - free(malloced_buffer); + uv__free(malloced_buffer); - buffer = malloced_buffer = (BYTE*) malloc(buffer_size); + buffer = malloced_buffer = (BYTE*) uv__malloc(buffer_size); if (malloced_buffer == NULL) { *uptime = 0; return UV_ENOMEM; @@ -584,7 +585,7 @@ int uv_uptime(double* uptime) { uint64_t value = *((uint64_t*) address); *uptime = (double) (object_type->PerfTime.QuadPart - value) / (double) object_type->PerfFreq.QuadPart; - free(malloced_buffer); + uv__free(malloced_buffer); return 0; } } @@ -594,12 +595,12 @@ int uv_uptime(double* uptime) { } /* If we get here, the uptime value was not found. */ - free(malloced_buffer); + uv__free(malloced_buffer); *uptime = 0; return UV_ENOSYS; internalError: - free(malloced_buffer); + uv__free(malloced_buffer); *uptime = 0; return UV_EIO; } @@ -625,14 +626,14 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { GetSystemInfo(&system_info); cpu_count = system_info.dwNumberOfProcessors; - cpu_infos = calloc(cpu_count, sizeof *cpu_infos); + cpu_infos = uv__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); + sppi = uv__malloc(sppi_size); if (sppi == NULL) { err = ERROR_OUTOFMEMORY; goto error; @@ -725,7 +726,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { assert(len > 0); /* Allocate 1 extra byte for the null terminator. */ - cpu_info->model = malloc(len + 1); + cpu_info->model = uv__malloc(len + 1); if (cpu_info->model == NULL) { err = ERROR_OUTOFMEMORY; goto error; @@ -747,7 +748,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { cpu_info->model[len] = '\0'; } - free(sppi); + uv__free(sppi); *cpu_count_ptr = cpu_count; *cpu_infos_ptr = cpu_infos; @@ -757,10 +758,10 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { 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); + uv__free(cpu_infos[i].model); - free(cpu_infos); - free(sppi); + uv__free(cpu_infos); + uv__free(sppi); return uv_translate_sys_error(err); } @@ -770,10 +771,10 @@ 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); + uv__free(cpu_infos[i].model); } - free(cpu_infos); + uv__free(cpu_infos); } @@ -801,8 +802,8 @@ static int is_windows_version_or_greater(DWORD os_major, /* Perform the test. */ return (int) VerifyVersionInfo( - &osvi, - VER_MAJORVERSION | VER_MINORVERSION | + &osvi, + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, condition_mask); } @@ -870,7 +871,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX; } - + /* Fetch the size of the adapters reported by windows, and then get the */ /* list itself. */ @@ -892,13 +893,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, if (r == ERROR_SUCCESS) break; - free(win_address_buf); + uv__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); + win_address_buf = uv__malloc(win_address_buf_size); if (win_address_buf == NULL) return UV_ENOMEM; @@ -906,7 +907,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, case ERROR_NO_DATA: { /* No adapters were found. */ - uv_address_buf = malloc(1); + uv_address_buf = uv__malloc(1); if (uv_address_buf == NULL) return UV_ENOMEM; @@ -966,7 +967,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, NULL, FALSE); if (name_size <= 0) { - free(win_address_buf); + uv__free(win_address_buf); return uv_translate_sys_error(GetLastError()); } uv_address_buf_size += name_size; @@ -983,9 +984,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, } /* Allocate space to store interface data plus adapter names. */ - uv_address_buf = malloc(uv_address_buf_size); + uv_address_buf = uv__malloc(uv_address_buf_size); if (uv_address_buf == NULL) { - free(win_address_buf); + uv__free(win_address_buf); return UV_ENOMEM; } @@ -1019,8 +1020,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, NULL, FALSE); if (name_size <= 0) { - free(win_address_buf); - free(uv_address_buf); + uv__free(win_address_buf); + uv__free(uv_address_buf); return uv_translate_sys_error(GetLastError()); } @@ -1053,14 +1054,14 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, prefix->PrefixLength <= prefix_len) continue; - if (address_prefix_match(sa->sa_family, sa, + if (address_prefix_match(sa->sa_family, sa, prefix->Address.lpSockaddr, prefix->PrefixLength)) { prefix_len = prefix->PrefixLength; } } /* If there is no matching prefix information, return a single-host - * subnet mask (e.g. 255.255.255.255 for IPv4). + * subnet mask (e.g. 255.255.255.255 for IPv4). */ if (!prefix_len) prefix_len = (sa->sa_family == AF_INET6) ? 128 : 32; @@ -1104,7 +1105,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, name_buf += name_size; } - free(win_address_buf); + uv__free(win_address_buf); *addresses_ptr = uv_address_buf; *count_ptr = count; @@ -1115,7 +1116,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { - free(addresses); + uv__free(addresses); } @@ -1153,3 +1154,67 @@ int uv_getrusage(uv_rusage_t *uv_rusage) { return 0; } + + +int uv_os_homedir(char* buffer, size_t* size) { + HANDLE token; + wchar_t path[MAX_PATH]; + DWORD bufsize; + size_t len; + int r; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + /* Check if the USERPROFILE environment variable is set first */ + len = GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH); + + if (len == 0) { + r = GetLastError(); + /* Don't return an error if USERPROFILE was not found */ + if (r != ERROR_ENVVAR_NOT_FOUND) + return uv_translate_sys_error(r); + } else if (len > MAX_PATH) { + /* This should not be possible */ + return UV_EIO; + } else { + goto convert_buffer; + } + + /* USERPROFILE is not set, so call GetUserProfileDirectoryW() */ + if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0) + return uv_translate_sys_error(GetLastError()); + + bufsize = MAX_PATH; + if (!GetUserProfileDirectoryW(token, path, &bufsize)) { + r = GetLastError(); + CloseHandle(token); + + /* This should not be possible */ + if (r == ERROR_INSUFFICIENT_BUFFER) + return UV_EIO; + + return uv_translate_sys_error(r); + } + + CloseHandle(token); + +convert_buffer: + + /* Check how much space we need */ + bufsize = uv_utf16_to_utf8(path, -1, NULL, 0); + if (bufsize == 0) { + return uv_translate_sys_error(GetLastError()); + } else if (bufsize > *size) { + *size = bufsize - 1; + return UV_ENOBUFS; + } + + /* Convert to UTF-8 */ + bufsize = uv_utf16_to_utf8(path, -1, buffer, *size); + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + *size = bufsize - 1; + return 0; +} diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index ea0503e8feefe4..e06a50e21341b7 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -184,7 +184,8 @@ enum test_status { # define inline __inline # endif -/* Emulate snprintf() on Windows, _snprintf() doesn't zero-terminate the buffer +# if defined(_MSC_VER) && _MSC_VER < 1900 +/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer * on overflow... */ inline int snprintf(char* buf, size_t len, const char* fmt, ...) { @@ -205,6 +206,7 @@ inline int snprintf(char* buf, size_t len, const char* fmt, ...) { return n; } +# endif #endif diff --git a/deps/uv/test/test-homedir.c b/deps/uv/test/test-homedir.c new file mode 100644 index 00000000000000..cbc47566c55e42 --- /dev/null +++ b/deps/uv/test/test-homedir.c @@ -0,0 +1,49 @@ +#include "uv.h" +#include "task.h" +#include + +#define PATHMAX 1024 +#define SMALLPATH 1 + +TEST_IMPL(homedir) { + char homedir[PATHMAX]; + size_t len; + char last; + int r; + + /* Test the normal case */ + len = sizeof homedir; + homedir[0] = '\0'; + ASSERT(strlen(homedir) == 0); + r = uv_os_homedir(homedir, &len); + ASSERT(r == 0); + ASSERT(strlen(homedir) == len); + ASSERT(len > 0); + ASSERT(homedir[len] == '\0'); + + if (len > 1) { + last = homedir[len - 1]; +#ifdef _WIN32 + ASSERT(last != '\\'); +#else + ASSERT(last != '/'); +#endif + } + + /* Test the case where the buffer is too small */ + len = SMALLPATH; + r = uv_os_homedir(homedir, &len); + ASSERT(r == UV_ENOBUFS); + ASSERT(len > SMALLPATH); + + /* Test invalid inputs */ + r = uv_os_homedir(NULL, &len); + ASSERT(r == UV_EINVAL); + r = uv_os_homedir(homedir, NULL); + ASSERT(r == UV_EINVAL); + len = 0; + r = uv_os_homedir(homedir, &len); + ASSERT(r == UV_EINVAL); + + return 0; +} diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 1e3c13d5e9267d..1e4018c98b8685 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -117,6 +117,7 @@ TEST_DECLARE (pipe_bind_error_inval) TEST_DECLARE (pipe_listen_without_bind) TEST_DECLARE (pipe_connect_bad_name) TEST_DECLARE (pipe_connect_to_file) +TEST_DECLARE (pipe_connect_on_prepare) TEST_DECLARE (pipe_getsockname) TEST_DECLARE (pipe_getsockname_abstract) TEST_DECLARE (pipe_getsockname_blocking) @@ -182,6 +183,7 @@ TEST_DECLARE (process_title) TEST_DECLARE (cwd_and_chdir) TEST_DECLARE (get_memory) TEST_DECLARE (handle_fileno) +TEST_DECLARE (homedir) TEST_DECLARE (hrtime) TEST_DECLARE (getaddrinfo_fail) TEST_DECLARE (getaddrinfo_fail_sync) @@ -344,6 +346,7 @@ TASK_LIST_START TEST_ENTRY (pipe_connect_bad_name) TEST_ENTRY (pipe_connect_to_file) + TEST_ENTRY (pipe_connect_on_prepare) TEST_ENTRY (pipe_server_close) #ifndef _WIN32 @@ -540,6 +543,8 @@ TASK_LIST_START TEST_ENTRY (handle_fileno) + TEST_ENTRY (homedir) + TEST_ENTRY (hrtime) TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000) diff --git a/deps/uv/test/test-pipe-connect-prepare.c b/deps/uv/test/test-pipe-connect-prepare.c new file mode 100644 index 00000000000000..a86e7284a799fd --- /dev/null +++ b/deps/uv/test/test-pipe-connect-prepare.c @@ -0,0 +1,83 @@ +/* Copyright (c) 2015 Saúl Ibarra Corretgé . + * 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 "task.h" +#include +#include + + +#ifdef _WIN32 +# define BAD_PIPENAME "bad-pipe" +#else +# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there" +#endif + + +static int close_cb_called = 0; +static int connect_cb_called = 0; + +static uv_pipe_t pipe_handle; +static uv_prepare_t prepare_handle; +static uv_connect_t conn_req; + + +static void close_cb(uv_handle_t* handle) { + ASSERT(handle != NULL); + close_cb_called++; +} + + +static void connect_cb(uv_connect_t* connect_req, int status) { + ASSERT(status == UV_ENOENT); + connect_cb_called++; + uv_close((uv_handle_t*)&prepare_handle, close_cb); + uv_close((uv_handle_t*)&pipe_handle, close_cb); +} + + +static void prepare_cb(uv_prepare_t* handle) { + ASSERT(handle == &prepare_handle); + uv_pipe_connect(&conn_req, &pipe_handle, BAD_PIPENAME, connect_cb); +} + + +TEST_IMPL(pipe_connect_on_prepare) { + int r; + + r = uv_pipe_init(uv_default_loop(), &pipe_handle, 0); + ASSERT(r == 0); + + r = uv_prepare_init(uv_default_loop(), &prepare_handle); + ASSERT(r == 0); + r = uv_prepare_start(&prepare_handle, prepare_cb); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(close_cb_called == 2); + ASSERT(connect_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c index dc6fa32b0d115f..76495e14fd87c3 100644 --- a/deps/uv/test/test-platform-output.c +++ b/deps/uv/test/test-platform-output.c @@ -112,11 +112,13 @@ TEST_IMPL(platform_output) { if (interfaces[i].netmask.netmask4.sin_family == AF_INET) { uv_ip4_name(&interfaces[i].netmask.netmask4, buffer, sizeof(buffer)); + printf(" netmask: %s\n", buffer); } else if (interfaces[i].netmask.netmask4.sin_family == AF_INET6) { uv_ip6_name(&interfaces[i].netmask.netmask6, buffer, sizeof(buffer)); + printf(" netmask: %s\n", buffer); + } else { + printf(" netmask: none\n"); } - - printf(" netmask: %s\n", buffer); } uv_free_interface_addresses(interfaces, count); diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index e5e3eabb6dd61b..7173a827a371ed 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -64,12 +64,6 @@ 'src/version.c' ], 'conditions': [ - [ 'gcc_version<=44', { - # GCC versions <= 4.4 do not handle the aliasing in the queue - # implementation, so disable aliasing on these platforms - # to avoid subtle bugs - 'cflags': [ '-fno-strict-aliasing' ], - }], [ 'OS=="win"', { 'defines': [ '_WIN32_WINNT=0x0600', @@ -116,6 +110,7 @@ '-liphlpapi', '-lpsapi', '-lshell32', + '-luserenv', '-lws2_32' ], }, @@ -310,6 +305,7 @@ 'test/test-getnameinfo.c', 'test/test-getsockname.c', 'test/test-handle-fileno.c', + 'test/test-homedir.c', 'test/test-hrtime.c', 'test/test-idle.c', 'test/test-ip6-addr.c', @@ -330,6 +326,7 @@ 'test/test-ping-pong.c', 'test/test-pipe-bind-error.c', 'test/test-pipe-connect-error.c', + 'test/test-pipe-connect-prepare.c', 'test/test-pipe-getsockname.c', 'test/test-pipe-sendmsg.c', 'test/test-pipe-server-close.c', diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat index 084ab9578fe10d..696f0db30e15ad 100644 --- a/deps/uv/vcbuild.bat +++ b/deps/uv/vcbuild.bat @@ -44,6 +44,14 @@ goto next-arg if defined WindowsSDKDir goto select-target if defined VCINSTALLDIR goto select-target +@rem Look for Visual Studio 2015 +if not defined VS140COMNTOOLS goto vc-set-2013 +if not exist "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2013 +call "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset% +set GYP_MSVS_VERSION=2015 +goto select-target + +:vc-set-2013 @rem Look for Visual Studio 2013 if not defined VS120COMNTOOLS goto vc-set-2012 if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012