Frank Denis <github@pureftpd.org>
Isaac Z. Schlueter <i@izs.me>
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
-Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
+Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
+Rasmus Christian Pedersen <ruysch@outlook.com>
Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
Brian Mazza <louseman@gmail.com>
Elliot Saba <staticfloat@gmail.com>
Ben Kelly <ben@wanderview.com>
-Kristian Evensen <kristian.evensen@gmail.com>
Nils Maier <maierman@web.de>
Nicholas Vavilov <vvnicholas@gmail.com>
Miroslav Bajtoš <miro.bajtos@gmail.com>
Sam Roberts <vieuxtech@gmail.com>
River Tarnell <river@loreley.flyingparchment.org.uk>
Nathan Sweet <nathanjsweet@gmail.com>
-Alex Crichton <alex@alexcrichton.com>
Luca Bruno <lucab@debian.org>
Trevor Norris <trev.norris@gmail.com>
Oguz Bastemur <obastemur@gmail.com>
Austin Foxley <austinf@cetoncorp.com>
Benjamin Saunders <ben.e.saunders@gmail.com>
Geoffry Song <goffrie@gmail.com>
-Rasmus Pedersen <ruysch@outlook.com>
+Rasmus Christian Pedersen <ruysch@outlook.com>
William Light <wrl@illest.net>
Oleg Efimov <o.efimov@corp.badoo.com>
Lars Gierth <larsg@systemli.org>
-rcp <zerhacken@yahoo.com>
-Alexis Campailla <alexis@janeasystems.com>
+Rasmus Christian Pedersen <zerhacken@yahoo.com>
Justin Venus <justin.venus@gmail.com>
-Ben Kelly <ben@wanderview.com>
Kristian Evensen <kristian.evensen@gmail.com>
-Sean Silva <chisophugis@gmail.com>
Linus Mårtensson <linus.martensson@sonymobile.com>
Navaneeth Kedaram Nambiathan <navaneethkn@gmail.com>
-Brent Cook <brent@boundary.com>
-Brian Kaisner <bkize1@gmail.com>
-Reini Urban <rurban@cpanel.net>
-Maks Naumov <maksqwe1@ukr.net>
-Sean Farrell <sean.farrell@rioki.org>
-Christoph Iserlohn <christoph.iserlohn@innoq.com>
-Steven Kabbes <stevenkabbes@gmail.com>
-Tenor Biel <tenorbiel@gmail.com>
-Andrej Manduch <AManduch@gmail.com>
-Joshua Neuheisel <joshua@neuheisel.us>
Yorkie <yorkiefixer@gmail.com>
-Sam Roberts <vieuxtech@gmail.com>
-River Tarnell <river@loreley.flyingparchment.org.uk>
-Nathan Sweet <nathanjsweet@gmail.com>
-Dylan Cali <calid1984@gmail.com>
-Austin Foxley <austinf@cetoncorp.com>
-Geoffry Song <goffrie@gmail.com>
-Benjamin Saunders <ben.e.saunders@gmail.com>
-Rasmus Pedersen <ruysch@outlook.com>
-William Light <wrl@illest.net>
-Oleg Efimov <o.efimov@corp.badoo.com>
-Lars Gierth <larsg@systemli.org>
StarWing <weasley.wx@gmail.com>
thierry-FreeBSD <thierry@FreeBSD.org>
Isaiah Norton <isaiah.norton@gmail.com>
Paul Tan <pyokagan@gmail.com>
Javier Hernández <jhernandez@emergya.com>
Tonis Tiigi <tonistiigi@gmail.com>
+Norio Kobota <nori.0428@gmail.com>
+李港平 <chopdown@gmail.com>
+Chernyshev Viacheslav <astellar@ro.ru>
+Stephen von Takach <steve@advancedcontrol.com.au>
-2014.04.07, Version 0.11.23 (Unstable)
+2014.05.02, Version 0.11.25 (Unstable)
+
+Changes since version 0.11.24:
+
+* osx: pass const handle pointer to uv___stream_fd (Chernyshev Viacheslav)
+
+* unix, windows: pass const handle ptr to uv_tcp_get*name (Chernyshev
+ Viacheslav)
+
+* common: pass const sockaddr ptr to uv_ip*_name (Chernyshev Viacheslav)
+
+* unix, windows: validate flags on uv_udp|tcp_bind (Saúl Ibarra Corretgé)
+
+* unix: handle case when addr is not initialized after recvmsg (Saúl Ibarra
+ Corretgé)
+
+* unix, windows: uv_now constness (Rasmus Pedersen)
+
+
+2014.04.15, Version 0.11.24 (Unstable), ed948c29f6e8c290f79325a6f0bc9ef35bcde644
+
+Changes since version 0.11.23:
+
+* linux: reduce file descriptor count of async pipe (Ben Noordhuis)
+
+* sunos: support IPv6 qualified link-local addresses (Saúl Ibarra Corretgé)
+
+* windows: fix opening of read-only stdin pipes (Alexis Campailla)
+
+* windows: Fix an infinite loop in uv_spawn (Alex Crichton)
+
+* windows: fix console signal handler refcount (李港平)
+
+* inet: allow scopeid in uv_inet_pton (Fedor Indutny)
+
+* win: always leave crit section in get_proc_title (Fedor Indutny)
+
+
+2014.04.07, Version 0.11.23 (Unstable), e54de537efcacd593f36fcaaf8b4cb9e64313275
Changes since version 0.11.22:
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
-AC_INIT([libuv], [0.11.23], [https://github.com/joyent/libuv/issues])
+AC_INIT([libuv], [0.11.25], [https://github.com/joyent/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
+m4_include([m4/as_case.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
AC_CANONICAL_HOST
AC_ENABLE_SHARED
#endif /* defined(PORT_SOURCE_FILE) */
+#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
+
#endif /* UV_SUNOS_H */
uv_buf_t bufsml[4]; \
#define UV_HANDLE_PRIVATE_FIELDS \
- int flags; \
uv_handle_t* next_closing; \
+ unsigned int flags; \
#define UV_STREAM_PRIVATE_FIELDS \
uv_connect_t *connect_req; \
#define UV_VERSION_MAJOR 0
#define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 23
+#define UV_VERSION_PATCH 25
#define UV_VERSION_IS_RELEASE 1
#endif /* UV_VERSION_H */
void* queue[2]; \
int queue_len; \
} pending_ipc_info; \
- uv_write_t* non_overlapped_writes_tail;
+ uv_write_t* non_overlapped_writes_tail; \
+ void* reserved;
#define UV_PIPE_PRIVATE_FIELDS \
HANDLE handle; \
*
* Use uv_hrtime() if you need sub-millisecond granularity.
*/
-UV_EXTERN uint64_t uv_now(uv_loop_t*);
+UV_EXTERN uint64_t uv_now(const uv_loop_t*);
/*
* Get backend file descriptor. Only kqueue, epoll and event ports are
* Same as `uv_write()`, but won't queue write request if it can't be completed
* immediately.
* Will return either:
- * - positive number of bytes written
- * - zero - if queued write is needed
- * - negative error code
+ * - >= 0: number of bytes written (can be less than the supplied buffer size)
+ * - < 0: negative error code
*/
UV_EXTERN int uv_try_write(uv_stream_t* handle,
const uv_buf_t bufs[],
UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle,
const struct sockaddr* addr,
unsigned int flags);
-UV_EXTERN int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
- int* namelen);
-UV_EXTERN int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
- int* namelen);
+UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t* handle,
+ struct sockaddr* name,
+ int* namelen);
+UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle,
+ struct sockaddr* name,
+ int* namelen);
/*
* Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle
* discard or repurpose the read buffer.
* < 0 if a transmission error was detected.
* buf uv_buf_t with the received data.
- * addr struct sockaddr_in or struct sockaddr_in6.
- * Valid for the duration of the callback only.
+ * addr struct sockaddr* containing the address of the sender.
+ * Can be NULL. Valid for the duration of the callback only.
* flags One or more OR'ed UV_UDP_* constants.
* Right now only UV_UDP_PARTIAL is used.
*/
UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr);
/* Convert binary addresses to strings */
-UV_EXTERN int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size);
-UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
+UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size);
+UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size);
/* Cross-platform IPv6-capable implementation of the 'standard' inet_ntop */
/* and inet_pton functions. On success they return 0. If an error */
curtok = src;
seen_xdigits = 0;
val = 0;
- while ((ch = *src++) != '\0') {
+ while ((ch = *src++) != '\0' && ch != '%') {
const char *pch;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
continue;
}
if (ch == '.' && ((tp + sizeof(struct in_addr)) <= endp)) {
- int err = inet_pton4(curtok, tp);
+ int err;
+
+ /* Scope id present, parse ipv4 addr without it */
+ pch = strchr(curtok, '%');
+ if (pch != NULL) {
+ char tmp[sizeof "255.255.255.255"];
+
+ memcpy(tmp, curtok, pch - curtok);
+ curtok = tmp;
+ src = pch;
+ }
+
+ err = inet_pton4(curtok, tp);
if (err == 0) {
tp += sizeof(struct in_addr);
seen_xdigits = 0;
#include "internal.h"
#include <errno.h>
+#include <stdio.h> /* snprintf() */
#include <assert.h>
#include <stdlib.h>
#include <string.h>
pipefd[0] = err;
pipefd[1] = -1;
}
- else if (err == -ENOSYS)
+ else if (err == -ENOSYS) {
err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
+#if defined(__linux__)
+ /* Save a file descriptor by opening one of the pipe descriptors as
+ * read/write through the procfs. That file descriptor can then
+ * function as both ends of the pipe.
+ */
+ if (err == 0) {
+ char buf[32];
+ int fd;
+
+ snprintf(buf, sizeof(buf), "/proc/self/fd/%d", pipefd[0]);
+ fd = uv__open_cloexec(buf, O_RDWR);
+ if (fd != -1) {
+ uv__close(pipefd[0]);
+ uv__close(pipefd[1]);
+ pipefd[0] = fd;
+ pipefd[1] = fd;
+ }
+ }
+#endif
+ }
if (err < 0)
return err;
if (wa->io_watcher.fd == -1)
return;
- uv__io_stop(loop, &wa->io_watcher, UV__POLLIN);
- uv__close(wa->io_watcher.fd);
- wa->io_watcher.fd = -1;
-
if (wa->wfd != -1) {
- uv__close(wa->wfd);
+ if (wa->wfd != wa->io_watcher.fd)
+ uv__close(wa->wfd);
wa->wfd = -1;
}
+
+ uv__io_stop(loop, &wa->io_watcher, UV__POLLIN);
+ uv__close(wa->io_watcher.fd);
+ wa->io_watcher.fd = -1;
}
uv_handle_type uv__handle_type(int fd);
#if defined(__APPLE__)
-int uv___stream_fd(uv_stream_t* handle);
-#define uv__stream_fd(handle) (uv___stream_fd((uv_stream_t*) (handle)))
+int uv___stream_fd(const uv_stream_t* handle);
+#define uv__stream_fd(handle) (uv___stream_fd((const uv_stream_t*) (handle)))
#else
#define uv__stream_fd(handle) ((handle)->io_watcher.fd)
#endif /* defined(__APPLE__) */
#if defined(__APPLE__)
-int uv___stream_fd(uv_stream_t* handle) {
- uv__stream_select_t* s;
+int uv___stream_fd(const uv_stream_t* handle) {
+ const uv__stream_select_t* s;
assert(handle->type == UV_TCP ||
handle->type == UV_TTY ||
int err;
int on;
+ /* Cannot set IPv6-only mode on non-IPv6 socket. */
+ if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
+ return -EINVAL;
+
err = maybe_new_socket(tcp,
addr->sa_family,
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
}
-int uv_tcp_getsockname(uv_tcp_t* handle,
+int uv_tcp_getsockname(const uv_tcp_t* handle,
struct sockaddr* name,
int* namelen) {
socklen_t socklen;
}
-int uv_tcp_getpeername(uv_tcp_t* handle,
+int uv_tcp_getpeername(const uv_tcp_t* handle,
struct sockaddr* name,
int* namelen) {
socklen_t socklen;
handle->recv_cb(handle, -errno, &buf, NULL, 0);
}
else {
- flags = 0;
+ const struct sockaddr *addr;
+ if (h.msg_namelen == 0)
+ addr = NULL;
+ else
+ addr = (const struct sockaddr*) &peer;
+ flags = 0;
if (h.msg_flags & MSG_TRUNC)
flags |= UV_UDP_PARTIAL;
- handle->recv_cb(handle,
- nread,
- &buf,
- (const struct sockaddr*) &peer,
- flags);
+ handle->recv_cb(handle, nread, &buf, addr, flags);
}
}
/* recv_cb callback may decide to pause or close the handle */
}
-int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
+int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) {
return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
}
-int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
+int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) {
return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
}
}
-uint64_t uv_now(uv_loop_t* loop) {
+uint64_t uv_now(const uv_loop_t* loop) {
return loop->time;
}
}
-static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle,
- HANDLE pipeHandle, DWORD duplex_flags) {
+static int uv_set_pipe_handle(uv_loop_t* loop,
+ uv_pipe_t* handle,
+ HANDLE pipeHandle,
+ DWORD duplex_flags) {
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;
FILE_MODE_INFORMATION mode_info;
DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
+ DWORD current_mode = 0;
+ DWORD err = 0;
if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
- /* If this returns ERROR_INVALID_PARAMETER we probably opened something */
- /* that is not a pipe. */
- if (GetLastError() == ERROR_INVALID_PARAMETER) {
- SetLastError(WSAENOTSOCK);
+ err = GetLastError();
+ if (err == ERROR_ACCESS_DENIED) {
+ /*
+ * SetNamedPipeHandleState can fail if the handle doesn't have either
+ * GENERIC_WRITE or FILE_WRITE_ATTRIBUTES.
+ * But if the handle already has the desired wait and blocking modes
+ * we can continue.
+ */
+ if (!GetNamedPipeHandleState(pipeHandle, ¤t_mode, NULL, NULL,
+ NULL, NULL, 0)) {
+ return -1;
+ } else if (current_mode != mode) {
+ SetLastError(ERROR_ACCESS_DENIED);
+ return -1;
+ } else {
+ duplex_flags &= ~UV_HANDLE_WRITABLE;
+ }
+ } else {
+ /* If this returns ERROR_INVALID_PARAMETER we probably opened
+ * something that is not a pipe. */
+ if (err == ERROR_INVALID_PARAMETER) {
+ SetLastError(WSAENOTSOCK);
+ }
+ return -1;
}
- return -1;
}
/* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */
int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
HANDLE os_handle = uv__get_osfhandle(file);
+ DWORD duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
if (os_handle == INVALID_HANDLE_VALUE ||
- uv_set_pipe_handle(pipe->loop, pipe, os_handle, 0) == -1) {
+ uv_set_pipe_handle(pipe->loop, pipe, os_handle, duplex_flags) == -1) {
return UV_EINVAL;
}
uv_pipe_connection_init(pipe);
- pipe->handle = os_handle;
- pipe->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
if (pipe->ipc) {
assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
}
/* Skip the separator that dir_end now points to */
- if (dir_end != path) {
+ if (dir_end != path || *path == L';') {
dir_end++;
}
/* If the console control handler has already been hooked, just add a */
/* reference. */
- if (uv__signal_control_handler_refs > 0)
+ if (uv__signal_control_handler_refs > 0) {
+ uv__signal_control_handler_refs++;
return 0;
+ }
if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE))
return GetLastError();
int r;
if (handle->socket == INVALID_SOCKET) {
- SOCKET sock = socket(addr->sa_family, SOCK_STREAM, 0);
+ SOCKET sock;
+
+ /* Cannot set IPv6-only mode on non-IPv6 socket. */
+ if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
+ return ERROR_INVALID_PARAMETER;
+
+ sock = socket(addr->sa_family, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
return WSAGetLastError();
}
}
-int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
- int* namelen) {
+int uv_tcp_getsockname(const uv_tcp_t* handle,
+ struct sockaddr* name,
+ int* namelen) {
int result;
if (!(handle->flags & UV_HANDLE_BOUND)) {
}
-int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
- int* namelen) {
+int uv_tcp_getpeername(const uv_tcp_t* handle,
+ struct sockaddr* name,
+ int* namelen) {
int result;
if (!(handle->flags & UV_HANDLE_BOUND)) {
* we must query it with getConsoleTitleW
*/
if (!process_title && uv__get_process_title() == -1) {
+ LeaveCriticalSection(&process_title_lock);
return uv_translate_sys_error(GetLastError());
}
/* Free the read/write buffer and the request */
wr = (write_req_t*) req;
free(wr->buf.base);
- free(wr);
-
- if (status == 0)
- return;
- fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
-
- if (status == UV_ECANCELED)
+ if (status == 0) {
+ free(wr);
return;
+ }
- ASSERT(status == UV_EPIPE);
- uv_close((uv_handle_t*)req->handle, on_close);
-}
-
+ fprintf(stderr,
+ "uv_write error: %s - %s\n",
+ uv_err_name(status),
+ uv_strerror(status));
-static void after_shutdown(uv_shutdown_t* req, int status) {
- uv_close((uv_handle_t*)req->handle, on_close);
- free(req);
+ if (!uv_is_closing((uv_handle_t*) req->handle))
+ uv_close((uv_handle_t*) req->handle, on_close);
+ free(wr);
}
const uv_buf_t* buf) {
int i;
write_req_t *wr;
- uv_shutdown_t* req;
if (nread < 0) {
/* Error or EOF */
free(buf->base);
}
- req = (uv_shutdown_t*) malloc(sizeof *req);
- uv_shutdown(req, handle, after_shutdown);
-
+ uv_close((uv_handle_t*) handle, on_close);
return;
}
}
wr = (write_req_t*) malloc(sizeof *wr);
-
+ ASSERT(wr != NULL);
wr->buf = uv_buf_init(buf->base, nread);
+
if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) {
FATAL("uv_write failed");
}
callback_counts[i] = 0;
data = (int*)malloc(sizeof(int));
+ ASSERT(data != NULL);
*data = i;
getaddrinfo_handles[i].data = data;
RETURN_SKIP("Qualified link-local addresses are not supported.");
#endif
}
+
+
+#define GOOD_ADDR_LIST(X) \
+ X("::") \
+ X("::1") \
+ X("fe80::1") \
+ X("fe80::") \
+ X("fe80::2acf:daff:fedd:342a") \
+ X("fe80:0:0:0:2acf:daff:fedd:342a") \
+ X("fe80:0:0:0:2acf:daff:1.2.3.4") \
+
+#define BAD_ADDR_LIST(X) \
+ X(":::1") \
+ X("abcde::1") \
+ X("fe80:0:0:0:2acf:daff:fedd:342a:5678") \
+ X("fe80:0:0:0:2acf:daff:abcd:1.2.3.4") \
+ X("fe80:0:0:2acf:daff:1.2.3.4.5") \
+
+#define TEST_GOOD(ADDR) \
+ ASSERT(0 == uv_inet_pton(AF_INET6, ADDR, &addr)); \
+ ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%en1", &addr)); \
+ ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%%%%", &addr)); \
+ ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%en1:1.2.3.4", &addr)); \
+
+#define TEST_BAD(ADDR) \
+ ASSERT(0 != uv_inet_pton(AF_INET6, ADDR, &addr)); \
+ ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%en1", &addr)); \
+ ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%%%%", &addr)); \
+ ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%en1:1.2.3.4", &addr)); \
+
+TEST_IMPL(ip6_pton) {
+ struct in6_addr addr;
+
+ GOOD_ADDR_LIST(TEST_GOOD)
+ BAD_ADDR_LIST(TEST_BAD)
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#undef GOOD_ADDR_LIST
+#undef BAD_ADDR_LIST
TEST_DECLARE (semaphore_3)
TEST_DECLARE (tty)
TEST_DECLARE (stdio_over_pipes)
+TEST_DECLARE (ip6_pton)
TEST_DECLARE (ipc_listen_before_write)
TEST_DECLARE (ipc_listen_after_write)
#ifndef _WIN32
TEST_DECLARE (tcp_bind_error_fault)
TEST_DECLARE (tcp_bind_error_inval)
TEST_DECLARE (tcp_bind_localhost_ok)
+TEST_DECLARE (tcp_bind_invalid_flags)
TEST_DECLARE (tcp_listen_without_bind)
TEST_DECLARE (tcp_connect_error_fault)
TEST_DECLARE (tcp_connect_timeout)
TEST_DECLARE (listen_with_simultaneous_accepts)
TEST_DECLARE (listen_no_simultaneous_accepts)
TEST_DECLARE (fs_stat_root)
+TEST_DECLARE (spawn_with_an_odd_path)
#else
TEST_DECLARE (emfile)
TEST_DECLARE (close_fd)
TEST_ENTRY (pipe_server_close)
TEST_ENTRY (tty)
TEST_ENTRY (stdio_over_pipes)
+ TEST_ENTRY (ip6_pton)
TEST_ENTRY (ipc_listen_before_write)
TEST_ENTRY (ipc_listen_after_write)
#ifndef _WIN32
TEST_ENTRY (tcp_bind_error_fault)
TEST_ENTRY (tcp_bind_error_inval)
TEST_ENTRY (tcp_bind_localhost_ok)
+ TEST_ENTRY (tcp_bind_invalid_flags)
TEST_ENTRY (tcp_listen_without_bind)
TEST_ENTRY (tcp_connect_error_fault)
TEST_ENTRY (tcp_connect_timeout)
TEST_ENTRY (listen_with_simultaneous_accepts)
TEST_ENTRY (listen_no_simultaneous_accepts)
TEST_ENTRY (fs_stat_root)
+ TEST_ENTRY (spawn_with_an_odd_path)
#else
TEST_ENTRY (emfile)
TEST_ENTRY (close_fd)
struct sockaddr_in6 server_addr;
pinger_t *pinger;
+
ASSERT(0 ==uv_ip6_addr("::1", TEST_PORT, &server_addr));
pinger = malloc(sizeof(*pinger));
+ ASSERT(pinger != NULL);
pinger->state = 0;
pinger->pongs = 0;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
pinger = malloc(sizeof(*pinger));
+ ASSERT(pinger != NULL);
pinger->state = 0;
pinger->pongs = 0;
pinger_t *pinger;
pinger = (pinger_t*)malloc(sizeof(*pinger));
+ ASSERT(pinger != NULL);
pinger->state = 0;
pinger->pongs = 0;
r = uv_spawn(uv_default_loop(), &process, &options);
ASSERT(r == UV_ENOENT || r == UV_EACCES);
ASSERT(0 == uv_is_active((uv_handle_t*) &process));
+ uv_close((uv_handle_t*) &process, NULL);
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
MAKE_VALGRIND_HAPPY();
uv_write_t write_req;
uv_buf_t buf;
uv_stdio_container_t stdio[2];
- static char buffer[] = "hello-from-spawn_stdin";
+ static char buffer[] = "hello-from-spawn_stdin\n";
- init_process_options("spawn_helper1", exit_cb);
+ init_process_options("spawn_helper3", exit_cb);
uv_pipe_init(uv_default_loop(), &in, 0);
options.stdio = stdio;
WCHAR* non_verbatim_output;
test_output = calloc(count, sizeof(WCHAR*));
+ ASSERT(test_output != NULL);
for (i = 0; i < count; ++i) {
test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR));
quote_cmd_arg(test_str[i], test_output[i]);
total_size += wcslen(test_output[i]) + 1;
}
command_line = calloc(total_size + 1, sizeof(WCHAR));
+ ASSERT(command_line != NULL);
for (i = 0; i < count; ++i) {
wcscat(command_line, test_output[i]);
wcscat(command_line, L" ");
return 0;
}
+
+// Regression test for issue #909
+TEST_IMPL(spawn_with_an_odd_path) {
+ int r;
+
+ char newpath[2048];
+ char *path = getenv("PATH");
+ ASSERT(path != NULL);
+ snprintf(newpath, 2048, ";.;%s", path);
+ SetEnvironmentVariable("PATH", path);
+
+ init_process_options("", exit_cb);
+ options.file = options.args[0] = "program-that-had-better-not-exist";
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == UV_ENOENT || r == UV_EACCES);
+ ASSERT(0 == uv_is_active((uv_handle_t*) &process));
+ uv_close((uv_handle_t*) &process, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
#endif
#ifndef _WIN32
}
+TEST_IMPL(tcp_bind_invalid_flags) {
+ struct sockaddr_in addr;
+ uv_tcp_t server;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, UV_TCP_IPV6ONLY);
+ ASSERT(r == UV_EINVAL);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(tcp_listen_without_bind) {
int r;
uv_tcp_t server;
* the thread pool is saturated. As with any timing dependent test,
* this is obviously not ideal.
*/
- if (uv_cond_timedwait(&signal_cond, &signal_mutex, (uint64_t)(350 * 1e6))) {
+ if (uv_cond_timedwait(&signal_cond,
+ &signal_mutex,
+ (uint64_t) (350 * 1e6))) {
ASSERT(0 == uv_cancel((uv_req_t*) req));
break;
}
'test/test-getsockname.c',
'test/test-hrtime.c',
'test/test-idle.c',
+ 'test/test-ip6-addr.c',
'test/test-ipc.c',
'test/test-ipc-send-recv.c',
'test/test-list.h',