Merge branch 'v0.6'

Conflicts:
	src/unix/core.c
	src/win/winapi.h
This commit is contained in:
Ben Noordhuis 2011-12-02 18:15:04 +01:00
commit f5c2a4a1ae
34 changed files with 304 additions and 81 deletions

View File

@ -9,3 +9,4 @@ Isaac Z. Schlueter <i@izs.me>
Saúl Ibarra Corretgé <saghul@gmail.com>
Yuki OKUMURA <mjt@cltn.org>
Frank Denis <github@pureftpd.org>
Ryan Emery <seebees@gmail.com>

View File

@ -33,3 +33,6 @@ Roman Shtylman <shtylman@gmail.com>
Frank Denis <github@pureftpd.org>
Carter Allen <CarterA@opt-6.com>
Tj Holowaychuk <tj@vision-media.ca>
Shimon Doodkin <helpmepro1@gmail.com>
Ryan Emery <seebees@gmail.com>
Bruce Mitchener <bruce.mitchener@gmail.com>

View File

@ -1,7 +1,7 @@
# libuv
libuv is a new platform layer for Node. Its purpose is to abstract IOCP on
windows and libev on Unix systems. We intend to eventually contain all
Windows and libev on Unix systems. We intend to eventually contain all
platform differences in this library.
http://nodejs.org/

View File

@ -51,7 +51,6 @@ endif
ifeq (Darwin,$(uname_S))
EV_CONFIG=config_darwin.h
EIO_CONFIG=config_darwin.h
CPPFLAGS += -D__DARWIN_64_BIT_INO_T=1
CPPFLAGS += -Isrc/ares/config_darwin
LINKFLAGS+=-framework CoreServices
OBJS += src/unix/darwin.o

View File

@ -291,7 +291,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
LPFN_WSARECVFROM func_wsarecvfrom;
#define uv_pipe_server_fields \
uv_pipe_accept_t accept_reqs[4]; \
int pending_instances; \
uv_pipe_accept_t* accept_reqs; \
uv_pipe_accept_t* pending_accepts;
#define uv_pipe_connection_fields \

View File

