Compare commits

...

22 Commits
v1.x ... v0.8

Author SHA1 Message Date
Ben Noordhuis
0865a6f228 windows: use WSAGetLastError(), not errno
setsockopt() doesn't touch errno on failure. Use WSAGetLastError()
instead.

This is a back-port of commit 30a8b44 from the master branch.
2013-06-26 01:09:04 +02:00
Bert Belder
399c3ef55c windows: uv_spawn shouldn't reject reparse points
This fixes an issue where uv_spawn would not try to run a reparse point,
and continue to scan the PATH instead. Effectively, it was impossible to
spawn a symlinked binary. This commit fixes that.

Also see #748

This is a backport of 495d1a0 to the v0.8 branch.
2013-06-19 00:17:25 +02:00
isaacs
1258d9e3ef win: map ERROR_INVALID_FUNCTION to EISDIR
This error is raised when calling read() or write() on a directory.

A bit of googling turns up some cases where this error can be raised
that are not properly mapped to EISDIR, but are also cases that libuv
doesn't really care about, like the Password Manager API,
GetFirmwareEnvironmentVariable, or CreateTapePartition.

If libuv ever needs to handle these cases, then I suppose that the
ERROR_INVALID_FUNCTION->EISDIR mapping could be done directly in the
fs read() and write() functions, but doing so at this point seems
premature, as it makes the error code mapping a bit more messy.

Fixes joyent/node#4951
2013-03-08 12:57:20 +01:00
Bert Belder
36d19dde8c win/tty: fix typo in color attributes enumeration 2013-03-08 12:57:01 +01:00
Bert Belder
83626b6bc2 win/tty: don't touch insert mode or quick edit mode
This is a back-port of 4abad23, whichi is supposed to fix
joyent/node#4809.

