mirror of
https://github.com/libuv/libuv
synced 2025-03-28 21:13:16 +00:00
Merge remote-tracking branch 'origin/v0.10'
Conflicts: ChangeLog src/version.c
This commit is contained in:
commit
ebdeaed2e3
1
AUTHORS
1
AUTHORS
@ -84,3 +84,4 @@ 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>
|
||||
|
73
ChangeLog
73
ChangeLog
@ -1,39 +1,16 @@
|
||||
2013.04.11, Version 0.11.1 (Unstable), 5c10e82ae0bc99eff86d4b9baff1f1aa0bf84c0a
|
||||
2013.04.24, Version 0.10.5 (Stable), 6595a7732c52eb4f8e57c88655f72997a8567a67
|
||||
|
||||
This is the first versioned release from the current unstable libuv branch.
|
||||
Changes since version 0.10.4:
|
||||
|
||||
Changes since Node.js v0.11.0:
|
||||
* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis)
|
||||
|
||||
* all platforms: nanosecond resolution support for uv_fs_[fl]stat (Timothy J.
|
||||
Fontaine)
|
||||
* windows: make timers handle large timeouts (Miroslav Bajtoš)
|
||||
|
||||
* all platforms: add netmask to uv_interface_address (Ben Kelly)
|
||||
* windows: remove superfluous assert statement (Bert Belder)
|
||||
|
||||
* unix: make sure the `status` parameter passed to the `uv_getaddrinfo` is 0 or
|
||||
-1 (Ben Noordhuis)
|
||||
* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis)
|
||||
|
||||
* unix: limit the number of iovecs written in a single `writev` syscall to
|
||||
IOV_MAX (Fedor Indutny)
|
||||
|
||||
* unix: add dtrace probes for tick-start and tick-stop (Timothy J. Fontaine)
|
||||
|
||||
* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier)
|
||||
|
||||
* windows: fix memory leak in fs__sendfile (Shannen Saez)
|
||||
|
||||
* windows: fix edge case bugs in uv_cpu_info (Bert Belder)
|
||||
|
||||
* include: no longer ship with / include ngx-queue.h (Ben Noordhuis)
|
||||
|
||||
* include: remove UV_VERSION_* macros from uv.h (Ben Noordhuis)
|
||||
|
||||
* documentation updates (Kristian Evensen, Ben Kelly, Ben Noordhuis)
|
||||
|
||||
* build: fix dtrace-enabled builds (Ben Noordhuis, Timothy J. Fontaine)
|
||||
|
||||
* build: gyp disable thin archives (Timothy J. Fontaine)
|
||||
|
||||
* build: add support for Visual Studio 2012 (Nicholas Vavilov)
|
||||
* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis)
|
||||
|
||||
|
||||
2013.04.12, Version 0.10.4 (Stable), 85827e26403ac6dfa331af8ec9916ea7e27bd833
|
||||
@ -71,6 +48,42 @@ Changes since version 0.10.3:
|
||||
* build: -Wno-dollar-in-identifier-extension is clang only (Ben Noordhuis)
|
||||
|
||||
|
||||
2013.04.11, Version 0.11.1 (Unstable), 5c10e82ae0bc99eff86d4b9baff1f1aa0bf84c0a
|
||||
|
||||
This is the first versioned release from the current unstable libuv branch.
|
||||
|
||||
Changes since Node.js v0.11.0:
|
||||
|
||||
* all platforms: nanosecond resolution support for uv_fs_[fl]stat (Timothy J.
|
||||
Fontaine)
|
||||
|
||||
* all platforms: add netmask to uv_interface_address (Ben Kelly)
|
||||
|
||||
* unix: make sure the `status` parameter passed to the `uv_getaddrinfo` is 0 or
|
||||
-1 (Ben Noordhuis)
|
||||
|
||||
* unix: limit the number of iovecs written in a single `writev` syscall to
|
||||
IOV_MAX (Fedor Indutny)
|
||||
|
||||
* unix: add dtrace probes for tick-start and tick-stop (Timothy J. Fontaine)
|
||||
|
||||
* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier)
|
||||
|
||||
* windows: fix memory leak in fs__sendfile (Shannen Saez)
|
||||
|
||||
* windows: fix edge case bugs in uv_cpu_info (Bert Belder)
|
||||
|
||||
* include: no longer ship with / include ngx-queue.h (Ben Noordhuis)
|
||||
|
||||
* include: remove UV_VERSION_* macros from uv.h (Ben Noordhuis)
|
||||
|
||||
* documentation updates (Kristian Evensen, Ben Kelly, Ben Noordhuis)
|
||||
|
||||
* build: fix dtrace-enabled builds (Ben Noordhuis, Timothy J. Fontaine)
|
||||
|
||||
* build: gyp disable thin archives (Timothy J. Fontaine)
|
||||
|
||||
* build: add support for Visual Studio 2012 (Nicholas Vavilov)
|
||||
2013.02.04, Version 0.10.3 (Stable), 31ebe23973dd98fd8a24c042b606f37a794e99d0
|
||||
|
||||
Changes since version 0.10.2:
|
||||
|
1
build.mk
1
build.mk
@ -88,6 +88,7 @@ TESTS= \
|
||||
test/test-loop-stop.o \
|
||||
test/test-multiple-listen.o \
|
||||
test/test-mutexes.o \
|
||||
test/test-osx-select.o \
|
||||
test/test-pass-always.o \
|
||||
test/test-ping-pong.o \
|
||||
test/test-pipe-bind-error.o \
|
||||
|
@ -71,10 +71,8 @@ STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->base) ==
|
||||
sizeof(((struct iovec*) 0)->iov_base));
|
||||
STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->len) ==
|
||||
sizeof(((struct iovec*) 0)->iov_len));
|
||||
STATIC_ASSERT((uintptr_t) &((uv_buf_t*) 0)->base ==
|
||||
(uintptr_t) &((struct iovec*) 0)->iov_base);
|
||||
STATIC_ASSERT((uintptr_t) &((uv_buf_t*) 0)->len ==
|
||||
(uintptr_t) &((struct iovec*) 0)->iov_len);
|
||||
STATIC_ASSERT(offsetof(uv_buf_t, base) == offsetof(struct iovec, iov_base));
|
||||
STATIC_ASSERT(offsetof(uv_buf_t, len) == offsetof(struct iovec, iov_len));
|
||||
|
||||
|
||||
uint64_t uv_hrtime(void) {
|
||||
|
@ -284,98 +284,59 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uv_err_t uv_resident_set_memory(size_t* rss) {
|
||||
FILE* f;
|
||||
int itmp;
|
||||
char ctmp;
|
||||
unsigned int utmp;
|
||||
size_t page_size = getpagesize();
|
||||
char *cbuf;
|
||||
int foundExeEnd;
|
||||
char buf[PATH_MAX + 1];
|
||||
char buf[1024];
|
||||
const char* s;
|
||||
ssize_t n;
|
||||
long val;
|
||||
int fd;
|
||||
int i;
|
||||
|
||||
f = fopen("/proc/self/stat", "r");
|
||||
if (!f) return uv__new_sys_error(errno);
|
||||
do
|
||||
fd = open("/proc/self/stat", O_RDONLY);
|
||||
while (fd == -1 && errno == EINTR);
|
||||
|
||||
/* PID */
|
||||
if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Exec file */
|
||||
cbuf = buf;
|
||||
foundExeEnd = 0;
|
||||
if (fscanf (f, "%c", cbuf++) == 0) goto error;
|
||||
while (1) {
|
||||
if (fscanf(f, "%c", cbuf) == 0) goto error;
|
||||
if (*cbuf == ')') {
|
||||
foundExeEnd = 1;
|
||||
} else if (foundExeEnd && *cbuf == ' ') {
|
||||
*cbuf = 0;
|
||||
break;
|
||||
}
|
||||
if (fd == -1)
|
||||
return uv__new_sys_error(errno);
|
||||
|
||||
cbuf++;
|
||||
do
|
||||
n = read(fd, buf, sizeof(buf) - 1);
|
||||
while (n == -1 && errno == EINTR);
|
||||
|
||||
SAVE_ERRNO(close(fd));
|
||||
if (n == -1)
|
||||
return uv__new_sys_error(errno);
|
||||
buf[n] = '\0';
|
||||
|
||||
s = strchr(buf, ' ');
|
||||
if (s == NULL)
|
||||
goto err;
|
||||
|
||||
s += 1;
|
||||
if (*s != '(')
|
||||
goto err;
|
||||
|
||||
s = strchr(s, ')');
|
||||
if (s == NULL)
|
||||
goto err;
|
||||
|
||||
for (i = 1; i <= 22; i++) {
|
||||
s = strchr(s + 1, ' ');
|
||||
if (s == NULL)
|
||||
goto err;
|
||||
}
|
||||
/* State */
|
||||
if (fscanf (f, "%c ", &ctmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Parent process */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Process group */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Session id */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* TTY */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* TTY owner process group */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Flags */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Minor faults (no memory page) */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Minor faults, children */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Major faults (memory page faults) */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Major faults, children */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* utime */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* stime */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* utime, children */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* stime, children */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* jiffies remaining in current time slice */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* 'nice' value */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* jiffies until next timeout */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* jiffies until next SIGALRM */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* start time (jiffies since system boot) */
|
||||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
|
||||
/* Virtual memory size */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
errno = 0;
|
||||
val = strtol(s, NULL, 10);
|
||||
if (errno != 0)
|
||||
goto err;
|
||||
if (val < 0)
|
||||
goto err;
|
||||
|
||||
/* Resident set size */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
*rss = (size_t) utmp * page_size;
|
||||
|
||||
/* rlim */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Start of text */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* End of text */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
/* Start of stack */
|
||||
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
|
||||
|
||||
fclose (f);
|
||||
*rss = val * getpagesize();
|
||||
return uv_ok_;
|
||||
|
||||
error:
|
||||
fclose (f);
|
||||
return uv__new_sys_error(errno);
|
||||
err:
|
||||
return uv__new_artificial_error(UV_EINVAL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,8 +46,8 @@ typedef struct uv__stream_select_s uv__stream_select_t;
|
||||
struct uv__stream_select_s {
|
||||
uv_stream_t* stream;
|
||||
uv_thread_t thread;
|
||||
uv_sem_t sem;
|
||||
uv_mutex_t mutex;
|
||||
uv_sem_t close_sem;
|
||||
uv_sem_t async_sem;
|
||||
uv_async_t async;
|
||||
int events;
|
||||
int fake_fd;
|
||||
@ -139,7 +139,7 @@ static void uv__stream_osx_select(void* arg) {
|
||||
|
||||
stream = arg;
|
||||
s = stream->select;
|
||||
fd = stream->io_watcher.fd;
|
||||
fd = s->fd;
|
||||
|
||||
if (fd > s->int_fd)
|
||||
max_fd = fd;
|
||||
@ -148,7 +148,7 @@ static void uv__stream_osx_select(void* arg) {
|
||||
|
||||
while (1) {
|
||||
/* Terminate on semaphore */
|
||||
if (uv_sem_trywait(&s->sem) == 0)
|
||||
if (uv_sem_trywait(&s->close_sem) == 0)
|
||||
break;
|
||||
|
||||
/* Watch fd using select(2) */
|
||||
@ -202,12 +202,16 @@ static void uv__stream_osx_select(void* arg) {
|
||||
if (FD_ISSET(fd, &swrite))
|
||||
events |= UV__POLLOUT;
|
||||
|
||||
uv_mutex_lock(&s->mutex);
|
||||
s->events |= events;
|
||||
uv_mutex_unlock(&s->mutex);
|
||||
assert(events != 0 || FD_ISSET(s->int_fd, &sread));
|
||||
if (events != 0) {
|
||||
ACCESS_ONCE(int, s->events) = events;
|
||||
|
||||
if (events != 0)
|
||||
uv_async_send(&s->async);
|
||||
uv_sem_wait(&s->async_sem);
|
||||
|
||||
/* Should be processed at this stage */
|
||||
assert((s->events == 0) || (stream->flags & UV_CLOSING));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,10 +244,9 @@ static void uv__stream_osx_select_cb(uv_async_t* handle, int status) {
|
||||
stream = s->stream;
|
||||
|
||||
/* Get and reset stream's events */
|
||||
uv_mutex_lock(&s->mutex);
|
||||
events = s->events;
|
||||
s->events = 0;
|
||||
uv_mutex_unlock(&s->mutex);
|
||||
ACCESS_ONCE(int, s->events) = 0;
|
||||
uv_sem_post(&s->async_sem);
|
||||
|
||||
assert(events != 0);
|
||||
assert(events == (events & (UV__POLLIN | UV__POLLOUT)));
|
||||
@ -305,6 +308,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
||||
if (s == NULL)
|
||||
return uv__set_artificial_error(stream->loop, UV_ENOMEM);
|
||||
|
||||
s->events = 0;
|
||||
s->fd = *fd;
|
||||
|
||||
if (uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb)) {
|
||||
@ -315,10 +319,10 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
||||
s->async.flags |= UV__HANDLE_INTERNAL;
|
||||
uv__handle_unref(&s->async);
|
||||
|
||||
if (uv_sem_init(&s->sem, 0))
|
||||
if (uv_sem_init(&s->close_sem, 0))
|
||||
goto fatal1;
|
||||
|
||||
if (uv_mutex_init(&s->mutex))
|
||||
if (uv_sem_init(&s->async_sem, 0))
|
||||
goto fatal2;
|
||||
|
||||
/* Create fds for io watcher and to interrupt the select() loop. */
|
||||
@ -343,9 +347,9 @@ fatal4:
|
||||
s->fake_fd = -1;
|
||||
s->int_fd = -1;
|
||||
fatal3:
|
||||
uv_mutex_destroy(&s->mutex);
|
||||
uv_sem_destroy(&s->async_sem);
|
||||
fatal2:
|
||||
uv_sem_destroy(&s->sem);
|
||||
uv_sem_destroy(&s->close_sem);
|
||||
fatal1:
|
||||
uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
|
||||
return uv__set_sys_error(stream->loop, errno);
|
||||
@ -437,7 +441,6 @@ void uv__stream_destroy(uv_stream_t* stream) {
|
||||
*/
|
||||
static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
|
||||
int fd;
|
||||
int r;
|
||||
|
||||
if (loop->emfile_fd == -1)
|
||||
return -1;
|
||||
@ -455,14 +458,8 @@ static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
r = 0;
|
||||
else
|
||||
r = -1;
|
||||
|
||||
loop->emfile_fd = uv__open_cloexec("/", O_RDONLY);
|
||||
|
||||
return r;
|
||||
SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
@ -475,10 +472,9 @@ static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
|
||||
|
||||
|
||||
void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
static int use_emfile_trick = -1;
|
||||
uv_stream_t* stream;
|
||||
int err;
|
||||
int fd;
|
||||
int r;
|
||||
|
||||
stream = container_of(w, uv_stream_t, io_watcher);
|
||||
assert(events == UV__POLLIN);
|
||||
@ -492,50 +488,32 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
*/
|
||||
while (uv__stream_fd(stream) != -1) {
|
||||
assert(stream->accepted_fd == -1);
|
||||
|
||||
#if defined(UV_HAVE_KQUEUE)
|
||||
if (w->rcount <= 0)
|
||||
return;
|
||||
#endif /* defined(UV_HAVE_KQUEUE) */
|
||||
|
||||
fd = uv__accept(uv__stream_fd(stream));
|
||||
|
||||
if (fd == -1) {
|
||||
switch (errno) {
|
||||
#if EWOULDBLOCK != EAGAIN
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
case EAGAIN:
|
||||
return; /* Not an error. */
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
return; /* Not an error. */
|
||||
|
||||
case ECONNABORTED:
|
||||
UV_DEC_BACKLOG(w)
|
||||
continue; /* Ignore. */
|
||||
if (errno == ECONNABORTED)
|
||||
continue; /* Ignore. Nothing we can do about that. */
|
||||
|
||||
case EMFILE:
|
||||
case ENFILE:
|
||||
if (use_emfile_trick == -1) {
|
||||
const char* val = getenv("UV_ACCEPT_EMFILE_TRICK");
|
||||
use_emfile_trick = (val == NULL || atoi(val) != 0);
|
||||
}
|
||||
|
||||
if (use_emfile_trick) {
|
||||
SAVE_ERRNO(r = uv__emfile_trick(loop, uv__stream_fd(stream)));
|
||||
if (r == 0) {
|
||||
UV_DEC_BACKLOG(w)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall through. */
|
||||
|
||||
default:
|
||||
uv__set_sys_error(loop, errno);
|
||||
stream->connection_cb(stream, -1);
|
||||
continue;
|
||||
if (errno == EMFILE || errno == ENFILE) {
|
||||
SAVE_ERRNO(err = uv__emfile_trick(loop, uv__stream_fd(stream)));
|
||||
if (err == EAGAIN || err == EWOULDBLOCK)
|
||||
break;
|
||||
}
|
||||
|
||||
uv__set_sys_error(loop, errno);
|
||||
stream->connection_cb(stream, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
UV_DEC_BACKLOG(w)
|
||||
|
||||
stream->accepted_fd = fd;
|
||||
stream->connection_cb(stream, 0);
|
||||
|
||||
@ -1356,11 +1334,12 @@ void uv__stream_close(uv_stream_t* handle) {
|
||||
|
||||
s = handle->select;
|
||||
|
||||
uv_sem_post(&s->sem);
|
||||
uv_sem_post(&s->close_sem);
|
||||
uv_sem_post(&s->async_sem);
|
||||
uv__stream_osx_interrupt_select(handle);
|
||||
uv_thread_join(&s->thread);
|
||||
uv_sem_destroy(&s->sem);
|
||||
uv_mutex_destroy(&s->mutex);
|
||||
uv_sem_destroy(&s->close_sem);
|
||||
uv_sem_destroy(&s->async_sem);
|
||||
close(s->fake_fd);
|
||||
close(s->int_fd);
|
||||
uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
|
||||
|
@ -222,6 +222,9 @@ TEST_DECLARE (we_get_signal)
|
||||
TEST_DECLARE (we_get_signals)
|
||||
TEST_DECLARE (signal_multiple_loops)
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
TEST_DECLARE (osx_select)
|
||||
#endif
|
||||
HELPER_DECLARE (tcp4_echo_server)
|
||||
HELPER_DECLARE (tcp6_echo_server)
|
||||
HELPER_DECLARE (udp4_echo_server)
|
||||
@ -444,6 +447,10 @@ TASK_LIST_START
|
||||
TEST_ENTRY (signal_multiple_loops)
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
TEST_ENTRY (osx_select)
|
||||
#endif
|
||||
|
||||
TEST_ENTRY (fs_file_noent)
|
||||
TEST_ENTRY (fs_file_nametoolong)
|
||||
TEST_ENTRY (fs_file_loop)
|
||||
|
82
test/test-osx-select.c
Normal file
82
test/test-osx-select.c
Normal file
@ -0,0 +1,82 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
|
||||
static int read_count;
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) {
|
||||
static char buf[1024];
|
||||
|
||||
return uv_buf_init(buf, ARRAY_SIZE(buf));
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
|
||||
fprintf(stdout, "got data %d\n", ++read_count);
|
||||
|
||||
if (read_count == 3)
|
||||
uv_close((uv_handle_t*) stream, NULL);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(osx_select) {
|
||||
int r;
|
||||
int fd;
|
||||
size_t i;
|
||||
size_t len;
|
||||
const char* str;
|
||||
uv_tty_t tty;
|
||||
|
||||
fd = open("/dev/tty", O_RDONLY);
|
||||
|
||||
ASSERT(fd >= 0);
|
||||
|
||||
r = uv_tty_init(uv_default_loop(), &tty, fd, 1);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb);
|
||||
|
||||
// Emulate user-input
|
||||
str = "got some input\n"
|
||||
"with a couple of lines\n"
|
||||
"feel pretty happy\n";
|
||||
for (i = 0, len = strlen(str); i < len; i++) {
|
||||
r = ioctl(fd, TIOCSTI, str + i);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT(read_count == 3);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __APPLE__ */
|
12
uv.gyp
12
uv.gyp
@ -236,21 +236,16 @@
|
||||
}],
|
||||
[ 'OS=="freebsd" or OS=="dragonflybsd"', {
|
||||
'sources': [ 'src/unix/freebsd.c' ],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-lkvm',
|
||||
],
|
||||
},
|
||||
}],
|
||||
[ 'OS=="openbsd"', {
|
||||
'sources': [ 'src/unix/openbsd.c' ],
|
||||
}],
|
||||
[ 'OS=="netbsd"', {
|
||||
'sources': [ 'src/unix/netbsd.c' ],
|
||||
}],
|
||||
[ 'OS in "freebsd dragonflybsd openbsd netbsd".split()', {
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-lkvm',
|
||||
],
|
||||
'libraries': [ '-lkvm' ],
|
||||
},
|
||||
}],
|
||||
[ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', {
|
||||
@ -310,6 +305,7 @@
|
||||
'test/test-loop-stop.c',
|
||||
'test/test-walk-handles.c',
|
||||
'test/test-multiple-listen.c',
|
||||
'test/test-osx-select.c',
|
||||
'test/test-pass-always.c',
|
||||
'test/test-ping-pong.c',
|
||||
'test/test-pipe-bind-error.c',
|
||||
|
Loading…
x
Reference in New Issue
Block a user