@ -106,7 +106,7 @@ typedef intptr_t ssize_t;
XX( 35, ENOSYS, "function not implemented") \
XX( 36, EPIPE, "broken pipe") \
XX( 37, EPROTO, "protocol error") \
XX( 38, EPROTONOSUPPORT, "protocol not suppored") \
XX( 38, EPROTONOSUPPORT, "protocol not supported") \
XX( 39, EPROTOTYPE, "protocol wrong type for socket") \
XX( 40, ETIMEDOUT, "connection timed out") \
XX( 41, ECHARSET, "") \
@ -226,7 +226,6 @@ UV_EXTERN int64_t uv_now(uv_loop_t*);
/*
* The status parameter is 0 if the request completed successfully,
* and should be -1 if the request was cancelled or failed.
* For uv_close_cb, -1 means that the handle was closed due to an error.
* Error details can be obtained by calling uv_last_error().
*
* In the case of uv_read_cb the uv_buf_t returned should be freed by the
@ -263,7 +262,7 @@ typedef void (*uv_after_work_cb)(uv_work_t* req);
* This will be called repeatedly after the uv_fs_event_t is initialized.
* If uv_fs_event_t was initialized with a directory the filename parameter
* will be a relative path to a file contained in the directory.
* The events paramenter is an ORed mask of enum uv_fs_event elements.
* The events parameter is an ORed mask of enum uv_fs_event elements.
*/
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename,
int events, int status);
@ -315,8 +314,8 @@ UV_PRIVATE_REQ_TYPES
*
* Shutdown the outgoing (write) side of a duplex stream. It waits for
* pending write requests to complete. The handle should refer to a
* initialized stream. req should be an uninitalized shutdown request
* struct. The cb is a called after shutdown is complete.
* initialized stream. req should be an uninitialized shutdown request
* struct. The cb is called after shutdown is complete.
*/
UV_EXTERN int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle,
uv_shutdown_cb cb);
@ -345,8 +344,8 @@ struct uv_handle_s {
};
/*
* Returns 1 if the prepare/check/idle handle has been started, 0 otherwise.
* For other handle types this always returns 1.
* Returns 1 if the prepare/check/idle/timer handle has been started, 0
* otherwise. For other handle types this always returns 1.
*/
UV_EXTERN int uv_is_active(uv_handle_t* handle);
@ -524,7 +523,7 @@ UV_EXTERN int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
* uv_tcp_connect, uv_tcp_connect6
* These functions establish IPv4 and IPv6 TCP connections. Provide an
* initialized TCP handle and an uninitialized uv_connect_t*. The callback
* will be made when the connection is estabished.
* will be made when the connection is established.
*/
UV_EXTERN int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
struct sockaddr_in address, uv_connect_cb cb);
@ -788,6 +787,13 @@ UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
UV_EXTERN void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
const char* name, uv_connect_cb cb);
/*
* This setting applies to Windows only.
* Set the number of pending pipe instance handles when the pipe server
* is waiting for connections.
*/
UV_EXTERN void uv_pipe_pending_instances(uv_pipe_t* handle, int count);
/*
* uv_prepare_t is a subclass of uv_handle_t.
@ -899,7 +905,7 @@ UV_EXTERN int uv_timer_again(uv_timer_t* timer);
/*
* Set the repeat value. Note that if the repeat value is set from a timer
* callback it does not immediately take effect. If the timer was nonrepeating
* callback it does not immediately take effect. If the timer was non-repeating
* before, it will have been stopped. If it was repeating, then the old repeat
* value will have been used to schedule the next timeout.
*/
@ -953,7 +959,7 @@ typedef struct uv_process_options_s {
const char* file; /* Path to program to execute. */
/*
* Command line arguments. args[0] should be the path to the program. On
* Windows this uses CreateProcess which concatinates the arguments into a
* Windows this uses CreateProcess which concatenates the arguments into a
* string this can cause some strange errors. See the note at
* windows_verbatim_arguments.
*/
@ -977,7 +983,7 @@ typedef struct uv_process_options_s {
/*
* The user should supply pointers to initialized uv_pipe_t structs for
* stdio. This is used to to send or receive input from the subprocess.
* The user is reponsible for calling uv_close on them.
* The user is responsible for calling uv_close on them.
*/
uv_pipe_t* stdin_stream;
uv_pipe_t* stdout_stream;
@ -1037,7 +1043,7 @@ UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req,
* uninitialized uv_fs_t object.
*
* uv_fs_req_cleanup() must be called after completion of the uv_fs_
* function to free any internal memory allocations associted with the
* function to free any internal memory allocations associated with the
* request.
*/
@ -1229,6 +1235,12 @@ UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
/* Gets the executable path */
UV_EXTERN int uv_exepath(char* buffer, size_t* size);
/* Gets the current working directory */
UV_EXTERN uv_err_t uv_cwd(char* buffer, size_t size);
/* Changes the current working directory */
UV_EXTERN uv_err_t uv_chdir(const char* dir);
/* Gets memory info in bytes */
UV_EXTERN uint64_t uv_get_free_memory(void);
UV_EXTERN uint64_t uv_get_total_memory(void);

View File

@ -827,3 +827,43 @@ int uv__cloexec(int fd, int set) {
return 0;
#endif
}
/* TODO move to uv-common.c? */
size_t uv__strlcpy(char* dst, const char* src, size_t size) {
const char *org;
if (size == 0) {
return 0;
}
org = src;
while (--size && *src) {
*dst++ = *src++;
}
*dst = '\0';
return src - org;
}
uv_err_t uv_cwd(char* buffer, size_t size) {
if (!buffer || !size) {
return uv__new_artificial_error(UV_EINVAL);
}
if (getcwd(buffer, size)) {
return uv_ok_;
} else {
return uv__new_sys_error(errno);
}
}
uv_err_t uv_chdir(const char* dir) {
if (chdir(dir) == 0) {
return uv_ok_;
} else {
return uv__new_sys_error(errno);
}
}

View File

@ -271,3 +271,8 @@ void uv__pipe_accept(EV_P_ ev_io* watcher, int revents) {
errno = saved_errno;
}
void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
return 0;
}

View File

@ -62,7 +62,7 @@ static void CALLBACK uv_ares_socksignal_tp(void* parameter,
/* do not fail if error, thread may run after socket close */
/* The code assumes that c-ares will write all pending data in the */
/* callback, unless the socket would block. We can clear the state here */
/* to avoid unecessary signals. */
/* to avoid unnecessary signals. */
WSAEnumNetworkEvents(sockhandle->sock,
sockhandle->h_event,
&network_events);
@ -113,7 +113,7 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read,
if (read == 0 && write == 0) {
/* if read and write are 0, cleanup existing data */
/* The code assumes that c-ares does a callback with read = 0 and */
/* write = 0 when the socket is closed. After we recieve this we stop */
/* write = 0 when the socket is closed. After we receive this we stop */
/* monitoring the socket. */
if (uv_handle_ares != NULL) {
uv_req_t* uv_ares_req;
@ -244,7 +244,7 @@ void uv_process_ares_cleanup_req(uv_loop_t* loop, uv_ares_task_t* handle,
}
}
} else {
/* stil busy - repost and try again */
/* still busy - repost and try again */
POST_COMPLETION_FOR_REQ(loop, req);
}
}

View File

@ -91,7 +91,7 @@ static void uv_loop_init(uv_loop_t* loop) {
static void uv_default_loop_init(void) {
/* Intialize libuv itself first */
/* Initialize libuv itself first */
uv_once(&uv_init_guard_, uv_init);
/* Initialize the main loop */
@ -204,13 +204,8 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
uv_idle_invoke((loop)); \
} \
\
/* Completely flush all pending reqs and endgames. */ \
/* We do even when we just called the idle callbacks because those may */ \
/* have closed handles or started requests that short-circuited. */ \
while ((loop)->pending_reqs_tail || (loop)->endgame_handles) { \
uv_process_endgames((loop)); \
uv_process_reqs((loop)); \
} \
uv_process_reqs((loop)); \
uv_process_endgames((loop)); \
\
if ((loop)->refs <= 0) { \
break; \
@ -218,7 +213,10 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
\
uv_prepare_invoke((loop)); \
\
poll((loop), (loop)->idle_handles == NULL && (loop)->refs > 0); \
poll((loop), (loop)->idle_handles == NULL && \
(loop)->pending_reqs_tail == NULL && \
(loop)->endgame_handles == NULL && \
(loop)->refs > 0); \
\
uv_check_invoke((loop)); \
}

View File

@ -39,6 +39,8 @@ static const uv_buf_t uv_null_buf_ = { 0, NULL };
/* when the local ends wants to shut it down. */
static const int64_t eof_timeout = 50; /* ms */
static const int default_pending_pipe_instances = 4;
/* IPC protocol flags. */
#define UV_IPC_RAW_DATA 0x0001
#define UV_IPC_UV_STREAM 0x0002
@ -249,7 +251,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
return;
}
/* Run FlushFileBuffers in the thhead pool. */
/* Run FlushFileBuffers in the thread pool. */
result = QueueUserWorkItem(pipe_shutdown_thread_proc,
req,
WT_EXECUTELONGFUNCTION);
@ -293,6 +295,12 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
}
}
if (handle->flags & UV_HANDLE_PIPESERVER) {
assert(handle->accept_reqs);
free(handle->accept_reqs);
handle->accept_reqs = NULL;
}
/* Remember the state of this flag because the close callback is */
/* allowed to clobber or free the handle's memory */
uv_alloced = handle->flags & UV_HANDLE_UV_ALLOCED;
@ -310,6 +318,12 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
}
void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
handle->pending_instances = count;
handle->flags |= UV_HANDLE_PIPESERVER;
}
/* Creates a pipe server. */
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
uv_loop_t* loop = handle->loop;
@ -326,7 +340,17 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
return -1;
}
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
handle->pending_instances = default_pending_pipe_instances;
}
handle->accept_reqs = (uv_pipe_accept_t*)
malloc(sizeof(uv_pipe_accept_t) * handle->pending_instances);
if (!handle->accept_reqs) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
for (i = 0; i < handle->pending_instances; i++) {
req = &handle->accept_reqs[i];
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_ACCEPT;
@ -537,14 +561,13 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
}
if (handle->flags & UV_HANDLE_PIPESERVER) {
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
for (i = 0; i < handle->pending_instances; i++) {
pipeHandle = handle->accept_reqs[i].pipeHandle;
if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(pipeHandle);
handle->accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
}
}
}
if (handle->flags & UV_HANDLE_CONNECTION) {
@ -686,7 +709,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
/* First pipe handle should have already been created in uv_pipe_bind */
assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
for (i = 0; i < handle->pending_instances; i++) {
uv_pipe_queue_accept(loop, handle, &handle->accept_reqs[i], i == 0);
}

View File

@ -254,7 +254,7 @@ static wchar_t* path_search_walk_ext(const wchar_t *dir,
* - CMD does not trim leading/trailing whitespace from path/pathex entries
* nor from the environment variables as a whole.
*
* - When cmd.exe cannot read a directory, it wil just skip it and go on
* - When cmd.exe cannot read a directory, it will just skip it and go on
* searching. However, unlike posix-y systems, it will happily try to run a
* file that is not readable/executable; if the spawn fails it will not
* continue searching.
@ -400,7 +400,7 @@ wchar_t* quote_cmd_arg(const wchar_t *source, wchar_t *target) {
}
/*
* Expected intput/output:
* Expected input/output:
* input : hello"world
* output: "hello\"world"
* input : hello""world
@ -1018,7 +1018,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
} else {
/* CreateProcessW failed, but this failure should be delivered */
/* asynchronously to retain unix compatibility. So pretent spawn */
/* asynchronously to retain unix compatibility. So pretend spawn */
/* succeeded, and start a thread instead that prints an error */
/* to the child's intended stderr. */
process->spawn_errno = GetLastError();
@ -1046,7 +1046,7 @@ done:
close_child_stdio(process);
} else {
/* We're keeping the handles open, the thread pool is going to have */
/* it's way with them. But at least make them noninheritable. */
/* it's way with them. But at least make them non-inheritable. */
int i;
for (i = 0; i < COUNTOF(process->child_stdio); i++) {
SetHandleInformation(child_stdio[i], HANDLE_FLAG_INHERIT, 0);

View File

@ -51,27 +51,6 @@ void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
}
static uv_req_t* uv_remove_pending_req(uv_loop_t* loop) {
uv_req_t* req;
if (loop->pending_reqs_tail) {
req = loop->pending_reqs_tail->next_req;
if (req == loop->pending_reqs_tail) {
loop->pending_reqs_tail = NULL;
} else {
loop->pending_reqs_tail->next_req = req->next_req;
}
return req;
} else {
/* queue empty */
return NULL;
}
}
#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
do { \
switch (((uv_handle_t*) (req)->handle_at)->type) { \
@ -101,8 +80,21 @@ static uv_req_t* uv_remove_pending_req(uv_loop_t* loop) {
void uv_process_reqs(uv_loop_t* loop) {
uv_req_t* req;
uv_req_t* first;
uv_req_t* next;
if (loop->pending_reqs_tail == NULL) {
return;
}
first = loop->pending_reqs_tail->next_req;
next = first;
loop->pending_reqs_tail = NULL;
while (next != NULL) {
req = next;
next = req->next_req != first ? req->next_req : NULL;
while (req = uv_remove_pending_req(loop)) {
switch (req->type) {
case UV_READ:
DELEGATE_STREAM_REQ(loop, req, read, data);

View File

@ -1084,7 +1084,7 @@ int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
/*
* We're about to share the socket with another process. Because
* this is a listening socket, we assume that the other process will
* be accepting conections on it. So, before sharing the socket
* be accepting connections on it. So, before sharing the socket
* with another process, we call listen here in the parent process.
* This needs to be modified if the socket is shared with
* another process for anything other than accepting connections.
@ -1137,7 +1137,7 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
/* Flip the changing flag if we have already queueed multiple accepts. */
/* Flip the changing flag if we have already queued multiple accepts. */
if (handle->flags & UV_HANDLE_LISTENING) {
handle->flags |= UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
}

View File

@ -86,7 +86,7 @@ uint64_t uv_hrtime(void) {
return 0;
}
/* Because we have no guarantee about the order of magniture of the */
/* Because we have no guarantee about the order of magnitude of the */
/* performance counter frequency, and there may not be much headroom to */
/* multiply by NANOSEC without overflowing, we use 128-bit math instead. */
return ((uint64_t) counter.LowPart * NANOSEC / uv_hrtime_frequency_) +

View File

@ -739,7 +739,7 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
handle->read_cb = read_cb;
handle->alloc_cb = alloc_cb;
/* If reading was stopped and then started again, there could stell be a */
/* If reading was stopped and then started again, there could still be a */
/* read request pending. */
if (handle->flags & UV_HANDLE_READ_PENDING) {
return 0;

View File

@ -362,7 +362,7 @@ int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
handle->recv_cb = recv_cb;
handle->alloc_cb = alloc_cb;
/* If reading was stopped and then started again, there could stell be a */
/* If reading was stopped and then started again, there could still be a */
/* recv request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING))
uv_udp_queue_recv(loop, handle);

View File

@ -20,6 +20,7 @@
*/
#include <assert.h>
#include <direct.h>
#include <malloc.h>
#include <string.h>
@ -97,6 +98,91 @@ done:
}
uv_err_t uv_cwd(char* buffer, size_t size) {
uv_err_t err;
size_t utf8Size;
wchar_t* utf16Buffer = NULL;
if (!buffer || !size) {
err.code = UV_EINVAL;
goto done;
}
utf16Buffer = (wchar_t*)malloc(sizeof(wchar_t) * size);
if (!utf16Buffer) {
err.code = UV_ENOMEM;
goto done;
}
if (!_wgetcwd(utf16Buffer, size - 1)) {
err = uv__new_sys_error(_doserrno);
goto done;
}
utf16Buffer[size - 1] = L'\0';
/* Convert to UTF-8 */
utf8Size = uv_utf16_to_utf8(utf16Buffer, -1, buffer, size);
if (utf8Size == 0) {
err = uv__new_sys_error(GetLastError());
goto done;
}
buffer[utf8Size] = '\0';
err = uv_ok_;
done:
if (utf16Buffer) {
free(utf16Buffer);
}
return err;
}
uv_err_t uv_chdir(const char* dir) {
uv_err_t err;
wchar_t* utf16Buffer = NULL;
size_t utf16Size;
if (!dir) {
err.code = UV_EINVAL;
goto done;
}
utf16Size = uv_utf8_to_utf16(dir, NULL, 0);
if (!utf16Size) {
err = uv__new_sys_error(GetLastError());
goto done;
}
utf16Buffer = (wchar_t*)malloc(sizeof(wchar_t) * utf16Size);
if (!utf16Buffer) {
err.code = UV_ENOMEM;
goto done;
}
if (!uv_utf8_to_utf16(dir, utf16Buffer, utf16Size)) {
err = uv__new_sys_error(GetLastError());
goto done;
}
if (_wchdir(utf16Buffer) == -1) {
err = uv__new_sys_error(_doserrno);
goto done;
}
err = uv_ok_;
done:
if (utf16Buffer) {
free(utf16Buffer);
}
return err;
}
void uv_loadavg(double avg[3]) {
/* Can't be implemented */
avg[0] = avg[1] = avg[2] = 0;

View File

@ -4394,6 +4394,7 @@ typedef VOID (WINAPI* sReleaseSRWLockExclusive)
(PSRWLOCK SRWLock);
/* Ntapi function pointers */
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
extern sNtDeviceIoControlFile pNtDeviceIoControlFile;

View File

@ -186,7 +186,7 @@ static void pinger_new() {
pinger->state = 0;
pinger->pongs = 0;
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
r = uv_tcp_init(loop, &pinger->tcp);
ASSERT(!r);

View File

@ -156,7 +156,7 @@ int process_wait(process_info_t *vec, int n, int timeout) {
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
DWORD timeout_api, result;
/* If there's nothing to wait for, return immedately. */
/* If there's nothing to wait for, return immediately. */
if (n == 0)
return 0;

View File

@ -19,10 +19,10 @@
* IN THE SOFTWARE.
*/
/* Don't complain about _snprintf being unsecure. */
/* Don't complain about _snprintf being insecure. */
#define _CRT_SECURE_NO_WARNINGS
/* Dont complain about write(), fileno() etc. being deprecated. */
/* Don't complain about write(), fileno() etc. being deprecated. */
#pragma warning(disable : 4996)

View File

@ -218,7 +218,7 @@ out:
} else if (benchmark_output) {
switch (process_output_size(main_proc)) {
case -1:
LOGF("%s: (unavailabe)\n", test);
LOGF("%s: (unavailable)\n", test);
break;
case 0:

View File

@ -138,7 +138,7 @@ static void write_cb(uv_write_t* req, int status) {
/* After the data has been sent, we're going to wait for a while, then */
/* start reading. This makes us certain that the message has been echoed */
/* back to our receive buffer when we start reading. This maximizes the */
/* tempation for the backend to use dirty stack for calling read_cb. */
/* temptation for the backend to use dirty stack for calling read_cb. */
nested++;
r = uv_timer_init(uv_default_loop(), &timer);
ASSERT(r == 0);

View File

@ -97,7 +97,7 @@ void connection_fail(uv_connect_cb connect_cb) {
/* There should be no servers listening on this port. */
server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
r = uv_tcp_init(uv_default_loop(), &tcp);
ASSERT(!r);

61
test/test-cwd-and-chdir.c Normal file
View File

@ -0,0 +1,61 @@
/* 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"
#include <string.h>
#define PATHMAX 1024
extern char executable_path[];
TEST_IMPL(cwd_and_chdir) {
char buffer_orig[PATHMAX];
char buffer_new[PATHMAX];
size_t size;
char* last_slash;
uv_err_t err;
size = sizeof(buffer_orig) / sizeof(buffer_orig[0]);
err = uv_cwd(buffer_orig, size);
ASSERT(err.code == UV_OK);
last_slash = strrchr(buffer_orig,
#ifdef _WIN32
'\\'
#else
'/'
#endif
);
ASSERT(last_slash);
*last_slash = '\0';
err = uv_chdir(buffer_orig);
ASSERT(err.code == UV_OK);
err = uv_cwd(buffer_new, size);
ASSERT(err.code == UV_OK);
ASSERT(strcmp(buffer_orig, buffer_new) == 0);
return 0;
}

View File

@ -152,7 +152,7 @@ static void connect_cb(uv_connect_t* req, int status) {
ASSERT(status == 0);
/* Not that the server will send anything, but otherwise we'll never know */
/* when te server closes the connection. */
/* when the server closes the connection. */
r = uv_read_start((uv_stream_t*)(req->handle), alloc_cb, read_cb);
ASSERT(r == 0);

View File

@ -19,7 +19,7 @@
* IN THE SOFTWARE.
*/
/* FIXME we shouldnt need to branch in this file */
/* FIXME we shouldn't need to branch in this file */
#define UNIX (defined(__unix__) || defined(__POSIX__) || defined(__APPLE__))
#include "uv.h"

View File

@ -83,7 +83,7 @@ static void check_sockname(struct sockaddr* addr, const char* compare_ip,
char check_ip[17];
int r;
/* Both adresses should be ipv4 */
/* Both addresses should be ipv4 */
ASSERT(check_addr.sin_family == AF_INET);
ASSERT(compare_addr.sin_family == AF_INET);

View File

@ -77,6 +77,7 @@ TEST_DECLARE (check_ref)
TEST_DECLARE (unref_in_prepare_cb)
TEST_DECLARE (async)
TEST_DECLARE (get_currentexe)
TEST_DECLARE (cwd_and_chdir)
TEST_DECLARE (get_memory)
TEST_DECLARE (hrtime)
TEST_DECLARE (getaddrinfo_basic)
@ -223,6 +224,8 @@ TASK_LIST_START
TEST_ENTRY (get_currentexe)
TEST_ENTRY (cwd_and_chdir)
TEST_ENTRY (get_memory)
TEST_ENTRY (get_loadavg)

View File

@ -58,7 +58,7 @@
* being started by a check_1 watcher. It verifies that a watcher is
* implicitly stopped when closed, and that a watcher can close itself
* safely.
* - There is a repeating timer. It does not keep te event loop alive
* - There is a repeating timer. It does not keep the event loop alive
* (ev_unref) but makes sure that the loop keeps polling the system for
* events.
*/

View File

@ -154,7 +154,7 @@ static void tcp_pinger_v6_new() {
pinger->state = 0;
pinger->pongs = 0;
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp);
pinger->stream.tcp.data = pinger;
ASSERT(!r);
@ -179,7 +179,7 @@ static void tcp_pinger_new() {
pinger->state = 0;
pinger->pongs = 0;
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp);
pinger->stream.tcp.data = pinger;
ASSERT(!r);
@ -203,7 +203,7 @@ static void pipe_pinger_new() {
pinger->state = 0;
pinger->pongs = 0;
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
r = uv_pipe_init(uv_default_loop(), &pinger->stream.pipe, 0);
pinger->stream.pipe.data = pinger;
ASSERT(!r);

View File

@ -28,7 +28,7 @@ TEST_IMPL(tty) {
uv_loop_t* loop = uv_default_loop();
/*
* Not necessarally a problem if this assert goes off. E.G you are piping
* Not necessarily a problem if this assert goes off. E.G you are piping
* this test to a file. 0 == stdin.
*/
ASSERT(UV_TTY == uv_guess_handle(0));

4
uv.gyp
View File

@ -9,9 +9,6 @@
'EIO_STACKSIZE=262144'
],
'conditions': [
['OS=="mac"', {
'defines': ['__DARWIN_64_BIT_INO_T=1'],
}],
['OS=="solaris"', {
'cflags': ['-pthreads'],
'ldlags': ['-pthreads'],
@ -283,6 +280,7 @@
'test/test-error.c',
'test/test-callback-stack.c',
'test/test-connection-fail.c',
'test/test-cwd-and-chdir.c',
'test/test-delayed-accept.c',
'test/test-fail-always.c',
'test/test-fs.c',