The private `original_console_mode` field in the uv_tty_t struct has
been renamed, but couldn't be removed because changing the ABI isn't
allowed on stable branches.
2013-03-08 12:56:32 +01:00
Bert Belder
b77139964b win/tty: fix case where uv_read_start incorrectly reports failure
In very rare circumstances a uv_read_start() call on a uv_tty_t handle
in raw mode would return -1 but there was no actual failure. This patch
fixes that.
2013-03-08 12:45:11 +01:00
Bert Belder
aebc0f2242 windows: link with advapi32 and shell32 libraries
Older versions of GYP would set up the Visual Studio project to link
with these libraries by default, but this was changed in r1584 (see
https://codereview.chromium.org/12256017).

Closes #728
2013-03-08 12:45:02 +01:00
Timothy J Fontaine
95577a8699 test: fix tap output even when ok but have output
This is a back-port of commit 49d2ae3 from the master branch.
2013-03-05 15:40:02 +01:00
Ben Noordhuis
99065bb235 test: fix tap output check
Only report as an error when status != 0.

Stops the platform_output test from being reported as having failed
on Jenkins.

This is a back-port of commit 1821bba from the master branch.
2013-03-05 15:39:40 +01:00
Ben Noordhuis
b0c5e62035 linux: make uv_cpu_info() handle absent procfs
Return an error when reading from /proc files fails because the procfs
isn't mounted.

This is a back-port of commit 7e59f9b from the master branch.
2013-03-05 15:29:17 +01:00
Timothy J Fontaine
23b93474b1 test: don't rewind_cursor when using tap_output
This is a back-port of commit 72bbf5d from the master branch.
2013-02-26 02:04:25 +01:00
Timothy J Fontaine
5d57f42ed3 test: add tap output
Given UV_TAP_OUTPUT being set, test result output should use TAP formatting

This is a back-port of commit bfe269b from the master branch.

Conflicts:
	test/runner-unix.c
2013-02-26 02:03:26 +01:00
Ben Noordhuis
86ae8b3c63 unix: handle EINPROGRESS for unix sockets
Before this commit, it was assumed that connect() on UNIX sockets never
returns EINPROGRESS. It turned out to be a bad assumption: Dave Pacheco
reports sporadic hangups on SmartOS because of that.

It's not clear to me _why_ the Illumos kernel returns that error but
that's inconsequential: whatever the cause, libuv needs to handle it
and now it does.

This is a back-port of commit 3348cd7 from the master branch.

Fixes joyent/node#4785.

Conflicts:
	src/unix/pipe.c
2013-02-21 23:27:15 +01:00
Ben Noordhuis
1ba01fddda build: handle bad gcc -dumpversion output
`gcc -dumpversion` usually prints major.minor - but on sunos it prints
major.minor.patch.
2013-02-21 23:27:15 +01:00
Bert Belder
034ea318af win: get rid of early ipv6 support detection
No longer explictly check wheter an IPv6 stack is present when the user
tries to use IPV6 sockets. Instead realy on the operating system
to report the lack of protocol support via appropriate error messages.
2013-01-30 19:09:58 +01:00
Bert Belder
36883f29ea win/udp: fix bug in getsockopt() return value check 2013-01-30 19:09:57 +01:00
Bert Belder
6b1cca3975 win/udp: make uv_udp_set_socket set UV_HANDLE_IPV6
This patch makes uv_udp_set_socket responsible for setting the
UV_HANDLE_IPV6 flag.

In addition, this patch fixes some minor style issues.
2013-01-30 19:09:57 +01:00
Bert Belder
c45564ac8a win/tcp: make uv_tcp_set_socket set UV_HANDLE_IPV6
This makes uv_tcp_set_socket responsible for setting the UV_HANDLE_IPV6
flag. This fixes a couple of situations where the the fact that a socket
is an IPv6 socket is not taken into account when deciding whether a call
to SetFileCompletionNotificationModes is appropriate.
2013-01-30 19:09:56 +01:00
Bert Belder
3382a923f5 win: fix uv_winsock_init crash when no IPv4 stack present
uv_winsock_init() tries to create an IPv4 socket in order to detect
if the system has any layered service providers (LSPs) installed.
When creating this socket failed it would call uv_fatal_error and exit
with the following message:

  socket: (10047) An address incompatible with the requested protocol was used.

This patch fixes that. It also includes some minor style tweaks.
2013-01-30 19:09:56 +01:00
Bert Belder
f0844ee760 win: add error mappings related to unsupported protocols 2013-01-30 19:09:55 +01:00
Bert Belder
d27d1e5078 win: sort error code mappings 2013-01-30 19:09:36 +01:00
Bert Belder
4c5c5d9aea windows: map ERROR_DIRECTORY to UV_ENOENT 2013-01-30 19:06:10 +01:00
17 changed files with 253 additions and 188 deletions

4
gyp_uv
View File

@ -22,7 +22,9 @@ def compiler_version():
proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE)
is_clang = 'clang' in proc.communicate()[0].split('\n')[0]
proc = subprocess.Popen(CC.split() + ['-dumpversion'], stdout=subprocess.PIPE)
version = tuple(map(int, proc.communicate()[0].split('.')))
version = proc.communicate()[0].split('.')
version = map(int, version[:2])
version = tuple(version)
return (version, is_clang)

View File

@ -383,7 +383,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
HANDLE read_line_handle; \
uv_buf_t read_line_buffer; \
HANDLE read_raw_wait; \
DWORD original_console_mode; \
DWORD dummy_original_console_mode; \
/* Fields used for translating win */ \
/* keystrokes into vt100 characters */ \
char last_key[8]; \

View File

