Brandon Philips <brandon.philips@rackspace.com> <brandon@ifup.org>
Brian White <mscdex@mscdex.net>
Brian White <mscdex@mscdex.net> <mscdex@gmail.com>
+Christoph Iserlohn <christoph.iserlohn@innoq.com>
Frank Denis <github@pureftpd.org>
Isaac Z. Schlueter <i@izs.me>
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>
Timothy J. Fontaine <tjfontaine@gmail.com>
Yasuhiro Matsumoto <mattn.jp@gmail.com>
+Yazhong Liu <yorkiefixer@gmail.com>
Yuki Okumura <mjt@cltn.org>
Sean Farrell <sean.farrell@rioki.org>
Chris Bank <cbank@adobe.com>
Geert Jansen <geertj@gmail.com>
+Christoph Iserlohn <christoph.iserlohn@innoq.com>
+Steven Kabbes <stevenkabbes@gmail.com>
Alex Gaynor <alex.gaynor@gmail.com>
huxingyi <huxingyi@msn.com>
-ci-innoq <christoph.iserlohn@innoq.com>
-Steven Kabbes <stevenkabbes@gmail.com>
Tenor Biel <tenorbiel@gmail.com>
Andrej Manduch <AManduch@gmail.com>
Joshua Neuheisel <joshua@neuheisel.us>
Alexis Campailla <alexis@janeasystems.com>
-Yorkie <yorkiefixer@gmail.com>
+Yazhong Liu <yorkiefixer@gmail.com>
Sam Roberts <vieuxtech@gmail.com>
River Tarnell <river@loreley.flyingparchment.org.uk>
+Nathan Sweet <nathanjsweet@gmail.com>
+Trevor Norris <trev.norris@gmail.com>
-2013.12.32, Version 0.11.17 (Unstable)
+2014.01.23, Version 0.11.18 (Unstable)
+
+Changes since version 0.11.17:
+
+* osx: Fix a possible segfault in uv__io_poll (Alex Crichton)
+
+* windows: improved handling of invalid FDs (Alexis Campailla)
+
+* doc: adding ARCHS flag to OS X build command (Nathan Sweet)
+
+* tcp: reveal bind-time errors before listen (Alexis Campailla)
+
+* tcp: uv_tcp_dualstack() (Fedor Indutny)
+
+* linux: relax assumption on /proc/stat parsing (Luca Bruno)
+
+* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny)
+
+* process: close stdio after dup2'ing it (Fedor Indutny)
+
+* linux: move sscanf() out of the assert() (Trevor Norris)
+
+
+2014.01.23, Version 0.10.23 (Stable)
+
+Changes since version 0.10.22:
+
+* linux: relax assumption on /proc/stat parsing (Luca Bruno)
+
+* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny)
+
+* process: close stdio after dup2'ing it (Fedor Indutny)
+
+
+2014.01.08, Version 0.10.22 (Stable), f526c90eeff271d9323a9107b9a64a4671fd3103
+
+Changes since version 0.10.21:
+
+* windows: avoid assertion failure when pipe server is closed (Bert Belder)
+
+
+2013.12.32, Version 0.11.17 (Unstable), 589c224d4c2e79fec65db01d361948f1e4976858
Changes since version 0.11.16:
Run:
$ ./gyp_uv.py -f xcode
- $ xcodebuild -project uv.xcodeproj -configuration Release -target All
+ $ xcodebuild -ARCHS="x86_64" -project uv.xcodeproj \
+ -configuration Release -target All
+
+Note to OS X users:
+
+Make sure that you specify the architecture you wish to build for in the
+"ARCHS" flag. You can specify more than one by delimiting with a space
+(e.g. "x86_64 i386").
### Android
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
-AC_INIT([libuv], [0.11.17], [https://github.com/joyent/libuv/issues])
+AC_INIT([libuv], [0.11.18], [https://github.com/joyent/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
*/
UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
+enum uv_tcp_flags {
+ /* Used with uv_tcp_bind, when an IPv6 address is used */
+ UV_TCP_IPV6ONLY = 1
+};
+
/*
* Bind the handle to an address and port. `addr` should point to an
* initialized struct sockaddr_in or struct sockaddr_in6.
* That is, a successful call to uv_tcp_bind() does not guarantee that
* the call to uv_listen() or uv_tcp_connect() will succeed as well.
*/
-UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr);
-
+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,
CHECK(0 == uv_tcp_init(loop, &sx->tcp_handle));
what = "uv_tcp_bind";
- err = uv_tcp_bind(&sx->tcp_handle, &s.addr);
+ err = uv_tcp_bind(&sx->tcp_handle, &s.addr, 0);
if (err == 0) {
what = "uv_listen";
err = uv_listen((uv_stream_t *) &sx->tcp_handle, 128, on_connection);
/* skip "cpu<num> " marker */
{
- unsigned int n = num;
+ unsigned int n;
+ int r = sscanf(buf, "cpu%u ", &n);
+ assert(r == 1);
+ (void) r; // silence build warning
for (len = sizeof("cpu0"); n /= 10; len++);
- assert(sscanf(buf, "cpu%u ", &n) == 1 && n == num);
}
/* Line contains user, nice, system, idle, iowait, irq, softirq, steal,
ci[num++].cpu_times = ts;
}
fclose(fp);
+ assert(num == numcpus);
return 0;
}
uint64_t info[CPUSTATES];
char model[512];
int numcpus = 1;
- static int which[] = {CTL_HW,HW_MODEL,0};
+ int which[] = {CTL_HW,HW_MODEL,0};
size_t size;
int i;
uv_cpu_info_t* cpu_info;
close_fd = pipes[fd][0];
use_fd = pipes[fd][1];
- if (use_fd >= 0) {
- if (close_fd != -1)
- uv__close(close_fd);
- }
- else if (fd >= 3)
- continue;
- else {
- /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
- * set
- */
- use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
-
- if (use_fd == -1) {
+ if (use_fd < 0) {
+ if (fd >= 3)
+ continue;
+ else {
+ /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
+ * set
+ */
+ use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
+ close_fd = use_fd;
+
+ if (use_fd == -1) {
uv__write_int(error_fd, -errno);
- perror("failed to open stdio");
- _exit(127);
+ perror("failed to open stdio");
+ _exit(127);
+ }
}
}
if (fd == use_fd)
uv__cloexec(use_fd, 0);
- else {
+ else
dup2(use_fd, fd);
- uv__close(use_fd);
- }
if (fd <= 2)
uv__nonblock(fd, 0);
+
+ if (close_fd != -1)
+ uv__close(close_fd);
+ }
+
+ for (fd = 0; fd < stdio_count; fd++) {
+ use_fd = pipes[fd][1];
+
+ if (use_fd >= 0 && fd != use_fd)
+ close(use_fd);
}
if (options->cwd != NULL && chdir(options->cwd)) {
int uv__tcp_bind(uv_tcp_t* tcp,
const struct sockaddr* addr,
- unsigned int addrlen) {
+ unsigned int addrlen,
+ unsigned int flags) {
int err;
int on;
if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
return -errno;
+#ifdef IPV6_V6ONLY
+ if (addr->sa_family == AF_INET6) {
+ on = (flags & UV_TCP_IPV6ONLY) != 0;
+ if (setsockopt(tcp->io_watcher.fd,
+ IPPROTO_IPV6,
+ IPV6_V6ONLY,
+ &on,
+ sizeof on) == -1) {
+ return -errno;
+ }
+ }
+#endif
+
errno = 0;
if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE)
return -errno;
}
-int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr) {
+int uv_tcp_bind(uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int flags) {
unsigned int addrlen;
if (handle->type != UV_TCP)
else
return UV_EINVAL;
- return uv__tcp_bind(handle, addr, addrlen);
+ return uv__tcp_bind(handle, addr, addrlen, flags);
}
int uv__tcp_bind(uv_tcp_t* tcp,
const struct sockaddr* addr,
- unsigned int addrlen);
+ unsigned int addrlen,
+ unsigned int flags);
int uv__tcp_connect(uv_connect_t* req,
uv_tcp_t* handle,
#define UV_VERSION_MAJOR 0
#define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 17
+#define UV_VERSION_PATCH 18
#define UV_VERSION_IS_RELEASE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <crtdbg.h>
#include "uv.h"
#include "internal.h"
static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
+#ifdef _DEBUG
+/* Our crt debug report handler allows us to temporarily disable asserts */
+/* just for the current thread. */
+
+__declspec( thread ) int uv__crt_assert_enabled = TRUE;
+
+static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) {
+ if (uv__crt_assert_enabled || report_type != _CRT_ASSERT)
+ return FALSE;
+
+ if (ret_val) {
+ /* Set ret_val to 0 to continue with normal execution. */
+ /* Set ret_val to 1 to trigger a breakpoint. */
+
+ if(IsDebuggerPresent())
+ *ret_val = 1;
+ else
+ *ret_val = 0;
+ }
+
+ /* Don't call _CrtDbgReport. */
+ return TRUE;
+}
+#endif
+
+
static void uv__crt_invalid_parameter_handler(const wchar_t* expression,
const wchar_t* function, const wchar_t * file, unsigned int line,
uintptr_t reserved) {
_set_invalid_parameter_handler(uv__crt_invalid_parameter_handler);
#endif
+ /* We also need to setup our debug report handler because some CRT */
+ /* functions (eg _get_osfhandle) raise an assert when called with invalid */
+ /* FDs even though they return the proper error code in the release build. */
+#ifdef _DEBUG
+ _CrtSetReportHook(uv__crt_dbg_report_handler);
+#endif
+
/* Fetch winapi function pointers. This must be done first because other */
/* intialization code might need these function pointers to be loaded. */
uv_winapi_init();
#include "uv.h"
#include "internal.h"
#include "req-inl.h"
+#include "handle-inl.h"
#define UV_FS_FREE_PATHS 0x0002
VERIFY_FD(fd, req);
- handle = (HANDLE) _get_osfhandle(fd);
+ handle = uv__get_osfhandle(fd);
+
if (handle == INVALID_HANDLE_VALUE) {
- SET_REQ_RESULT(req, -1);
+ SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
return;
}
VERIFY_FD(fd, req);
- handle = (HANDLE) _get_osfhandle(fd);
+ handle = uv__get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE) {
- SET_REQ_RESULT(req, -1);
+ SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
return;
}
VERIFY_FD(fd, req);
- handle = (HANDLE) _get_osfhandle(fd);
+ handle = uv__get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
VERIFY_FD(fd, req);
- result = FlushFileBuffers((HANDLE) _get_osfhandle(fd)) ? 0 : -1;
+ result = FlushFileBuffers(uv__get_osfhandle(fd)) ? 0 : -1;
if (result == -1) {
SET_REQ_WIN32_ERROR(req, GetLastError());
} else {
VERIFY_FD(fd, req);
- handle = (HANDLE)_get_osfhandle(fd);
+ handle = uv__get_osfhandle(fd);
eof_info.EndOfFile.QuadPart = req->offset;
VERIFY_FD(fd, req);
- handle = (HANDLE) _get_osfhandle(fd);
+ handle = uv__get_osfhandle(fd);
nt_status = pNtQueryInformationFile(handle,
&io_status,
HANDLE handle;
VERIFY_FD(fd, req);
- handle = (HANDLE) _get_osfhandle(fd);
+ handle = uv__get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
#define UV_WIN_HANDLE_INL_H_
#include <assert.h>
+#include <io.h>
#include "uv.h"
#include "internal.h"
}
}
+INLINE static HANDLE uv__get_osfhandle(int fd)
+{
+ /* _get_osfhandle() raises an assert in debug builds if the FD is invalid. */
+ /* But it also correctly checks the FD and returns INVALID_HANDLE_VALUE */
+ /* for invalid FDs in release builds (or if you let the assert continue). */
+ /* So this wrapper function disables asserts when calling _get_osfhandle. */
+
+ HANDLE handle;
+ UV_BEGIN_DISABLE_CRT_ASSERT();
+ handle = (HANDLE) _get_osfhandle(fd);
+ UV_END_DISABLE_CRT_ASSERT();
+ return handle;
+}
+
#endif /* UV_WIN_HANDLE_INL_H_ */
return UV_UNKNOWN_HANDLE;
}
- handle = (HANDLE) _get_osfhandle(file);
+ handle = uv__get_osfhandle(file);
switch (GetFileType(handle)) {
case FILE_TYPE_CHAR:
# define INLINE inline
#endif
+
+#ifdef _DEBUG
+extern __declspec( thread ) int uv__crt_assert_enabled;
+
+#define UV_BEGIN_DISABLE_CRT_ASSERT() \
+ { \
+ int uv__saved_crt_assert_enabled = uv__crt_assert_enabled; \
+ uv__crt_assert_enabled = FALSE;
+
+
+#define UV_END_DISABLE_CRT_ASSERT() \
+ uv__crt_assert_enabled = uv__saved_crt_assert_enabled; \
+ }
+
+#else
+#define UV_BEGIN_DISABLE_CRT_ASSERT()
+#define UV_END_DISABLE_CRT_ASSERT()
+#endif
+
/*
* Handles
* (also see handle-inl.h)
int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
- HANDLE os_handle = (HANDLE)_get_osfhandle(file);
+ HANDLE os_handle = uv__get_osfhandle(file);
if (os_handle == INVALID_HANDLE_VALUE ||
uv_set_pipe_handle(pipe->loop, pipe, os_handle, 0) == -1) {
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
- return uv_poll_init_socket(loop, handle, (SOCKET) _get_osfhandle(fd));
+ return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd));
}
#include "uv.h"
#include "internal.h"
+#include "handle-inl.h"
/*
return ERROR_INVALID_HANDLE;
}
- handle = (HANDLE) _get_osfhandle(fd);
+ handle = uv__get_osfhandle(fd);
return uv__duplicate_handle(loop, handle, dup);
}
static int uv_tcp_try_bind(uv_tcp_t* handle,
const struct sockaddr* addr,
- unsigned int addrlen) {
+ unsigned int addrlen,
+ unsigned int flags) {
DWORD err;
int r;
}
}
+#ifdef IPV6_V6ONLY
+ if (addr->sa_family == AF_INET6) {
+ int on;
+
+ on = (flags & UV_TCP_IPV6ONLY) != 0;
+
+ /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
+ /* available, or when run on XP/2003 which have no support for dualstack */
+ /* sockets. For now we're silently ignoring the error. */
+ setsockopt(handle->socket, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof on);
+ }
+#endif
+
r = bind(handle->socket, addr, addrlen);
if (r == SOCKET_ERROR) {
if (!(handle->flags & UV_HANDLE_BOUND)) {
err = uv_tcp_try_bind(handle,
(const struct sockaddr*) &uv_addr_ip4_any_,
- sizeof(uv_addr_ip4_any_));
+ sizeof(uv_addr_ip4_any_),
+ 0);
if (err)
return err;
}
} else {
abort();
}
- err = uv_tcp_try_bind(handle, bind_addr, addrlen);
+ err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0);
if (err)
return err;
}
if (!(handle->flags & UV_HANDLE_BOUND)) {
return ERROR_INVALID_PARAMETER;
}
+
+ /* Report any deferred bind errors now. */
+ if (handle->flags & UV_HANDLE_BIND_ERROR) {
+ return handle->bind_error;
+ }
+
if (listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) {
return WSAGetLastError();
}
*/
int uv__tcp_bind(uv_tcp_t* handle,
const struct sockaddr* addr,
- unsigned int addrlen) {
+ unsigned int addrlen,
+ unsigned int flags) {
int err;
- err = uv_tcp_try_bind(handle, addr, addrlen);
+ err = uv_tcp_try_bind(handle, addr, addrlen, flags);
if (err)
return uv_translate_sys_error(err);
if (type == UV_TCP) {
ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &ctx.server_handle));
ASSERT(0 == uv_tcp_bind((uv_tcp_t*) &ctx.server_handle,
- (const struct sockaddr*) &listen_addr));
+ (const struct sockaddr*) &listen_addr,
+ 0));
}
else
ASSERT(0);
pinger->tcp.data = pinger;
- ASSERT(0 == uv_tcp_bind(&pinger->tcp, (const struct sockaddr*) &client_addr));
+ ASSERT(0 == uv_tcp_bind(&pinger->tcp,
+ (const struct sockaddr*) &client_addr,
+ 0));
r = uv_tcp_connect(&pinger->connect_req,
&pinger->tcp,
server = (uv_stream_t*)&tcpServer;
r = uv_tcp_init(loop, &tcpServer);
ASSERT(r == 0);
- r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &listen_addr);
+ r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &listen_addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&tcpServer, MAX_WRITE_HANDLES, connection_cb);
ASSERT(r == 0);
r = uv_tcp_init(loop, &tcp_server);
ASSERT(r == 0);
- r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&tcp_server, 128, connection_cb);
return 1;
}
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
if (r) {
/* TODO: Error codes */
fprintf(stderr, "Bind error\n");
return 1;
}
- r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0);
if (r) {
/* TODO: Error codes */
fprintf(stderr, "Bind error\n");
}
/* IPv6 is optional as not all platforms support it */
- r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr6);
+ r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr6, 0);
if (r) {
/* show message but return OK */
fprintf(stderr, "IPv6 not supported\n");
/* We are never doing multiple reads/connects at a time anyway. */
/* so these handles can be pre-initialized. */
- ASSERT(0 == uv_tcp_bind(&tcp, (const struct sockaddr*) &client_addr));
+ ASSERT(0 == uv_tcp_bind(&tcp, (const struct sockaddr*) &client_addr, 0));
r = uv_tcp_connect(&req,
&tcp,
r = uv_tcp_init(uv_default_loop(), server);
ASSERT(r == 0);
- r = uv_tcp_bind(server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)server, 128, connection_cb);
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
ASSERT(0 == uv_tcp_init(loop, &server_handle));
ASSERT(0 == uv_tcp_init(loop, &client_handle));
- ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr));
+ ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0));
ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 8, connection_cb));
/* Lower the file descriptor limit and use up all fds save one. */
return 1;
}
- r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0);
if (r) {
fprintf(stderr, "Bind error\n");
return 1;
r = uv_tcp_init(uv_default_loop(), &ctx.send.tcp);
ASSERT(r == 0);
- r = uv_tcp_bind(&ctx.send.tcp, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&ctx.send.tcp, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = run_test();
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_tcp_simultaneous_accepts(&server, 1);
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_tcp_simultaneous_accepts(&server, 0);
r = uv_tcp_init(uv_default_loop(), &tcp_server);
ASSERT(r == 0);
- r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
if (!listen_after_write) {
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
- r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&tcp_server, 12, ipc_on_connection_tcp_conn);
TEST_DECLARE (spawn_setuid_fails)
TEST_DECLARE (spawn_setgid_fails)
TEST_DECLARE (spawn_stdout_to_file)
+TEST_DECLARE (spawn_stdout_and_stderr_to_file)
TEST_DECLARE (spawn_auto_unref)
TEST_DECLARE (fs_poll)
TEST_DECLARE (kill)
TEST_ENTRY (spawn_setuid_fails)
TEST_ENTRY (spawn_setgid_fails)
TEST_ENTRY (spawn_stdout_to_file)
+ TEST_ENTRY (spawn_stdout_and_stderr_to_file)
TEST_ENTRY (spawn_auto_unref)
TEST_ENTRY (fs_poll)
TEST_ENTRY (kill)
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server, 128, connection_cb);
}
+TEST_IMPL(spawn_stdout_and_stderr_to_file) {
+ int r;
+ uv_file file;
+ uv_fs_t fs_req;
+ uv_stdio_container_t stdio[3];
+
+ /* Setup. */
+ unlink("stdout_file");
+
+ init_process_options("spawn_helper6", exit_cb);
+
+ r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR,
+ S_IREAD | S_IWRITE, NULL);
+ ASSERT(r != -1);
+ uv_fs_req_cleanup(&fs_req);
+
+ file = r;
+
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_INHERIT_FD;
+ options.stdio[1].data.fd = file;
+ options.stdio[2].flags = UV_INHERIT_FD;
+ options.stdio[2].data.fd = file;
+ options.stdio_count = 3;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output),
+ 0, NULL);
+ ASSERT(r == 27);
+ uv_fs_req_cleanup(&fs_req);
+
+ r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&fs_req);
+
+ printf("output is: %s", output);
+ ASSERT(strcmp("hello world\nhello errworld\n", output) == 0);
+
+ /* Cleanup. */
+ unlink("stdout_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(spawn_stdin) {
int r;
uv_pipe_t out;
}
+TEST_IMPL(spawn_same_stdout_stderr) {
+ uv_write_t write_req;
+ uv_pipe_t in, out;
+ uv_buf_t buf;
+ uv_stdio_container_t stdio[3];
+ int r;
+
+ init_process_options("spawn_helper3", exit_cb);
+ buf = uv_buf_init("TEST", 4);
+
+ uv_pipe_init(uv_default_loop(), &out, 0);
+ uv_pipe_init(uv_default_loop(), &in, 0);
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+ options.stdio[0].data.stream = (uv_stream_t*)∈
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
+ options.stdio_count = 2;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ /* Sending signum == 0 should check if the
+ * child process is still alive, not kill it.
+ */
+ r = uv_process_kill(&process, 0);
+ ASSERT(r == 0);
+
+ r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*)&out, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(strcmp(output, "TEST") == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(kill) {
int r;
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &server1);
ASSERT(r == 0);
- r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_tcp_init(uv_default_loop(), &server2);
ASSERT(r == 0);
- r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server1, 128, NULL);
ASSERT(r == 0);
/* It seems that Linux is broken here - bind succeeds. */
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0 || r == UV_EADDRNOTAVAIL);
uv_close((uv_handle_t*)&server, close_cb);
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == UV_EADDRNOTAVAIL);
uv_close((uv_handle_t*)&server, close_cb);
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);
ASSERT(r == UV_EINVAL);
uv_close((uv_handle_t*)&server, close_cb);
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);
ASSERT(r == UV_EINVAL);
uv_close((uv_handle_t*)&server, close_cb);
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
r = uv_tcp_init(uv_default_loop(), &server1);
ASSERT(r == 0);
- r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_tcp_init(uv_default_loop(), &server2);
ASSERT(r == 0);
- r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server1, 128, NULL);
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == UV_EADDRNOTAVAIL);
uv_close((uv_handle_t*)&server, close_cb);
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);
ASSERT(r == UV_EINVAL);
uv_close((uv_handle_t*)&server, close_cb);
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);
ASSERT(r == UV_EINVAL);
uv_close((uv_handle_t*)&server, close_cb);
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
- r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
ASSERT(0 == uv_tcp_init(loop, &tcp_server));
- ASSERT(0 == uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr));
+ ASSERT(0 == uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0));
ASSERT(0 == uv_listen((uv_stream_t*) &tcp_server,
ARRAY_SIZE(tcp_outgoing),
connection_cb));
r = uv_tcp_init(loop, handle);
ASSERT(r == 0);
- r = uv_tcp_bind(handle, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(handle, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)handle, 128, connection_cb);
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
ASSERT(0 == uv_tcp_init(uv_default_loop(), &server));
- ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr));
+ ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0));
ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb));
}
ASSERT(0 == uv_tcp_init(loop, &server_handle));
ASSERT(0 == uv_tcp_init(loop, &client_handle));
ASSERT(0 == uv_tcp_init(loop, &peer_handle));
- ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr));
+ ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0));
ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb));
ASSERT(0 == uv_tcp_connect(&connect_req,
&client_handle,
r = uv_tcp_init(loop, &tcp_server);
ASSERT(r == 0);
- r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr);
+ r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&tcp_server, 1, connection_cb);
sockaddr_in addr;
int err = uv_ip4_addr(*ip_address, port, &addr);
- if (err == 0)
- err = uv_tcp_bind(&wrap->handle_, reinterpret_cast<const sockaddr*>(&addr));
+ if (err == 0) {
+ err = uv_tcp_bind(&wrap->handle_,
+ reinterpret_cast<const sockaddr*>(&addr),
+ 0);
+ }
args.GetReturnValue().Set(err);
}
sockaddr_in6 addr;
int err = uv_ip6_addr(*ip6_address, port, &addr);
- if (err == 0)
- err = uv_tcp_bind(&wrap->handle_, reinterpret_cast<const sockaddr*>(&addr));
+ if (err == 0) {
+ err = uv_tcp_bind(&wrap->handle_,
+ reinterpret_cast<const sockaddr*>(&addr),
+ 0);
+ }
args.GetReturnValue().Set(err);
}