diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index bfffbbbac7..6f9b605f14 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -82,3 +82,4 @@ Brian Mazza Nils Maier Nicholas Vavilov Miroslav Bajtoš +Elliot Saba diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 257d05c041..3f1411d6c4 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,4 +1,33 @@ -2013.04.24, Version 0.10.5 (Stable) +2013.05.15, Version 0.10.6 (Stable) + +Changes since version 0.10.5: + +* stream: fix osx select hack (Fedor Indutny) + +* stream: fix small nit in select hack, add test (Fedor Indutny) + +* build: link with libkvm on openbsd (Ben Noordhuis) + +* stream: use harder sync restrictions for osx-hack (Fedor Indutny) + +* unix: fix EMFILE error handling (Ben Noordhuis) + +* darwin: fix unnecessary include headers (Daisuke Murase) + +* darwin: rename darwin-getproctitle.m (Ben Noordhuis) + +* build: convert predefined $PLATFORM to lower case (Elliot Saba) + +* build: set soname in shared library (Ben Noordhuis) + +* build: make `make test` link against .a again (Ben Noordhuis) + +* darwin: fix ios build, don't require ApplicationServices (Ben Noordhuis) + +* build: only set soname on shared object builds (Timothy J. Fontaine) + + +2013.04.24, Version 0.10.5 (Stable), 6595a7732c52eb4f8e57c88655f72997a8567a67 Changes since version 0.10.4: @@ -48,7 +77,7 @@ Changes since version 0.10.3: * build: -Wno-dollar-in-identifier-extension is clang only (Ben Noordhuis) -2013.02.04, Version 0.10.3 (Stable), 31ebe23973dd98fd8a24c042b606f37a794e99d0 +2013.03.28, Version 0.10.3 (Stable), 31ebe23973dd98fd8a24c042b606f37a794e99d0 Changes since version 0.10.2: diff --git a/deps/uv/build.mk b/deps/uv/build.mk index 1986e78240..5ff713e0f1 100644 --- a/deps/uv/build.mk +++ b/deps/uv/build.mk @@ -18,7 +18,11 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -PLATFORM ?= $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"') +ifdef PLATFORM +override PLATFORM := $(shell echo $(PLATFORM) | tr "[A-Z]" "[a-z]") +else +PLATFORM = $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"') +endif CPPFLAGS += -I$(SRCDIR)/include -I$(SRCDIR)/include/uv-private @@ -88,6 +92,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 \ @@ -139,10 +144,10 @@ TESTS= \ all: libuv.a -run-tests$(E): test/run-tests.o test/runner.o $(RUNNER_SRC) $(TESTS) libuv.$(SOEXT) +run-tests$(E): test/run-tests.o test/runner.o $(RUNNER_SRC) $(TESTS) libuv.a $(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o $@ $^ $(RUNNER_LIBS) $(RUNNER_LDFLAGS) -run-benchmarks$(E): test/run-benchmarks.o test/runner.o $(RUNNER_SRC) $(BENCHMARKS) libuv.$(SOEXT) +run-benchmarks$(E): test/run-benchmarks.o test/runner.o $(RUNNER_SRC) $(BENCHMARKS) libuv.a $(CC) $(CPPFLAGS) $(RUNNER_CFLAGS) -o $@ $^ $(RUNNER_LIBS) $(RUNNER_LDFLAGS) test/echo.o: test/echo.c test/echo.h diff --git a/deps/uv/config-unix.mk b/deps/uv/config-unix.mk index ae510a332d..347d9d7764 100644 --- a/deps/uv/config-unix.mk +++ b/deps/uv/config-unix.mk @@ -18,8 +18,6 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -OBJC ?= $(CC) - E= CSTDFLAG=--std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter CFLAGS += -g @@ -31,7 +29,7 @@ CPPFLAGS += -D_FILE_OFFSET_BITS=64 RUNNER_SRC=test/runner-unix.c RUNNER_CFLAGS=$(CFLAGS) -I$(SRCDIR)/test -RUNNER_LDFLAGS=-L"$(CURDIR)" -luv -Xlinker -rpath -Xlinker "$(CURDIR)" +RUNNER_LDFLAGS=-L"$(CURDIR)" -luv HAVE_DTRACE= DTRACE_OBJS= @@ -66,7 +64,6 @@ HAVE_DTRACE=1 CPPFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500 LDFLAGS+=-lkstat -lnsl -lsendfile -lsocket # Library dependencies are not transitive. -RUNNER_LDFLAGS += $(LDFLAGS) OBJS += src/unix/sunos.o OBJS += src/unix/dtrace.o DTRACE_OBJS += src/unix/core.o @@ -89,8 +86,7 @@ endif CPPFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 LDFLAGS += -framework Foundation \ -framework CoreServices \ - -framework ApplicationServices \ - -dynamiclib -install_name "@rpath/libuv.dylib" + -framework ApplicationServices SOEXT = dylib OBJS += src/unix/darwin.o OBJS += src/unix/kqueue.o @@ -153,12 +149,19 @@ CPPFLAGS += -Isrc/unix CFLAGS += -DHAVE_DTRACE endif +ifneq (darwin,$(PLATFORM)) +# Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR in src/version.c +SO_LDFLAGS = -Wl,-soname,libuv.so.0.10 +endif + +RUNNER_LDFLAGS += $(LDFLAGS) + libuv.a: $(OBJS) $(AR) rcs $@ $^ libuv.$(SOEXT): override CFLAGS += -fPIC libuv.$(SOEXT): $(OBJS:%.o=%.pic.o) - $(CC) -shared -o $@ $^ $(LDFLAGS) + $(CC) -shared -o $@ $^ $(LDFLAGS) $(SO_LDFLAGS) include/uv-private/uv-unix.h: \ include/uv-private/uv-bsd.h \ @@ -184,9 +187,6 @@ test/%.o: test/%.c include/uv.h test/.buildstamp clean-platform: $(RM) test/run-{tests,benchmarks}.dSYM $(OBJS) $(OBJS:%.o=%.pic.o) src/unix/uv-dtrace.h -%.pic.o %.o: %.m - $(OBJC) $(CPPFLAGS) $(CFLAGS) -c $^ -o $@ - src/unix/uv-dtrace.h: src/unix/uv-dtrace.d dtrace -h -xnolibs -s $< -o $@ diff --git a/deps/uv/src/unix/darwin-proctitle.m b/deps/uv/src/unix/darwin-proctitle.c similarity index 89% rename from deps/uv/src/unix/darwin-proctitle.m rename to deps/uv/src/unix/darwin-proctitle.c index d0ee95b498..c3171a6176 100644 --- a/deps/uv/src/unix/darwin-proctitle.m +++ b/deps/uv/src/unix/darwin-proctitle.c @@ -18,10 +18,18 @@ * IN THE SOFTWARE. */ -#include +#include + +#if !TARGET_OS_IPHONE +# include +# include +#endif int uv__set_process_title(const char* title) { +#if TARGET_OS_IPHONE + return -1; +#else typedef CFTypeRef (*LSGetCurrentApplicationASNType)(void); typedef OSStatus (*LSSetApplicationInformationItemType)(int, CFTypeRef, @@ -43,14 +51,14 @@ int uv__set_process_title(const char* title) { if (launch_services_bundle == NULL) return -1; - ls_get_current_application_asn = + ls_get_current_application_asn = (LSGetCurrentApplicationASNType) CFBundleGetFunctionPointerForName(launch_services_bundle, CFSTR("_LSGetCurrentApplicationASN")); if (ls_get_current_application_asn == NULL) return -1; - ls_set_application_information_item = + ls_set_application_information_item = (LSSetApplicationInformationItemType) CFBundleGetFunctionPointerForName(launch_services_bundle, CFSTR("_LSSetApplicationInformationItem")); @@ -75,4 +83,5 @@ int uv__set_process_title(const char* title) { NULL); return (err == noErr) ? 0 : -1; +#endif /* !TARGET_OS_IPHONE */ } diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index bc9d4f1bb7..fda2f02f57 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -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); @@ -493,50 +489,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)); + fd = uv__accept(uv__stream_fd(stream)); if (fd == -1) { - switch (errno) { -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - case EAGAIN: - return; /* Not an error. */ - - case ECONNABORTED: - UV_DEC_BACKLOG(w) - continue; /* Ignore. */ - - 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; - } - } + if (errno == EAGAIN || errno == EWOULDBLOCK) + return; /* Not an error. */ - /* Fall through. */ + if (errno == ECONNABORTED) + continue; /* Ignore. Nothing we can do about that. */ - 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); @@ -1357,11 +1335,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); diff --git a/deps/uv/src/version.c b/deps/uv/src/version.c index 3291d47eeb..75a5677b30 100644 --- a/deps/uv/src/version.c +++ b/deps/uv/src/version.c @@ -24,7 +24,9 @@ /* * Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI * stable. When the minor version is odd, the API can change between patch - * releases. + * releases. Make sure you update the -soname directives in config-unix.mk + * and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but + * not UV_VERSION_PATCH.) */ #undef UV_VERSION_MAJOR /* TODO(bnoordhuis) Remove in v0.11. */ @@ -32,7 +34,7 @@ #define UV_VERSION_MAJOR 0 #define UV_VERSION_MINOR 10 -#define UV_VERSION_PATCH 5 +#define UV_VERSION_PATCH 6 #define UV_VERSION_IS_RELEASE 1 diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c index eefb700835..b66df51b98 100644 --- a/deps/uv/test/runner-unix.c +++ b/deps/uv/test/runner-unix.c @@ -286,6 +286,34 @@ int process_copy_output(process_info_t *p, int fd) { } +/* Copy the last line of the stdio output buffer to `buffer` */ +int process_read_last_line(process_info_t *p, + char* buffer, + size_t buffer_len) { + char* ptr; + + int r = fseek(p->stdout_file, 0, SEEK_SET); + if (r < 0) { + perror("fseek"); + return -1; + } + + buffer[0] = '\0'; + + while (fgets(buffer, buffer_len, p->stdout_file) != NULL) { + for (ptr = buffer; *ptr && *ptr != '\r' && *ptr != '\n'; ptr++); + *ptr = '\0'; + } + + if (ferror(p->stdout_file)) { + perror("read"); + buffer[0] = '\0'; + return -1; + } + return 0; +} + + /* Return the name that was specified when `p` was started by process_start */ char* process_get_name(process_info_t *p) { return p->name; diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c index 3aae1c3e9c..5d23259437 100644 --- a/deps/uv/test/runner-win.c +++ b/deps/uv/test/runner-win.c @@ -248,6 +248,46 @@ int process_copy_output(process_info_t *p, int fd) { } +int process_read_last_line(process_info_t *p, + char * buffer, + size_t buffer_len) { + DWORD size; + DWORD read; + DWORD start; + OVERLAPPED overlapped; + + ASSERT(buffer_len > 0); + + size = GetFileSize(p->stdio_out, NULL); + if (size == INVALID_FILE_SIZE) + return -1; + + if (size == 0) { + buffer[0] = '\0'; + return 1; + } + + memset(&overlapped, 0, sizeof overlapped); + if (size >= buffer_len) + overlapped.Offset = size - buffer_len - 1; + + if (!ReadFile(p->stdio_out, buffer, buffer_len - 1, &read, &overlapped)) + return -1; + + for (start = read - 1; start >= 0; start--) { + if (buffer[start] == '\n' || buffer[start] == '\r') + break; + } + + if (start > 0) + memmove(buffer, buffer + start, read - start); + + buffer[read - start] = '\0'; + + return 0; +} + + char* process_get_name(process_info_t *p) { return p->name; } diff --git a/deps/uv/test/runner.c b/deps/uv/test/runner.c index bda1080a18..d8e9ddeb01 100644 --- a/deps/uv/test/runner.c +++ b/deps/uv/test/runner.c @@ -31,12 +31,25 @@ char executable_path[PATHMAX] = { '\0' }; int tap_output = 0; -static void log_progress(int total, int passed, int failed, const char* name) { +static void log_progress(int total, + int passed, + int failed, + int todos, + int skipped, + const char* name) { + int progress; + if (total == 0) total = 1; - LOGF("[%% %3d|+ %3d|- %3d]: %s", (int) ((passed + failed) / ((double) total) * 100.0), - passed, failed, name); + progress = 100 * (passed + failed + skipped + todos) / total; + LOGF("[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s", + progress, + passed, + failed, + todos, + skipped, + name); } @@ -78,7 +91,13 @@ const char* fmt(double d) { int run_tests(int timeout, int benchmark_output) { - int total, passed, failed, current; + int total; + int passed; + int failed; + int todos; + int skipped; + int current; + int test_result; task_entry_t* task; /* Count the number of tests. */ @@ -96,6 +115,8 @@ int run_tests(int timeout, int benchmark_output) { /* Run all tests. */ passed = 0; failed = 0; + todos = 0; + skipped = 0; current = 1; for (task = TASKS; task->main; task++) { if (task->is_helper) { @@ -106,13 +127,15 @@ int run_tests(int timeout, int benchmark_output) { rewind_cursor(); if (!benchmark_output && !tap_output) { - log_progress(total, passed, failed, task->task_name); + log_progress(total, passed, failed, todos, skipped, task->task_name); } - if (run_test(task->task_name, timeout, benchmark_output, current) == 0) { - passed++; - } else { - failed++; + test_result = run_test(task->task_name, timeout, benchmark_output, current); + switch (test_result) { + case TEST_OK: passed++; break; + case TEST_TODO: todos++; break; + case TEST_SKIP: skipped++; break; + default: failed++; } current++; } @@ -121,13 +144,50 @@ int run_tests(int timeout, int benchmark_output) { rewind_cursor(); if (!benchmark_output && !tap_output) { - log_progress(total, passed, failed, "Done.\n"); + log_progress(total, passed, failed, todos, skipped, "Done.\n"); } return failed; } +void log_tap_result(int test_count, + const char* test, + int status, + process_info_t* process) { + const char* result; + const char* directive; + char reason[1024]; + + switch (status) { + case TEST_OK: + result = "ok"; + directive = ""; + break; + case TEST_TODO: + result = "not ok"; + directive = " # TODO "; + break; + case TEST_SKIP: + result = "ok"; + directive = " # SKIP "; + break; + default: + result = "not ok"; + directive = ""; + } + + if ((status == TEST_SKIP || status == TEST_TODO) && + process_output_size(process) > 0) { + process_read_last_line(process, reason, sizeof reason); + } else { + reason[0] = '\0'; + } + + LOGF("%s %d - %s%s%s\n", result, test_count, test, directive, reason); +} + + int run_test(const char* test, int timeout, int benchmark_output, @@ -231,7 +291,7 @@ int run_test(const char* test, } status = process_reap(main_proc); - if (status != 0) { + if (status != TEST_OK) { snprintf(errmsg, sizeof errmsg, "exit code %d", @@ -255,17 +315,17 @@ 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); - } + if (tap_output) + log_tap_result(test_count, test, status, &processes[i]); /* Show error and output from processes if the test failed. */ if (status != 0 || task->show_output) { if (tap_output) { LOGF("#"); + } else if (status == TEST_TODO) { + LOGF("\n`%s` todo\n", test); + } else if (status == TEST_SKIP) { + LOGF("\n`%s` skipped\n", test); } else if (status != 0) { LOGF("\n`%s` failed: %s\n", test, errmsg); } else { diff --git a/deps/uv/test/runner.h b/deps/uv/test/runner.h index 8be9e39fcc..aa7f205407 100644 --- a/deps/uv/test/runner.h +++ b/deps/uv/test/runner.h @@ -143,6 +143,11 @@ long int process_output_size(process_info_t *p); /* Copy the contents of the stdio output buffer to `fd`. */ int process_copy_output(process_info_t *p, int fd); +/* Copy the last line of the stdio output buffer to `buffer` */ +int process_read_last_line(process_info_t *p, + char * buffer, + size_t buffer_len); + /* Return the name that was specified when `p` was started by process_start */ char* process_get_name(process_info_t *p); diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index de7c80ec3a..308201e579 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -119,4 +119,28 @@ void uv_sleep(int msec); /* Format big numbers nicely. WARNING: leaks memory. */ const char* fmt(double d); +/* Reserved test exit codes. */ +enum test_status { + TEST_OK = 0, + TEST_TODO, + TEST_SKIP +}; + +#define RETURN_OK() \ + do { \ + return TEST_OK; \ + } while (0) + +#define RETURN_TODO(explanation) \ + do { \ + LOGF("%s\n", explanation); \ + return TEST_TODO; \ + } while (0) + +#define RETURN_SKIP(explanation) \ + do { \ + LOGF("%s\n", explanation); \ + return TEST_SKIP; \ + } while (0) + #endif /* TASK_H_ */ diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 016f627110..4c0158589e 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -220,6 +220,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) @@ -440,6 +443,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) diff --git a/deps/uv/test/test-osx-select.c b/deps/uv/test/test-osx-select.c new file mode 100644 index 0000000000..5c2cbd4d93 --- /dev/null +++ b/deps/uv/test/test-osx-select.c @@ -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 +#include + +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__ */ diff --git a/deps/uv/test/test-process-title.c b/deps/uv/test/test-process-title.c index 13d9dddfc4..c870abd150 100644 --- a/deps/uv/test/test-process-title.c +++ b/deps/uv/test/test-process-title.c @@ -42,8 +42,12 @@ static void set_title(const char* title) { TEST_IMPL(process_title) { +#if defined(__sun) + RETURN_SKIP("uv_(get|set)_process_title is not implemented."); +#else /* Check for format string vulnerabilities. */ - set_title("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); + set_title("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); set_title("new title"); return 0; +#endif } diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c index eb5d5df526..f3003efa6a 100644 --- a/deps/uv/test/test-tty.c +++ b/deps/uv/test/test-tty.c @@ -30,6 +30,9 @@ # include #endif +#include +#include + TEST_IMPL(tty) { int r, width, height; @@ -62,7 +65,12 @@ TEST_IMPL(tty) { #else /* unix */ ttyin_fd = open("/dev/tty", O_RDONLY, 0); + if (ttyin_fd < 0) + LOGF("Cannot open /dev/tty as read-only: %s\n", strerror(errno)); + ttyout_fd = open("/dev/tty", O_WRONLY, 0); + if (ttyout_fd < 0) + LOGF("Cannot open /dev/tty as write-only: %s\n", strerror(errno)); #endif ASSERT(ttyin_fd >= 0); diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 7824819a9b..54c771ee3d 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -164,9 +164,16 @@ ], }, 'conditions': [ - ['"<(library)" == "shared_library"', { + ['library=="shared_library"', { 'cflags': [ '-fPIC' ], }], + ['library=="shared_library" and OS!="mac"', { + 'link_settings': { + # Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR + # in src/version.c + 'libraries': [ '-Wl,-soname,libuv.so.0.10' ], + }, + }], ], }], [ 'OS=="linux" or OS=="mac"', { @@ -176,7 +183,7 @@ 'sources': [ 'src/unix/darwin.c', 'src/unix/fsevents.c', - 'src/unix/darwin-proctitle.m', + 'src/unix/darwin-proctitle.c', ], 'link_settings': { 'libraries': [ @@ -235,21 +242,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()', { @@ -309,6 +311,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',