@ -64,9 +64,9 @@ static struct {
size_t len;
} process_title;
static void read_models(unsigned int numcpus, uv_cpu_info_t* ci);
static int read_models(unsigned int numcpus, uv_cpu_info_t* ci);
static int read_times(unsigned int numcpus, uv_cpu_info_t* ci);
static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
static void read_times(unsigned int numcpus, uv_cpu_info_t* ci);
static unsigned long read_cpufreq(unsigned int cpunum);
@ -325,10 +325,19 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
if (ci == NULL)
return uv__new_sys_error(ENOMEM);
read_models(numcpus, ci);
read_times(numcpus, ci);
if (read_models(numcpus, ci)) {
SAVE_ERRNO(free(ci));
return uv__new_sys_error(errno);
}
/* read_models() on x86 also reads the CPU speed from /proc/cpuinfo */
if (read_times(numcpus, ci)) {
SAVE_ERRNO(free(ci));
return uv__new_sys_error(errno);
}
/* read_models() on x86 also reads the CPU speed from /proc/cpuinfo.
* We don't check for errors here. Worst case, the field is left zero.
*/
if (ci[0].speed == 0)
read_speeds(numcpus, ci);
@ -350,7 +359,7 @@ static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) {
/* Also reads the CPU frequency on x86. The other architectures only have
* a BogoMIPS field, which may not be very accurate.
*/
static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
#if defined(__i386__) || defined(__x86_64__)
static const char model_marker[] = "model name\t: ";
static const char speed_marker[] = "cpu MHz\t\t: ";
@ -373,7 +382,7 @@ static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
fp = fopen("/proc/cpuinfo", "r");
if (fp == NULL)
return;
return -1;
model_idx = 0;
speed_idx = 0;
@ -398,10 +407,12 @@ static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
}
}
fclose(fp);
return 0;
}
static void read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
unsigned long clock_ticks;
struct uv_cpu_times_s ts;
unsigned long user;
@ -421,7 +432,7 @@ static void read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
fp = fopen("/proc/stat", "r");
if (fp == NULL)
return;
return -1;
if (!fgets(buf, sizeof(buf), fp))
abort();
@ -466,6 +477,8 @@ static void read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
ci[num++].cpu_times = ts;
}
fclose(fp);
return 0;
}

View File

@ -186,15 +186,13 @@ void uv_pipe_connect(uv_connect_t* req,
uv_strlcpy(saddr.sun_path, name, sizeof(saddr.sun_path));
saddr.sun_family = AF_UNIX;
/* We don't check for EINPROGRESS. Think about it: the socket
* is either there or not.
*/
do {
r = connect(handle->fd, (struct sockaddr*)&saddr, sizeof saddr);
}
while (r == -1 && errno == EINTR);
if (r == -1)
if (errno != EINPROGRESS)
goto out;
if (new_sock)
@ -216,7 +214,8 @@ out:
req->cb = cb;
ngx_queue_init(&req->queue);
/* Run callback on next tick. */
/* Force callback to run on next tick in case of error. */
if (err != 0)
uv__io_feed(handle->loop, &handle->write_watcher, UV__IO_WRITE);
/* Mimic the Windows pipe implementation, always

View File

@ -66,6 +66,41 @@ void uv_fatal_error(const int errorno, const char* syscall) {
uv_err_code uv_translate_sys_error(int sys_errno) {
switch (sys_errno) {
case ERROR_SUCCESS: return UV_OK;
case ERROR_NOACCESS: return UV_EACCES;
case WSAEACCES: return UV_EACCES;
case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
case WSAEADDRINUSE: return UV_EADDRINUSE;
case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT;
case WSAEWOULDBLOCK: return UV_EAGAIN;
case WSAEALREADY: return UV_EALREADY;
case ERROR_INVALID_FLAGS: return UV_EBADF;
case ERROR_INVALID_HANDLE: return UV_EBADF;
case ERROR_LOCK_VIOLATION: return UV_EBUSY;
case ERROR_PIPE_BUSY: return UV_EBUSY;
case ERROR_SHARING_VIOLATION: return UV_EBUSY;
case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED;
case WSAECONNABORTED: return UV_ECONNABORTED;
case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED;
case WSAECONNREFUSED: return UV_ECONNREFUSED;
case ERROR_NETNAME_DELETED: return UV_ECONNRESET;
case WSAECONNRESET: return UV_ECONNRESET;
case ERROR_ALREADY_EXISTS: return UV_EEXIST;
case ERROR_FILE_EXISTS: return UV_EEXIST;
case ERROR_BUFFER_OVERFLOW: return UV_EFAULT;
case WSAEFAULT: return UV_EFAULT;
case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH;
case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
case ERROR_OPERATION_ABORTED: return UV_EINTR;
case WSAEINTR: return UV_EINTR;
case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
case ERROR_INVALID_DATA: return UV_EINVAL;
case ERROR_INVALID_PARAMETER: return UV_EINVAL;
case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
case WSAEINVAL: return UV_EINVAL;
case WSAEPFNOSUPPORT: return UV_EINVAL;
case WSAESOCKTNOSUPPORT: return UV_EINVAL;
case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
case ERROR_BUS_RESET: return UV_EIO;
case ERROR_CRC: return UV_EIO;
@ -82,41 +117,6 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ERROR_OPEN_FAILED: return UV_EIO;
case ERROR_SETMARK_DETECTED: return UV_EIO;
case ERROR_SIGNAL_REFUSED: return UV_EIO;
case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
case ERROR_INVALID_NAME: return UV_ENOENT;
case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT;
case ERROR_MOD_NOT_FOUND: return UV_ENOENT;
case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
case WSANO_DATA: return UV_ENOENT;
case ERROR_ACCESS_DENIED: return UV_EPERM;
case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM;
case ERROR_NOACCESS: return UV_EACCES;
case WSAEACCES: return UV_EACCES;
case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
case WSAEADDRINUSE: return UV_EADDRINUSE;
case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT;
case WSAEWOULDBLOCK: return UV_EAGAIN;
case WSAEALREADY: return UV_EALREADY;
case ERROR_LOCK_VIOLATION: return UV_EBUSY;
case ERROR_SHARING_VIOLATION: return UV_EBUSY;
case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED;
case WSAECONNABORTED: return UV_ECONNABORTED;
case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED;
case WSAECONNREFUSED: return UV_ECONNREFUSED;
case ERROR_NETNAME_DELETED: return UV_ECONNRESET;
case WSAECONNRESET: return UV_ECONNRESET;
case ERROR_ALREADY_EXISTS: return UV_EEXIST;
case ERROR_FILE_EXISTS: return UV_EEXIST;
case ERROR_BUFFER_OVERFLOW: return UV_EFAULT;
case WSAEFAULT: return UV_EFAULT;
case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH;
case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
case ERROR_OPERATION_ABORTED: return UV_EINTR;
case WSAEINTR: return UV_EINTR;
case ERROR_INVALID_DATA: return UV_EINVAL;
case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
case WSAEINVAL: return UV_EINVAL;
case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP;
case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE;
case WSAEMFILE: return UV_EMFILE;
@ -125,6 +125,14 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
case WSAENETUNREACH: return UV_ENETUNREACH;
case WSAENOBUFS: return UV_ENOBUFS;
case ERROR_DIRECTORY: return UV_ENOENT;
case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
case ERROR_INVALID_NAME: return UV_ENOENT;
case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT;
case ERROR_MOD_NOT_FOUND: return UV_ENOENT;
case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
case WSAHOST_NOT_FOUND: return UV_ENOENT;
case WSANO_DATA: return UV_ENOENT;
case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM;
case ERROR_OUTOFMEMORY: return UV_ENOMEM;
case ERROR_CANNOT_MAKE: return UV_ENOSPC;
@ -132,27 +140,24 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ERROR_EA_TABLE_FULL: return UV_ENOSPC;
case ERROR_END_OF_MEDIA: return UV_ENOSPC;
case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC;
case ERROR_WRITE_PROTECT: return UV_EROFS;
case ERROR_NOT_CONNECTED: return UV_ENOTCONN;
case WSAENOTCONN: return UV_ENOTCONN;
case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY;
case WSAENOTSOCK: return UV_ENOTSOCK;
case ERROR_NOT_SUPPORTED: return UV_ENOTSUP;
case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
case ERROR_INVALID_FLAGS: return UV_EBADF;
case ERROR_INVALID_HANDLE: return UV_EBADF;
case ERROR_INVALID_PARAMETER: return UV_EINVAL;
case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
case ERROR_BROKEN_PIPE: return UV_EOF;
case ERROR_ACCESS_DENIED: return UV_EPERM;
case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM;
case ERROR_BAD_PIPE: return UV_EPIPE;
case ERROR_NO_DATA: return UV_EPIPE;
case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE;
case WSAESHUTDOWN: return UV_EPIPE;
case ERROR_PIPE_BUSY: return UV_EBUSY;
case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT;
case ERROR_WRITE_PROTECT: return UV_EROFS;
case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT;
case WSAETIMEDOUT: return UV_ETIMEDOUT;
case WSAHOST_NOT_FOUND: return UV_ENOENT;
case WSAENOTSOCK: return UV_ENOTSOCK;
case ERROR_NOT_SAME_DEVICE: return UV_EXDEV;
case ERROR_INVALID_FUNCTION: return UV_EISDIR;
default: return UV_UNKNOWN;
}
}

View File

@ -323,9 +323,6 @@ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
OVERLAPPED* overlapped);
/* Whether ipv6 is supported */
extern int uv_allow_ipv6;
/* Whether there are any non-IFS LSPs stacked on TCP */
extern int uv_tcp_non_ifs_lsp_ipv4;
extern int uv_tcp_non_ifs_lsp_ipv6;

View File

@ -166,7 +166,7 @@ static wchar_t* search_path_join_test(const wchar_t* dir,
attrs = GetFileAttributesW(result);
if (attrs != INVALID_FILE_ATTRIBUTES &&
!(attrs & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))) {
!(attrs & FILE_ATTRIBUTE_DIRECTORY)) {
return result;
}

View File

@ -50,7 +50,7 @@ static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
TCP_NODELAY,
(const char*)&enable,
sizeof enable) == -1) {
uv__set_sys_error(handle->loop, errno);
uv__set_sys_error(handle->loop, WSAGetLastError());
return -1;
}
return 0;
@ -63,7 +63,7 @@ static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsign
SO_KEEPALIVE,
(const char*)&enable,
sizeof enable) == -1) {
uv__set_sys_error(handle->loop, errno);
uv__set_sys_error(handle->loop, WSAGetLastError());
return -1;
}
@ -72,7 +72,7 @@ static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsign
TCP_KEEPALIVE,
(const char*)&delay,
sizeof delay) == -1) {
uv__set_sys_error(handle->loop, errno);
uv__set_sys_error(handle->loop, WSAGetLastError());
return -1;
}
@ -81,7 +81,7 @@ static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsign
static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
SOCKET socket, int imported) {
SOCKET socket, int family, int imported) {
DWORD yes = 1;
int non_ifs_lsp;
@ -107,8 +107,11 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
}
}
non_ifs_lsp = (handle->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
uv_tcp_non_ifs_lsp_ipv4;
if (family == AF_INET6) {
non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6;
} else {
non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4;
}
if (pSetFileCompletionNotificationModes && !non_ifs_lsp) {
if (pSetFileCompletionNotificationModes((HANDLE) socket,
@ -134,6 +137,12 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
handle->socket = socket;
if (family == AF_INET6) {
handle->flags |= UV_HANDLE_IPV6;
} else {
assert(!(handle->flags & UV_HANDLE_IPV6));
}
return 0;
}
@ -238,14 +247,14 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
static int uv__bind(uv_tcp_t* handle,
int domain,
int family,
struct sockaddr* addr,
int addrsize) {
DWORD err;
int r;
if (handle->socket == INVALID_SOCKET) {
SOCKET sock = socket(domain, SOCK_STREAM, 0);
SOCKET sock = socket(family, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
uv__set_sys_error(handle->loop, WSAGetLastError());
return -1;
@ -258,7 +267,7 @@ static int uv__bind(uv_tcp_t* handle,
return -1;
}
if (uv_tcp_set_socket(handle->loop, handle, sock, 0) == -1) {
if (uv_tcp_set_socket(handle->loop, handle, sock, family, 0) < 0) {
closesocket(sock);
return -1;
}
@ -293,17 +302,10 @@ int uv__tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
if (uv_allow_ipv6) {
handle->flags |= UV_HANDLE_IPV6;
return uv__bind(handle,
AF_INET6,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in6));
} else {
uv__set_sys_error(handle->loop, WSAEAFNOSUPPORT);
return -1;
}
}
@ -592,6 +594,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
uv_loop_t* loop = server->loop;
int rv = 0;
int family;
uv_tcp_accept_t* req = server->pending_accepts;
@ -606,7 +609,17 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
return -1;
}
if (uv_tcp_set_socket(client->loop, client, req->accept_socket, 0) == -1) {
if (server->flags & UV_HANDLE_IPV6) {
family = AF_INET6;
} else {
family = AF_INET;
}
if (uv_tcp_set_socket(client->loop,
client,
req->accept_socket,
family,
0) < 0) {
closesocket(req->accept_socket);
rv = -1;
} else {
@ -756,11 +769,6 @@ int uv__tcp_connect6(uv_connect_t* req,
BOOL success;
DWORD bytes;
if (!uv_allow_ipv6) {
uv__set_sys_error(loop, WSAEAFNOSUPPORT);
return -1;
}
if (handle->flags & UV_HANDLE_BIND_ERROR) {
uv__set_sys_error(loop, handle->bind_error);
return -1;
@ -1181,7 +1189,11 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
return -1;
}
if (uv_tcp_set_socket(tcp->loop, tcp, socket, 1) != 0) {
if (uv_tcp_set_socket(tcp->loop,
tcp,
socket,
socket_protocol_info->iAddressFamily,
1) < 0) {
closesocket(socket);
return -1;
}
@ -1193,10 +1205,6 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
tcp->flags |= UV_HANDLE_BOUND;
tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
if (socket_protocol_info->iAddressFamily == AF_INET6) {
tcp->flags |= UV_HANDLE_IPV6;
}
tcp->loop->active_tcp_streams++;
return 0;
}

View File

@ -100,11 +100,6 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
return -1;
}
if (!GetConsoleMode(win_handle, &tty->original_console_mode)) {
uv__set_sys_error(loop, GetLastError());
return -1;
}
/* Initialize virtual window size; if it fails, assume that this is stdin. */
if (GetConsoleScreenBufferInfo(win_handle, &info)) {
EnterCriticalSection(&uv_tty_output_lock);
@ -143,7 +138,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
int uv_tty_set_mode(uv_tty_t* tty, int mode) {
DWORD flags = 0;
DWORD flags;
unsigned char was_reading;
uv_alloc_cb alloc_cb;
uv_read_cb read_cb;
@ -152,17 +147,12 @@ int uv_tty_set_mode(uv_tty_t* tty, int mode) {
return 0;
}
if (tty->original_console_mode & ENABLE_QUICK_EDIT_MODE) {
flags = ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS;
}
if (mode) {
/* Raw input */
flags |= ENABLE_WINDOW_INPUT;
flags = ENABLE_WINDOW_INPUT;
} else {
/* Line-buffered mode. */
flags |= ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT |
ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT;
flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
}
if (!SetConsoleMode(tty->handle, flags)) {
@ -758,7 +748,7 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
if (handle->last_key_len > 0) {
SET_REQ_SUCCESS(&handle->read_req);
uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req);
return -1;
return 0;
}
uv_tty_queue_read(loop, handle);
@ -913,7 +903,7 @@ static int uv_tty_move_caret(uv_tty_t* handle, int x, unsigned char x_relative,
static int uv_tty_reset(uv_tty_t* handle, DWORD* error) {
const COORD origin = {0, 0};
const WORD char_attrs = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_RED;
const WORD char_attrs = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
CONSOLE_SCREEN_BUFFER_INFO info;
DWORD count, written;

View File

@ -56,8 +56,8 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
}
static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
SOCKET socket) {
static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
int family) {
DWORD yes = 1;
WSAPROTOCOL_INFOW info;
int opt_len;
@ -93,7 +93,7 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
/* if the user is using the default UDP driver (AFD) and has no other */
/* LSPs stacked on top. Here we check whether that is the case. */
opt_len = (int) sizeof info;
if (!getsockopt(socket,
if (getsockopt(socket,
SOL_SOCKET,
SO_PROTOCOL_INFOW,
(char*) &info,
@ -118,6 +118,12 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
handle->socket = socket;
if (family == AF_INET6) {
handle->flags |= UV_HANDLE_IPV6;
} else {
assert(!(handle->flags & UV_HANDLE_IPV6));
}
return 0;
}
@ -164,33 +170,36 @@ void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
static int uv__bind(uv_udp_t* handle,
int domain,
int family,
struct sockaddr* addr,
int addrsize,
unsigned int flags) {
int r;
DWORD no = 0, yes = 1;
if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
if ((flags & UV_UDP_IPV6ONLY) && family != AF_INET6) {
/* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
uv__set_artificial_error(handle->loop, UV_EINVAL);
return -1;
}
if (handle->socket == INVALID_SOCKET) {
SOCKET sock = socket(domain, SOCK_DGRAM, 0);
SOCKET sock = socket(family, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) {
uv__set_sys_error(handle->loop, WSAGetLastError());
return -1;
}
if (uv_udp_set_socket(handle->loop, handle, sock) == -1) {
if (uv_udp_set_socket(handle->loop, handle, sock, family) < 0) {
closesocket(sock);
return -1;
}
if (family == AF_INET6)
handle->flags |= UV_HANDLE_IPV6;
}
if (domain == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
if (family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
/* On windows IPV6ONLY is on by default. */
/* If the user doesn't specify it libuv turns it off. */
@ -238,17 +247,11 @@ int uv__udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
unsigned int flags) {
if (uv_allow_ipv6) {
handle->flags |= UV_HANDLE_IPV6;
return uv__bind(handle,
AF_INET6,
(struct sockaddr*) &addr,
sizeof(struct sockaddr_in6),
flags);
} else {
uv__set_sys_error(handle->loop, WSAEAFNOSUPPORT);
return -1;
}
}

View File

@ -25,9 +25,6 @@
#include "internal.h"
/* Whether ipv6 is supported */
int uv_allow_ipv6;
/* Whether there are any non-IFS LSPs stacked on TCP */
int uv_tcp_non_ifs_lsp_ipv4;
int uv_tcp_non_ifs_lsp_ipv6;
@ -75,6 +72,12 @@ BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) {
}
static int error_means_no_support(DWORD error) {
return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT ||
error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT;
}
void uv_winsock_init() {
const GUID wsaid_connectex = WSAID_CONNECTEX;
const GUID wsaid_acceptex = WSAID_ACCEPTEX;
@ -100,48 +103,48 @@ void uv_winsock_init() {
/* Detect non-IFS LSPs */
dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (dummy == INVALID_SOCKET) {
uv_fatal_error(WSAGetLastError(), "socket");
}
if (dummy != INVALID_SOCKET) {
opt_len = (int) sizeof protocol_info;
if (!getsockopt(dummy,
SOL_SOCKET,
SO_PROTOCOL_INFOW,
(char*) &protocol_info,
&opt_len) == SOCKET_ERROR) {
uv_fatal_error(WSAGetLastError(), "socket");
}
&opt_len) == SOCKET_ERROR)
uv_fatal_error(WSAGetLastError(), "getsockopt");
if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) {
if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
uv_tcp_non_ifs_lsp_ipv4 = 1;
}
if (closesocket(dummy) == SOCKET_ERROR) {
if (closesocket(dummy) == SOCKET_ERROR)
uv_fatal_error(WSAGetLastError(), "closesocket");
} else if (!error_means_no_support(WSAGetLastError())) {
/* Any error other than "socket type not supported" is fatal. */
uv_fatal_error(WSAGetLastError(), "socket");
}
/* Detect IPV6 support and non-IFS LSPs */
dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
if (dummy != INVALID_SOCKET) {
uv_allow_ipv6 = TRUE;
if (dummy != INVALID_SOCKET) {
opt_len = (int) sizeof protocol_info;
if (!getsockopt(dummy,
SOL_SOCKET,
SO_PROTOCOL_INFOW,
(char*) &protocol_info,
&opt_len) == SOCKET_ERROR) {
uv_fatal_error(WSAGetLastError(), "socket");
}
&opt_len) == SOCKET_ERROR)
uv_fatal_error(WSAGetLastError(), "getsockopt");
if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) {
if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
uv_tcp_non_ifs_lsp_ipv6 = 1;
}
if (closesocket(dummy) == SOCKET_ERROR) {
if (closesocket(dummy) == SOCKET_ERROR)
uv_fatal_error(WSAGetLastError(), "closesocket");
}
} else if (!error_means_no_support(WSAGetLastError())) {
/* Any error other than "socket type not supported" is fatal. */
uv_fatal_error(WSAGetLastError(), "socket");
}
}

View File

@ -60,5 +60,5 @@ static int maybe_run_test(int argc, char **argv) {
return 42;
}
return run_test(argv[1], BENCHMARK_TIMEOUT, 1);
return run_test(argv[1], BENCHMARK_TIMEOUT, 1, 1);
}

View File

@ -147,5 +147,5 @@ static int maybe_run_test(int argc, char **argv) {
return 1;
}
return run_test(argv[1], TEST_TIMEOUT, 0);
return run_test(argv[1], TEST_TIMEOUT, 0, 1);
}

View File

@ -40,6 +40,10 @@
/* Do platform-specific initialization. */
void platform_init(int argc, char **argv) {
const char* tap = getenv("UV_TAP_OUTPUT");
tap_output = (tap != NULL && atoi(tap) > 0);
/* Disable stdio output buffering. */
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
@ -227,19 +231,26 @@ int process_copy_output(process_info_t *p, int fd) {
return -1;
}
ssize_t nread, nwritten;
ssize_t nwritten;
char buf[1024];
while ((nread = read(fileno(p->stdout_file), buf, 1024)) > 0) {
nwritten = write(fd, buf, nread);
/* TODO: what if the line is longer than buf */
while (fgets(buf, sizeof(buf), p->stdout_file) != NULL) {
/* TODO: what if write doesn't write the whole buffer... */
nwritten = 0;
if (tap_output)
nwritten += write(fd, "#", 1);
nwritten += write(fd, buf, strlen(buf));
if (nwritten < 0) {
perror("write");
return -1;
}
}
if (nread < 0) {
if (ferror(p->stdout_file)) {
perror("read");
return -1;
}

View File

@ -27,6 +27,8 @@
char executable_path[PATHMAX] = { '\0' };
int tap_output = 0;
static void log_progress(int total, int passed, int failed, const char* name) {
if (total == 0)
@ -38,7 +40,7 @@ static void log_progress(int total, int passed, int failed, const char* name) {
int run_tests(int timeout, int benchmark_output) {
int total, passed, failed;
int total, passed, failed, current;
task_entry_t* task;
/* Count the number of tests. */
@ -49,29 +51,38 @@ int run_tests(int timeout, int benchmark_output) {
}
}
if (tap_output) {
LOGF("1..%d\n", total);
}
/* Run all tests. */
passed = 0;
failed = 0;
current = 1;
for (task = TASKS; task->main; task++) {
if (task->is_helper) {
continue;
}
if (!tap_output)
rewind_cursor();
if (!benchmark_output) {
if (!benchmark_output && !tap_output) {
log_progress(total, passed, failed, task->task_name);
}
if (run_test(task->task_name, timeout, benchmark_output) == 0) {
if (run_test(task->task_name, timeout, benchmark_output, current) == 0) {
passed++;
} else {
failed++;
}
current++;
}
if (!tap_output)
rewind_cursor();
if (!benchmark_output) {
if (!benchmark_output && !tap_output) {
log_progress(total, passed, failed, "Done.\n");
}
@ -79,7 +90,10 @@ int run_tests(int timeout, int benchmark_output) {
}
int run_test(const char* test, int timeout, int benchmark_output) {
int run_test(const char* test,
int timeout,
int benchmark_output,
int test_count) {
char errmsg[1024] = "no error";
process_info_t processes[1024];
process_info_t *main_proc;
@ -201,9 +215,18 @@ out:
FATAL("process_wait failed");
}
if (tap_output) {
if (status == 0)
LOGF("ok %d - %s\n", test_count, test);
else
LOGF("not ok %d - %s\n", test_count, test);
}
/* Show error and output from processes if the test failed. */
if (status != 0 || task->show_output) {
if (status != 0) {
if (tap_output) {
LOGF("#");
} else if (status != 0) {
LOGF("\n`%s` failed: %s\n", test, errmsg);
} else {
LOGF("\n");
@ -227,7 +250,10 @@ out:
break;
}
}
if (!tap_output) {
LOG("=============================================================\n");
}
/* In benchmark mode show concise output from the main process. */
} else if (benchmark_output) {

View File

@ -102,7 +102,10 @@ int run_tests(int timeout, int benchmark_output);
/*
* Run a single test. Starts up any helpers.
*/
int run_test(const char* test, int timeout, int benchmark_output);
int run_test(const char* test,
int timeout,
int benchmark_output,
int test_count);
/*
* Run a test part, i.e. the test or one of its helpers.
@ -156,4 +159,7 @@ void process_cleanup(process_info_t *p);
/* Move the console cursor one line up and back to the first column. */
void rewind_cursor();
/* trigger output as tap */
extern int tap_output;
#endif /* RUNNER_H_ */

6
uv.gyp
View File

@ -160,9 +160,11 @@
],
'link_settings': {
'libraries': [
'-lws2_32.lib',
'-ladvapi32.lib',
'-liphlpapi.lib',
'-lpsapi.lib',
'-liphlpapi.lib'
'-lshell32.lib',
'-lws2_32.lib'
],
},
}, { # Not Windows i.e. POSIX