mirror of
https://github.com/nodejs/node-v0.x-archive.git
synced 2026-04-28 03:01:10 -04:00
uv: upgrade to 8073a26
This commit is contained in:
1
deps/uv/config-unix.mk
vendored
1
deps/uv/config-unix.mk
vendored
@@ -37,6 +37,7 @@ OBJS += src/unix/loop-watcher.o
|
||||
OBJS += src/unix/pipe.o
|
||||
OBJS += src/unix/poll.o
|
||||
OBJS += src/unix/process.o
|
||||
OBJS += src/unix/signal.o
|
||||
OBJS += src/unix/stream.o
|
||||
OBJS += src/unix/tcp.o
|
||||
OBJS += src/unix/thread.o
|
||||
|
||||
4
deps/uv/gyp_uv
vendored
4
deps/uv/gyp_uv
vendored
@@ -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)
|
||||
|
||||
|
||||
|
||||
2
deps/uv/include/uv-private/eio.h
vendored
2
deps/uv/include/uv-private/eio.h
vendored
@@ -251,7 +251,7 @@ struct eio_req
|
||||
|
||||
eio_channel *channel; /* data used to direct poll callbacks arising from this req */
|
||||
|
||||
#if __i386 || __amd64
|
||||
#if defined(__i386) || defined(__amd64)
|
||||
unsigned char cancelled;
|
||||
#else
|
||||
sig_atomic_t cancelled;
|
||||
|
||||
2
deps/uv/include/uv-private/ngx-queue.h
vendored
2
deps/uv/include/uv-private/ngx-queue.h
vendored
@@ -62,7 +62,7 @@ struct ngx_queue_s {
|
||||
(q)->prev
|
||||
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
#if defined(NGX_DEBUG)
|
||||
|
||||
#define ngx_queue_remove(x) \
|
||||
(x)->next->prev = (x)->prev; \
|
||||
|
||||
30
deps/uv/include/uv-private/uv-bsd.h
vendored
Normal file
30
deps/uv/include/uv-private/uv-bsd.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef UV_BSD_H
|
||||
#define UV_BSD_H
|
||||
|
||||
#define UV_PLATFORM_FS_EVENT_FIELDS \
|
||||
uv__io_t event_watcher; \
|
||||
int fflags; \
|
||||
int fd; \
|
||||
|
||||
#endif /* UV_BSD_H */
|
||||
37
deps/uv/include/uv-private/uv-darwin.h
vendored
Normal file
37
deps/uv/include/uv-private/uv-darwin.h
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef UV_DARWIN_H
|
||||
#define UV_DARWIN_H
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# include <mach/mach.h>
|
||||
# include <mach/task.h>
|
||||
# include <mach/semaphore.h>
|
||||
# define UV_PLATFORM_SEM_T semaphore_t
|
||||
#endif
|
||||
|
||||
#define UV_PLATFORM_FS_EVENT_FIELDS \
|
||||
ev_io event_watcher; \
|
||||
int fflags; \
|
||||
int fd; \
|
||||
|
||||
#endif /* UV_DARWIN_H */
|
||||
34
deps/uv/include/uv-private/uv-linux.h
vendored
Normal file
34
deps/uv/include/uv-private/uv-linux.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef UV_LINUX_H
|
||||
#define UV_LINUX_H
|
||||
|
||||
#define UV_PLATFORM_LOOP_FIELDS \
|
||||
uv__io_t inotify_read_watcher; \
|
||||
void* inotify_watchers; \
|
||||
int inotify_fd; \
|
||||
|
||||
#define UV_PLATFORM_FS_EVENT_FIELDS \
|
||||
ngx_queue_t watchers; \
|
||||
int wd; \
|
||||
|
||||
#endif /* UV_LINUX_H */
|
||||
40
deps/uv/include/uv-private/uv-sunos.h
vendored
Normal file
40
deps/uv/include/uv-private/uv-sunos.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef UV_SUNOS_H
|
||||
#define UV_SUNOS_H
|
||||
|
||||
#include <sys/port.h>
|
||||
#include <port.h>
|
||||
|
||||
#if defined(PORT_SOURCE_FILE)
|
||||
|
||||
# define UV_PLATFORM_LOOP_FIELDS \
|
||||
uv__io_t fs_event_watcher; \
|
||||
int fs_fd; \
|
||||
|
||||
# define UV_PLATFORM_FS_EVENT_FIELDS \
|
||||
file_obj_t fo; \
|
||||
int fd; \
|
||||
|
||||
#endif /* defined(PORT_SOURCE_FILE) */
|
||||
|
||||
#endif /* UV_SUNOS_H */
|
||||
329
deps/uv/include/uv-private/uv-unix.h
vendored
329
deps/uv/include/uv-private/uv-unix.h
vendored
@@ -40,57 +40,10 @@
|
||||
#include <termios.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# include <mach/mach.h>
|
||||
# include <mach/task.h>
|
||||
# include <mach/semaphore.h>
|
||||
#else
|
||||
# include <semaphore.h>
|
||||
#endif
|
||||
|
||||
#if __sun
|
||||
# include <sys/port.h>
|
||||
# include <port.h>
|
||||
#endif
|
||||
|
||||
/* Note: May be cast to struct iovec. See writev(2). */
|
||||
typedef struct {
|
||||
char* base;
|
||||
size_t len;
|
||||
} uv_buf_t;
|
||||
|
||||
typedef int uv_file;
|
||||
|
||||
typedef int uv_os_sock_t;
|
||||
|
||||
typedef struct stat uv_statbuf_t;
|
||||
|
||||
#define UV_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
|
||||
typedef pthread_once_t uv_once_t;
|
||||
typedef pthread_t uv_thread_t;
|
||||
typedef pthread_mutex_t uv_mutex_t;
|
||||
typedef pthread_rwlock_t uv_rwlock_t;
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
typedef semaphore_t uv_sem_t;
|
||||
#else
|
||||
typedef sem_t uv_sem_t;
|
||||
#endif
|
||||
|
||||
/* Platform-specific definitions for uv_spawn support. */
|
||||
typedef gid_t uv_gid_t;
|
||||
typedef uid_t uv_uid_t;
|
||||
|
||||
/* Platform-specific definitions for uv_dlopen support. */
|
||||
#define UV_DYNAMIC /* empty */
|
||||
typedef struct {
|
||||
void* handle;
|
||||
char* errmsg;
|
||||
} uv_lib_t;
|
||||
|
||||
struct uv__io_s;
|
||||
struct uv_loop_s;
|
||||
|
||||
@@ -101,22 +54,63 @@ struct uv__io_s {
|
||||
ev_io io_watcher;
|
||||
};
|
||||
|
||||
#define UV_REQ_TYPE_PRIVATE /* empty */
|
||||
|
||||
#if __linux__
|
||||
# define UV_LOOP_PRIVATE_PLATFORM_FIELDS \
|
||||
uv__io_t inotify_read_watcher; \
|
||||
void* inotify_watchers; \
|
||||
int inotify_fd;
|
||||
#elif defined(PORT_SOURCE_FILE)
|
||||
# define UV_LOOP_PRIVATE_PLATFORM_FIELDS \
|
||||
uv__io_t fs_event_watcher; \
|
||||
int fs_fd;
|
||||
#else
|
||||
# define UV_LOOP_PRIVATE_PLATFORM_FIELDS
|
||||
#if defined(__linux__)
|
||||
# include "uv-linux.h"
|
||||
#elif defined(__sun)
|
||||
# include "uv-sunos.h"
|
||||
#elif defined(__APPLE__)
|
||||
# include "uv-darwin.h"
|
||||
#elif defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__)
|
||||
# include "uv-bsd.h"
|
||||
#endif
|
||||
|
||||
#ifndef UV_PLATFORM_SEM_T
|
||||
# define UV_PLATFORM_SEM_T sem_t
|
||||
#endif
|
||||
|
||||
#ifndef UV_PLATFORM_LOOP_FIELDS
|
||||
# define UV_PLATFORM_LOOP_FIELDS /* empty */
|
||||
#endif
|
||||
|
||||
#ifndef UV_PLATFORM_FS_EVENT_FIELDS
|
||||
# define UV_PLATFORM_FS_EVENT_FIELDS /* empty */
|
||||
#endif
|
||||
|
||||
/* Note: May be cast to struct iovec. See writev(2). */
|
||||
typedef struct {
|
||||
char* base;
|
||||
size_t len;
|
||||
} uv_buf_t;
|
||||
|
||||
typedef int uv_file;
|
||||
typedef int uv_os_sock_t;
|
||||
typedef struct stat uv_statbuf_t;
|
||||
|
||||
#define UV_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
|
||||
typedef pthread_once_t uv_once_t;
|
||||
typedef pthread_t uv_thread_t;
|
||||
typedef pthread_mutex_t uv_mutex_t;
|
||||
typedef pthread_rwlock_t uv_rwlock_t;
|
||||
typedef UV_PLATFORM_SEM_T uv_sem_t;
|
||||
|
||||
/* Platform-specific definitions for uv_spawn support. */
|
||||
typedef gid_t uv_gid_t;
|
||||
typedef uid_t uv_uid_t;
|
||||
|
||||
/* Platform-specific definitions for uv_dlopen support. */
|
||||
#define UV_DYNAMIC /* empty */
|
||||
|
||||
typedef struct {
|
||||
void* handle;
|
||||
char* errmsg;
|
||||
} uv_lib_t;
|
||||
|
||||
#define UV_LOOP_PRIVATE_FIELDS \
|
||||
unsigned long flags; \
|
||||
/* Poll result queue */ \
|
||||
eio_channel uv_eio_channel; \
|
||||
struct ev_loop* ev; \
|
||||
@@ -125,6 +119,7 @@ struct uv__io_s {
|
||||
uv_async_t uv_eio_done_poll_notifier; \
|
||||
uv_idle_t uv_eio_poller; \
|
||||
uv_handle_t* closing_handles; \
|
||||
ngx_queue_t process_handles[1]; \
|
||||
ngx_queue_t prepare_handles; \
|
||||
ngx_queue_t check_handles; \
|
||||
ngx_queue_t idle_handles; \
|
||||
@@ -132,111 +127,94 @@ struct uv__io_s {
|
||||
uv__io_t async_watcher; \
|
||||
int async_pipefd[2]; \
|
||||
/* RB_HEAD(uv__timers, uv_timer_s) */ \
|
||||
struct uv__timers { struct uv_timer_s* rbh_root; } timer_handles; \
|
||||
struct uv__timers { \
|
||||
struct uv_timer_s* rbh_root; \
|
||||
} timer_handles; \
|
||||
uint64_t time; \
|
||||
UV_LOOP_PRIVATE_PLATFORM_FIELDS
|
||||
void* signal_ctx; \
|
||||
uv_signal_t child_watcher; \
|
||||
UV_PLATFORM_LOOP_FIELDS \
|
||||
|
||||
#define UV_REQ_BUFSML_SIZE (4)
|
||||
#define UV_REQ_TYPE_PRIVATE /* empty */
|
||||
|
||||
#define UV_REQ_PRIVATE_FIELDS /* empty */
|
||||
|
||||
#define UV_WRITE_PRIVATE_FIELDS \
|
||||
ngx_queue_t queue; \
|
||||
int write_index; \
|
||||
uv_buf_t* bufs; \
|
||||
int bufcnt; \
|
||||
int error; \
|
||||
uv_buf_t bufsml[UV_REQ_BUFSML_SIZE];
|
||||
#define UV_PRIVATE_REQ_TYPES /* empty */
|
||||
|
||||
#define UV_WRITE_PRIVATE_FIELDS \
|
||||
ngx_queue_t queue; \
|
||||
int write_index; \
|
||||
uv_buf_t* bufs; \
|
||||
int bufcnt; \
|
||||
int error; \
|
||||
uv_buf_t bufsml[4]; \
|
||||
|
||||
#define UV_CONNECT_PRIVATE_FIELDS \
|
||||
ngx_queue_t queue; \
|
||||
|
||||
#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
|
||||
|
||||
#define UV_CONNECT_PRIVATE_FIELDS \
|
||||
ngx_queue_t queue;
|
||||
#define UV_UDP_SEND_PRIVATE_FIELDS \
|
||||
ngx_queue_t queue; \
|
||||
struct sockaddr_in6 addr; \
|
||||
int bufcnt; \
|
||||
uv_buf_t* bufs; \
|
||||
ssize_t status; \
|
||||
uv_udp_send_cb send_cb; \
|
||||
uv_buf_t bufsml[4]; \
|
||||
|
||||
#define UV_UDP_SEND_PRIVATE_FIELDS \
|
||||
ngx_queue_t queue; \
|
||||
struct sockaddr_in6 addr; \
|
||||
int bufcnt; \
|
||||
uv_buf_t* bufs; \
|
||||
ssize_t status; \
|
||||
uv_udp_send_cb send_cb; \
|
||||
uv_buf_t bufsml[UV_REQ_BUFSML_SIZE]; \
|
||||
#define UV_HANDLE_PRIVATE_FIELDS \
|
||||
int flags; \
|
||||
uv_handle_t* next_closing; \
|
||||
|
||||
#define UV_PRIVATE_REQ_TYPES /* empty */
|
||||
#define UV_STREAM_PRIVATE_FIELDS \
|
||||
uv_connect_t *connect_req; \
|
||||
uv_shutdown_t *shutdown_req; \
|
||||
uv__io_t read_watcher; \
|
||||
uv__io_t write_watcher; \
|
||||
ngx_queue_t write_queue; \
|
||||
ngx_queue_t write_completed_queue; \
|
||||
uv_connection_cb connection_cb; \
|
||||
int delayed_error; \
|
||||
int accepted_fd; \
|
||||
int fd; \
|
||||
|
||||
#define UV_TCP_PRIVATE_FIELDS \
|
||||
uv_idle_t* idle_handle; /* for UV_TCP_SINGLE_ACCEPT handles */ \
|
||||
|
||||
/* TODO: union or classes please! */
|
||||
#define UV_HANDLE_PRIVATE_FIELDS \
|
||||
int flags; \
|
||||
uv_handle_t* next_closing; \
|
||||
#define UV_UDP_PRIVATE_FIELDS \
|
||||
int fd; \
|
||||
uv_alloc_cb alloc_cb; \
|
||||
uv_udp_recv_cb recv_cb; \
|
||||
uv__io_t read_watcher; \
|
||||
uv__io_t write_watcher; \
|
||||
ngx_queue_t write_queue; \
|
||||
ngx_queue_t write_completed_queue; \
|
||||
|
||||
|
||||
#define UV_STREAM_PRIVATE_FIELDS \
|
||||
uv_connect_t *connect_req; \
|
||||
uv_shutdown_t *shutdown_req; \
|
||||
uv__io_t read_watcher; \
|
||||
uv__io_t write_watcher; \
|
||||
ngx_queue_t write_queue; \
|
||||
ngx_queue_t write_completed_queue; \
|
||||
uv_connection_cb connection_cb; \
|
||||
int delayed_error; \
|
||||
int accepted_fd; \
|
||||
int fd; \
|
||||
|
||||
|
||||
/* UV_TCP, idle_handle is for UV_TCP_SINGLE_ACCEPT handles */
|
||||
#define UV_TCP_PRIVATE_FIELDS \
|
||||
uv_idle_t* idle_handle; \
|
||||
|
||||
|
||||
/* UV_UDP */
|
||||
#define UV_UDP_PRIVATE_FIELDS \
|
||||
int fd; \
|
||||
uv_alloc_cb alloc_cb; \
|
||||
uv_udp_recv_cb recv_cb; \
|
||||
uv__io_t read_watcher; \
|
||||
uv__io_t write_watcher; \
|
||||
ngx_queue_t write_queue; \
|
||||
ngx_queue_t write_completed_queue; \
|
||||
|
||||
|
||||
/* UV_NAMED_PIPE */
|
||||
#define UV_PIPE_PRIVATE_FIELDS \
|
||||
#define UV_PIPE_PRIVATE_FIELDS \
|
||||
const char* pipe_fname; /* strdup'ed */
|
||||
|
||||
|
||||
/* UV_POLL */
|
||||
#define UV_POLL_PRIVATE_FIELDS \
|
||||
int fd; \
|
||||
#define UV_POLL_PRIVATE_FIELDS \
|
||||
int fd; \
|
||||
uv__io_t io_watcher;
|
||||
|
||||
|
||||
/* UV_PREPARE */
|
||||
#define UV_PREPARE_PRIVATE_FIELDS \
|
||||
uv_prepare_cb prepare_cb; \
|
||||
#define UV_PREPARE_PRIVATE_FIELDS \
|
||||
uv_prepare_cb prepare_cb; \
|
||||
ngx_queue_t queue;
|
||||
|
||||
|
||||
/* UV_CHECK */
|
||||
#define UV_CHECK_PRIVATE_FIELDS \
|
||||
uv_check_cb check_cb; \
|
||||
#define UV_CHECK_PRIVATE_FIELDS \
|
||||
uv_check_cb check_cb; \
|
||||
ngx_queue_t queue;
|
||||
|
||||
|
||||
/* UV_IDLE */
|
||||
#define UV_IDLE_PRIVATE_FIELDS \
|
||||
uv_idle_cb idle_cb; \
|
||||
#define UV_IDLE_PRIVATE_FIELDS \
|
||||
uv_idle_cb idle_cb; \
|
||||
ngx_queue_t queue;
|
||||
|
||||
|
||||
/* UV_ASYNC */
|
||||
#define UV_ASYNC_PRIVATE_FIELDS \
|
||||
volatile sig_atomic_t pending; \
|
||||
uv_async_cb async_cb; \
|
||||
ngx_queue_t queue;
|
||||
|
||||
|
||||
/* UV_TIMER */
|
||||
#define UV_TIMER_PRIVATE_FIELDS \
|
||||
/* RB_ENTRY(uv_timer_s) node; */ \
|
||||
struct { \
|
||||
@@ -249,66 +227,35 @@ struct uv__io_s {
|
||||
uint64_t timeout; \
|
||||
uint64_t repeat;
|
||||
|
||||
#define UV_GETADDRINFO_PRIVATE_FIELDS \
|
||||
uv_getaddrinfo_cb cb; \
|
||||
struct addrinfo* hints; \
|
||||
char* hostname; \
|
||||
char* service; \
|
||||
struct addrinfo* res; \
|
||||
#define UV_GETADDRINFO_PRIVATE_FIELDS \
|
||||
uv_getaddrinfo_cb cb; \
|
||||
struct addrinfo* hints; \
|
||||
char* hostname; \
|
||||
char* service; \
|
||||
struct addrinfo* res; \
|
||||
int retcode;
|
||||
|
||||
#define UV_PROCESS_PRIVATE_FIELDS \
|
||||
ev_child child_watcher;
|
||||
#define UV_PROCESS_PRIVATE_FIELDS \
|
||||
ngx_queue_t queue; \
|
||||
int errorno; \
|
||||
|
||||
#define UV_FS_PRIVATE_FIELDS \
|
||||
struct stat statbuf; \
|
||||
#define UV_FS_PRIVATE_FIELDS \
|
||||
struct stat statbuf; \
|
||||
uv_file file; \
|
||||
eio_req* eio; \
|
||||
|
||||
#define UV_WORK_PRIVATE_FIELDS \
|
||||
eio_req* eio;
|
||||
|
||||
#define UV_WORK_PRIVATE_FIELDS \
|
||||
eio_req* eio;
|
||||
|
||||
#define UV_TTY_PRIVATE_FIELDS \
|
||||
struct termios orig_termios; \
|
||||
#define UV_TTY_PRIVATE_FIELDS \
|
||||
struct termios orig_termios; \
|
||||
int mode;
|
||||
|
||||
/* UV_FS_EVENT_PRIVATE_FIELDS */
|
||||
#if defined(__linux__)
|
||||
#define UV_SIGNAL_PRIVATE_FIELDS \
|
||||
ngx_queue_t queue;
|
||||
|
||||
#define UV_FS_EVENT_PRIVATE_FIELDS \
|
||||
ngx_queue_t watchers; \
|
||||
uv_fs_event_cb cb; \
|
||||
int wd; \
|
||||
void* pad0; \
|
||||
void* pad1; \
|
||||
|
||||
#elif defined(__APPLE__) \
|
||||
|| defined(__FreeBSD__) \
|
||||
|| defined(__DragonFly__) \
|
||||
|| defined(__OpenBSD__) \
|
||||
|| defined(__NetBSD__)
|
||||
|
||||
#define UV_FS_EVENT_PRIVATE_FIELDS \
|
||||
ev_io event_watcher; \
|
||||
uv_fs_event_cb cb; \
|
||||
int fflags; \
|
||||
int fd;
|
||||
|
||||
#elif defined(__sun)
|
||||
|
||||
#ifdef PORT_SOURCE_FILE
|
||||
# define UV_FS_EVENT_PRIVATE_FIELDS \
|
||||
uv_fs_event_cb cb; \
|
||||
file_obj_t fo; \
|
||||
int fd;
|
||||
#else /* !PORT_SOURCE_FILE */
|
||||
# define UV_FS_EVENT_PRIVATE_FIELDS
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/* Stub for platforms where the file watcher isn't implemented yet. */
|
||||
#define UV_FS_EVENT_PRIVATE_FIELDS
|
||||
|
||||
#endif
|
||||
#define UV_FS_EVENT_PRIVATE_FIELDS \
|
||||
uv_fs_event_cb cb; \
|
||||
UV_PLATFORM_FS_EVENT_FIELDS \
|
||||
|
||||
#endif /* UV_UNIX_H */
|
||||
|
||||
509
deps/uv/include/uv-private/uv-win.h
vendored
509
deps/uv/include/uv-private/uv-win.h
vendored
@@ -29,12 +29,14 @@ typedef intptr_t ssize_t;
|
||||
# define _SSIZE_T_DEFINED
|
||||
#endif
|
||||
|
||||
#include <process.h>
|
||||
#include <stdint.h>
|
||||
#include <winsock2.h>
|
||||
#include <mswsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <process.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "tree.h"
|
||||
@@ -43,32 +45,50 @@ typedef intptr_t ssize_t;
|
||||
#define MAX_PIPENAME_LEN 256
|
||||
|
||||
#ifndef S_IFLNK
|
||||
# define S_IFLNK 0xA000
|
||||
# define S_IFLNK 0xA000
|
||||
#endif
|
||||
|
||||
/* Additional signals supported by uv_signal and or uv_kill. The CRT defines
|
||||
* the following signals already:
|
||||
*
|
||||
* #define SIGINT 2
|
||||
* #define SIGILL 4
|
||||
* #define SIGABRT_COMPAT 6
|
||||
* #define SIGFPE 8
|
||||
* #define SIGSEGV 11
|
||||
* #define SIGTERM 15
|
||||
* #define SIGBREAK 21
|
||||
* #define SIGABRT 22
|
||||
*
|
||||
* The additional signals have values that are common on other Unix
|
||||
* variants (Linux and Darwin)
|
||||
*/
|
||||
#define SIGHUP 1
|
||||
#define SIGKILL 9
|
||||
|
||||
/*
|
||||
* Guids and typedefs for winsock extension functions
|
||||
* Mingw32 doesn't have these :-(
|
||||
*/
|
||||
#ifndef WSAID_ACCEPTEX
|
||||
# define WSAID_ACCEPTEX \
|
||||
{0xb5367df1, 0xcbac, 0x11cf, \
|
||||
# define WSAID_ACCEPTEX \
|
||||
{0xb5367df1, 0xcbac, 0x11cf, \
|
||||
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
|
||||
|
||||
# define WSAID_CONNECTEX \
|
||||
{0x25a207b9, 0xddf3, 0x4660, \
|
||||
# define WSAID_CONNECTEX \
|
||||
{0x25a207b9, 0xddf3, 0x4660, \
|
||||
{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}}
|
||||
|
||||
# define WSAID_GETACCEPTEXSOCKADDRS \
|
||||
{0xb5367df2, 0xcbac, 0x11cf, \
|
||||
# define WSAID_GETACCEPTEXSOCKADDRS \
|
||||
{0xb5367df2, 0xcbac, 0x11cf, \
|
||||
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
|
||||
|
||||
# define WSAID_DISCONNECTEX \
|
||||
{0x7fda2e11, 0x8630, 0x436f, \
|
||||
# define WSAID_DISCONNECTEX \
|
||||
{0x7fda2e11, 0x8630, 0x436f, \
|
||||
{0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57}}
|
||||
|
||||
# define WSAID_TRANSMITFILE \
|
||||
{0xb5367df0, 0xcbac, 0x11cf, \
|
||||
# define WSAID_TRANSMITFILE \
|
||||
{0xb5367df0, 0xcbac, 0x11cf, \
|
||||
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
|
||||
|
||||
typedef BOOL PASCAL (*LPFN_ACCEPTEX)
|
||||
@@ -246,272 +266,281 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
||||
/* Counter to keep track of active udp streams */ \
|
||||
unsigned int active_udp_streams;
|
||||
|
||||
#define UV_REQ_TYPE_PRIVATE \
|
||||
/* TODO: remove the req suffix */ \
|
||||
UV_ACCEPT, \
|
||||
UV_FS_EVENT_REQ, \
|
||||
UV_POLL_REQ, \
|
||||
UV_PROCESS_EXIT, \
|
||||
UV_PROCESS_CLOSE, \
|
||||
UV_READ, \
|
||||
UV_UDP_RECV, \
|
||||
UV_WAKEUP,
|
||||
#define UV_REQ_TYPE_PRIVATE \
|
||||
/* TODO: remove the req suffix */ \
|
||||
UV_ACCEPT, \
|
||||
UV_FS_EVENT_REQ, \
|
||||
UV_POLL_REQ, \
|
||||
UV_PROCESS_EXIT, \
|
||||
UV_READ, \
|
||||
UV_UDP_RECV, \
|
||||
UV_WAKEUP, \
|
||||
UV_SIGNAL_REQ,
|
||||
|
||||
#define UV_REQ_PRIVATE_FIELDS \
|
||||
union { \
|
||||
/* Used by I/O operations */ \
|
||||
struct { \
|
||||
OVERLAPPED overlapped; \
|
||||
size_t queued_bytes; \
|
||||
}; \
|
||||
}; \
|
||||
#define UV_REQ_PRIVATE_FIELDS \
|
||||
union { \
|
||||
/* Used by I/O operations */ \
|
||||
struct { \
|
||||
OVERLAPPED overlapped; \
|
||||
size_t queued_bytes; \
|
||||
}; \
|
||||
}; \
|
||||
struct uv_req_s* next_req;
|
||||
|
||||
#define UV_WRITE_PRIVATE_FIELDS \
|
||||
int ipc_header; \
|
||||
uv_buf_t write_buffer; \
|
||||
HANDLE event_handle; \
|
||||
#define UV_WRITE_PRIVATE_FIELDS \
|
||||
int ipc_header; \
|
||||
uv_buf_t write_buffer; \
|
||||
HANDLE event_handle; \
|
||||
HANDLE wait_handle;
|
||||
|
||||
#define UV_CONNECT_PRIVATE_FIELDS \
|
||||
#define UV_CONNECT_PRIVATE_FIELDS \
|
||||
/* empty */
|
||||
|
||||
#define UV_SHUTDOWN_PRIVATE_FIELDS \
|
||||
#define UV_SHUTDOWN_PRIVATE_FIELDS \
|
||||
/* empty */
|
||||
|
||||
#define UV_UDP_SEND_PRIVATE_FIELDS \
|
||||
#define UV_UDP_SEND_PRIVATE_FIELDS \
|
||||
/* empty */
|
||||
|
||||
#define UV_PRIVATE_REQ_TYPES \
|
||||
typedef struct uv_pipe_accept_s { \
|
||||
UV_REQ_FIELDS \
|
||||
HANDLE pipeHandle; \
|
||||
struct uv_pipe_accept_s* next_pending; \
|
||||
} uv_pipe_accept_t; \
|
||||
\
|
||||
typedef struct uv_tcp_accept_s { \
|
||||
UV_REQ_FIELDS \
|
||||
SOCKET accept_socket; \
|
||||
char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \
|
||||
HANDLE event_handle; \
|
||||
HANDLE wait_handle; \
|
||||
struct uv_tcp_accept_s* next_pending; \
|
||||
} uv_tcp_accept_t; \
|
||||
\
|
||||
typedef struct uv_read_s { \
|
||||
UV_REQ_FIELDS \
|
||||
HANDLE event_handle; \
|
||||
HANDLE wait_handle; \
|
||||
#define UV_PRIVATE_REQ_TYPES \
|
||||
typedef struct uv_pipe_accept_s { \
|
||||
UV_REQ_FIELDS \
|
||||
HANDLE pipeHandle; \
|
||||
struct uv_pipe_accept_s* next_pending; \
|
||||
} uv_pipe_accept_t; \
|
||||
\
|
||||
typedef struct uv_tcp_accept_s { \
|
||||
UV_REQ_FIELDS \
|
||||
SOCKET accept_socket; \
|
||||
char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \
|
||||
HANDLE event_handle; \
|
||||
HANDLE wait_handle; \
|
||||
struct uv_tcp_accept_s* next_pending; \
|
||||
} uv_tcp_accept_t; \
|
||||
\
|
||||
typedef struct uv_read_s { \
|
||||
UV_REQ_FIELDS \
|
||||
HANDLE event_handle; \
|
||||
HANDLE wait_handle; \
|
||||
} uv_read_t;
|
||||
|
||||
#define uv_stream_connection_fields \
|
||||
unsigned int write_reqs_pending; \
|
||||
#define uv_stream_connection_fields \
|
||||
unsigned int write_reqs_pending; \
|
||||
uv_shutdown_t* shutdown_req;
|
||||
|
||||
#define uv_stream_server_fields \
|
||||
#define uv_stream_server_fields \
|
||||
uv_connection_cb connection_cb;
|
||||
|
||||
#define UV_STREAM_PRIVATE_FIELDS \
|
||||
unsigned int reqs_pending; \
|
||||
int activecnt; \
|
||||
uv_read_t read_req; \
|
||||
union { \
|
||||
struct { uv_stream_connection_fields }; \
|
||||
struct { uv_stream_server_fields }; \
|
||||
#define UV_STREAM_PRIVATE_FIELDS \
|
||||
unsigned int reqs_pending; \
|
||||
int activecnt; \
|
||||
uv_read_t read_req; \
|
||||
union { \
|
||||
struct { uv_stream_connection_fields }; \
|
||||
struct { uv_stream_server_fields }; \
|
||||
};
|
||||
|
||||
#define uv_tcp_server_fields \
|
||||
uv_tcp_accept_t* accept_reqs; \
|
||||
unsigned int processed_accepts; \
|
||||
uv_tcp_accept_t* pending_accepts; \
|
||||
#define uv_tcp_server_fields \
|
||||
uv_tcp_accept_t* accept_reqs; \
|
||||
unsigned int processed_accepts; \
|
||||
uv_tcp_accept_t* pending_accepts; \
|
||||
LPFN_ACCEPTEX func_acceptex;
|
||||
|
||||
#define uv_tcp_connection_fields \
|
||||
uv_buf_t read_buffer; \
|
||||
#define uv_tcp_connection_fields \
|
||||
uv_buf_t read_buffer; \
|
||||
LPFN_CONNECTEX func_connectex;
|
||||
|
||||
#define UV_TCP_PRIVATE_FIELDS \
|
||||
SOCKET socket; \
|
||||
int bind_error; \
|
||||
union { \
|
||||
struct { uv_tcp_server_fields }; \
|
||||
struct { uv_tcp_connection_fields }; \
|
||||
#define UV_TCP_PRIVATE_FIELDS \
|
||||
SOCKET socket; \
|
||||
int bind_error; \
|
||||
union { \
|
||||
struct { uv_tcp_server_fields }; \
|
||||
struct { uv_tcp_connection_fields }; \
|
||||
};
|
||||
|
||||
#define UV_UDP_PRIVATE_FIELDS \
|
||||
SOCKET socket; \
|
||||
unsigned int reqs_pending; \
|
||||
int activecnt; \
|
||||
uv_req_t recv_req; \
|
||||
uv_buf_t recv_buffer; \
|
||||
struct sockaddr_storage recv_from; \
|
||||
int recv_from_len; \
|
||||
uv_udp_recv_cb recv_cb; \
|
||||
uv_alloc_cb alloc_cb; \
|
||||
LPFN_WSARECV func_wsarecv; \
|
||||
#define UV_UDP_PRIVATE_FIELDS \
|
||||
SOCKET socket; \
|
||||
unsigned int reqs_pending; \
|
||||
int activecnt; \
|
||||
uv_req_t recv_req; \
|
||||
uv_buf_t recv_buffer; \
|
||||
struct sockaddr_storage recv_from; \
|
||||
int recv_from_len; \
|
||||
uv_udp_recv_cb recv_cb; \
|
||||
uv_alloc_cb alloc_cb; \
|
||||
LPFN_WSARECV func_wsarecv; \
|
||||
LPFN_WSARECVFROM func_wsarecvfrom;
|
||||
|
||||
#define uv_pipe_server_fields \
|
||||
int pending_instances; \
|
||||
uv_pipe_accept_t* accept_reqs; \
|
||||
#define uv_pipe_server_fields \
|
||||
int pending_instances; \
|
||||
uv_pipe_accept_t* accept_reqs; \
|
||||
uv_pipe_accept_t* pending_accepts;
|
||||
|
||||
#define uv_pipe_connection_fields \
|
||||
uv_timer_t* eof_timer; \
|
||||
uv_write_t ipc_header_write_req; \
|
||||
int ipc_pid; \
|
||||
uint64_t remaining_ipc_rawdata_bytes; \
|
||||
unsigned char reserved[sizeof(void*)]; \
|
||||
struct { \
|
||||
WSAPROTOCOL_INFOW* socket_info; \
|
||||
int tcp_connection; \
|
||||
} pending_ipc_info; \
|
||||
#define uv_pipe_connection_fields \
|
||||
uv_timer_t* eof_timer; \
|
||||
uv_write_t ipc_header_write_req; \
|
||||
int ipc_pid; \
|
||||
uint64_t remaining_ipc_rawdata_bytes; \
|
||||
unsigned char reserved[sizeof(void*)]; \
|
||||
struct { \
|
||||
WSAPROTOCOL_INFOW* socket_info; \
|
||||
int tcp_connection; \
|
||||
} pending_ipc_info; \
|
||||
uv_write_t* non_overlapped_writes_tail;
|
||||
|
||||
#define UV_PIPE_PRIVATE_FIELDS \
|
||||
HANDLE handle; \
|
||||
wchar_t* name; \
|
||||
union { \
|
||||
struct { uv_pipe_server_fields }; \
|
||||
struct { uv_pipe_connection_fields }; \
|
||||
#define UV_PIPE_PRIVATE_FIELDS \
|
||||
HANDLE handle; \
|
||||
WCHAR* name; \
|
||||
union { \
|
||||
struct { uv_pipe_server_fields }; \
|
||||
struct { uv_pipe_connection_fields }; \
|
||||
};
|
||||
|
||||
/* TODO: put the parser states in an union - TTY handles are always */
|
||||
/* half-duplex so read-state can safely overlap write-state. */
|
||||
#define UV_TTY_PRIVATE_FIELDS \
|
||||
HANDLE handle; \
|
||||
HANDLE read_line_handle; \
|
||||
uv_buf_t read_line_buffer; \
|
||||
HANDLE read_raw_wait; \
|
||||
DWORD original_console_mode; \
|
||||
/* Fields used for translating win */ \
|
||||
/* keystrokes into vt100 characters */ \
|
||||
char last_key[8]; \
|
||||
unsigned char last_key_offset; \
|
||||
unsigned char last_key_len; \
|
||||
INPUT_RECORD last_input_record; \
|
||||
WCHAR last_utf16_high_surrogate; \
|
||||
/* utf8-to-utf16 conversion state */ \
|
||||
unsigned char utf8_bytes_left; \
|
||||
unsigned int utf8_codepoint; \
|
||||
/* eol conversion state */ \
|
||||
unsigned char previous_eol; \
|
||||
/* ansi parser state */ \
|
||||
unsigned char ansi_parser_state; \
|
||||
unsigned char ansi_csi_argc; \
|
||||
unsigned short ansi_csi_argv[4]; \
|
||||
COORD saved_position; \
|
||||
WORD saved_attributes;
|
||||
|
||||
#define UV_POLL_PRIVATE_FIELDS \
|
||||
SOCKET socket; \
|
||||
/* Used in fast mode */ \
|
||||
SOCKET peer_socket; \
|
||||
AFD_POLL_INFO afd_poll_info_1; \
|
||||
AFD_POLL_INFO afd_poll_info_2; \
|
||||
/* Used in fast and slow mode. */ \
|
||||
uv_req_t poll_req_1; \
|
||||
uv_req_t poll_req_2; \
|
||||
unsigned char submitted_events_1; \
|
||||
unsigned char submitted_events_2; \
|
||||
unsigned char mask_events_1; \
|
||||
unsigned char mask_events_2; \
|
||||
unsigned char events;
|
||||
|
||||
#define UV_TIMER_PRIVATE_FIELDS \
|
||||
RB_ENTRY(uv_timer_s) tree_entry; \
|
||||
int64_t due; \
|
||||
int64_t repeat; \
|
||||
uv_timer_cb timer_cb;
|
||||
|
||||
#define UV_ASYNC_PRIVATE_FIELDS \
|
||||
struct uv_req_s async_req; \
|
||||
uv_async_cb async_cb; \
|
||||
/* char to avoid alignment issues */ \
|
||||
char volatile async_sent;
|
||||
|
||||
#define UV_PREPARE_PRIVATE_FIELDS \
|
||||
uv_prepare_t* prepare_prev; \
|
||||
uv_prepare_t* prepare_next; \
|
||||
uv_prepare_cb prepare_cb;
|
||||
|
||||
#define UV_CHECK_PRIVATE_FIELDS \
|
||||
uv_check_t* check_prev; \
|
||||
uv_check_t* check_next; \
|
||||
uv_check_cb check_cb;
|
||||
|
||||
#define UV_IDLE_PRIVATE_FIELDS \
|
||||
uv_idle_t* idle_prev; \
|
||||
uv_idle_t* idle_next; \
|
||||
uv_idle_cb idle_cb;
|
||||
|
||||
#define UV_HANDLE_PRIVATE_FIELDS \
|
||||
uv_handle_t* endgame_next; \
|
||||
unsigned int flags;
|
||||
|
||||
#define UV_GETADDRINFO_PRIVATE_FIELDS \
|
||||
uv_getaddrinfo_cb getaddrinfo_cb; \
|
||||
void* alloc; \
|
||||
wchar_t* node; \
|
||||
wchar_t* service; \
|
||||
struct addrinfoW* hints; \
|
||||
struct addrinfoW* res; \
|
||||
int retcode;
|
||||
|
||||
#define UV_PROCESS_PRIVATE_FIELDS \
|
||||
struct uv_process_exit_s { \
|
||||
UV_REQ_FIELDS \
|
||||
} exit_req; \
|
||||
struct uv_process_close_s { \
|
||||
UV_REQ_FIELDS \
|
||||
} close_req; \
|
||||
BYTE* child_stdio_buffer; \
|
||||
int exit_signal; \
|
||||
DWORD spawn_errno; \
|
||||
HANDLE wait_handle; \
|
||||
HANDLE process_handle; \
|
||||
HANDLE close_handle;
|
||||
|
||||
#define UV_FS_PRIVATE_FIELDS \
|
||||
int flags; \
|
||||
DWORD sys_errno_; \
|
||||
union { \
|
||||
/* TODO: remove me in 0.9. */ \
|
||||
WCHAR* pathw; \
|
||||
int fd; \
|
||||
}; \
|
||||
union { \
|
||||
struct { \
|
||||
int mode; \
|
||||
WCHAR* new_pathw; \
|
||||
int file_flags; \
|
||||
int fd_out; \
|
||||
void* buf; \
|
||||
size_t length; \
|
||||
int64_t offset; \
|
||||
}; \
|
||||
struct _stati64 stat; \
|
||||
struct { \
|
||||
double atime; \
|
||||
double mtime; \
|
||||
}; \
|
||||
#define UV_TTY_PRIVATE_FIELDS \
|
||||
HANDLE handle; \
|
||||
union { \
|
||||
struct { \
|
||||
/* Used for readable TTY handles */ \
|
||||
HANDLE read_line_handle; \
|
||||
uv_buf_t read_line_buffer; \
|
||||
HANDLE read_raw_wait; \
|
||||
DWORD original_console_mode; \
|
||||
/* Fields used for translating win keystrokes into vt100 characters */ \
|
||||
char last_key[8]; \
|
||||
unsigned char last_key_offset; \
|
||||
unsigned char last_key_len; \
|
||||
WCHAR last_utf16_high_surrogate; \
|
||||
INPUT_RECORD last_input_record; \
|
||||
}; \
|
||||
struct { \
|
||||
/* Used for writable TTY handles */ \
|
||||
/* utf8-to-utf16 conversion state */ \
|
||||
unsigned int utf8_codepoint; \
|
||||
unsigned char utf8_bytes_left; \
|
||||
/* eol conversion state */ \
|
||||
unsigned char previous_eol; \
|
||||
/* ansi parser state */ \
|
||||
unsigned char ansi_parser_state; \
|
||||
unsigned char ansi_csi_argc; \
|
||||
unsigned short ansi_csi_argv[4]; \
|
||||
COORD saved_position; \
|
||||
WORD saved_attributes; \
|
||||
}; \
|
||||
};
|
||||
|
||||
#define UV_WORK_PRIVATE_FIELDS \
|
||||
#define UV_POLL_PRIVATE_FIELDS \
|
||||
SOCKET socket; \
|
||||
/* Used in fast mode */ \
|
||||
SOCKET peer_socket; \
|
||||
AFD_POLL_INFO afd_poll_info_1; \
|
||||
AFD_POLL_INFO afd_poll_info_2; \
|
||||
/* Used in fast and slow mode. */ \
|
||||
uv_req_t poll_req_1; \
|
||||
uv_req_t poll_req_2; \
|
||||
unsigned char submitted_events_1; \
|
||||
unsigned char submitted_events_2; \
|
||||
unsigned char mask_events_1; \
|
||||
unsigned char mask_events_2; \
|
||||
unsigned char events;
|
||||
|
||||
#define UV_FS_EVENT_PRIVATE_FIELDS \
|
||||
struct uv_fs_event_req_s { \
|
||||
UV_REQ_FIELDS \
|
||||
} req; \
|
||||
HANDLE dir_handle; \
|
||||
int req_pending; \
|
||||
uv_fs_event_cb cb; \
|
||||
wchar_t* filew; \
|
||||
wchar_t* short_filew; \
|
||||
wchar_t* dirw; \
|
||||
#define UV_TIMER_PRIVATE_FIELDS \
|
||||
RB_ENTRY(uv_timer_s) tree_entry; \
|
||||
int64_t due; \
|
||||
int64_t repeat; \
|
||||
uv_timer_cb timer_cb;
|
||||
|
||||
#define UV_ASYNC_PRIVATE_FIELDS \
|
||||
struct uv_req_s async_req; \
|
||||
uv_async_cb async_cb; \
|
||||
/* char to avoid alignment issues */ \
|
||||
char volatile async_sent;
|
||||
|
||||
#define UV_PREPARE_PRIVATE_FIELDS \
|
||||
uv_prepare_t* prepare_prev; \
|
||||
uv_prepare_t* prepare_next; \
|
||||
uv_prepare_cb prepare_cb;
|
||||
|
||||
#define UV_CHECK_PRIVATE_FIELDS \
|
||||
uv_check_t* check_prev; \
|
||||
uv_check_t* check_next; \
|
||||
uv_check_cb check_cb;
|
||||
|
||||
#define UV_IDLE_PRIVATE_FIELDS \
|
||||
uv_idle_t* idle_prev; \
|
||||
uv_idle_t* idle_next; \
|
||||
uv_idle_cb idle_cb;
|
||||
|
||||
#define UV_HANDLE_PRIVATE_FIELDS \
|
||||
uv_handle_t* endgame_next; \
|
||||
unsigned int flags;
|
||||
|
||||
#define UV_GETADDRINFO_PRIVATE_FIELDS \
|
||||
uv_getaddrinfo_cb getaddrinfo_cb; \
|
||||
void* alloc; \
|
||||
WCHAR* node; \
|
||||
WCHAR* service; \
|
||||
struct addrinfoW* hints; \
|
||||
struct addrinfoW* res; \
|
||||
int retcode;
|
||||
|
||||
#define UV_PROCESS_PRIVATE_FIELDS \
|
||||
struct uv_process_exit_s { \
|
||||
UV_REQ_FIELDS \
|
||||
} exit_req; \
|
||||
BYTE* child_stdio_buffer; \
|
||||
uv_err_t spawn_error; \
|
||||
int exit_signal; \
|
||||
HANDLE wait_handle; \
|
||||
HANDLE process_handle; \
|
||||
volatile char exit_cb_pending;
|
||||
|
||||
#define UV_FS_PRIVATE_FIELDS \
|
||||
int flags; \
|
||||
DWORD sys_errno_; \
|
||||
union { \
|
||||
/* TODO: remove me in 0.9. */ \
|
||||
WCHAR* pathw; \
|
||||
int fd; \
|
||||
}; \
|
||||
union { \
|
||||
struct { \
|
||||
int mode; \
|
||||
WCHAR* new_pathw; \
|
||||
int file_flags; \
|
||||
int fd_out; \
|
||||
void* buf; \
|
||||
size_t length; \
|
||||
int64_t offset; \
|
||||
}; \
|
||||
struct _stati64 stat; \
|
||||
struct { \
|
||||
double atime; \
|
||||
double mtime; \
|
||||
}; \
|
||||
};
|
||||
|
||||
#define UV_WORK_PRIVATE_FIELDS \
|
||||
|
||||
#define UV_FS_EVENT_PRIVATE_FIELDS \
|
||||
struct uv_fs_event_req_s { \
|
||||
UV_REQ_FIELDS \
|
||||
} req; \
|
||||
HANDLE dir_handle; \
|
||||
int req_pending; \
|
||||
uv_fs_event_cb cb; \
|
||||
WCHAR* filew; \
|
||||
WCHAR* short_filew; \
|
||||
WCHAR* dirw; \
|
||||
char* buffer;
|
||||
|
||||
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
|
||||
#define UV_SIGNAL_PRIVATE_FIELDS \
|
||||
RB_ENTRY(uv_signal_s) tree_entry; \
|
||||
struct uv_req_s signal_req; \
|
||||
unsigned long pending_signum;
|
||||
|
||||
int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
|
||||
char* utf8Buffer, size_t utf8Size);
|
||||
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
|
||||
int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
|
||||
size_t utf16Size);
|
||||
|
||||
292
deps/uv/include/uv.h
vendored
292
deps/uv/include/uv.h
vendored
@@ -19,7 +19,7 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* See uv_loop_new for an introduction. */
|
||||
/* See http://nikhilm.github.com/uvbook/ for an introduction. */
|
||||
|
||||
#ifndef UV_H
|
||||
#define UV_H
|
||||
@@ -53,6 +53,10 @@ extern "C" {
|
||||
#include <stdint.h> /* int64_t */
|
||||
#include <sys/types.h> /* size_t */
|
||||
|
||||
#if defined(__SVR4) && !defined(__unix__)
|
||||
# define __unix__
|
||||
#endif
|
||||
|
||||
#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
|
||||
# include "uv-private/uv-unix.h"
|
||||
#else
|
||||
@@ -60,64 +64,64 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Expand this list if necessary. */
|
||||
#define UV_ERRNO_MAP(XX) \
|
||||
XX( -1, UNKNOWN, "unknown error") \
|
||||
XX( 0, OK, "success") \
|
||||
XX( 1, EOF, "end of file") \
|
||||
XX( 2, EADDRINFO, "getaddrinfo error") \
|
||||
XX( 3, EACCES, "permission denied") \
|
||||
XX( 4, EAGAIN, "no more processes") \
|
||||
XX( 5, EADDRINUSE, "address already in use") \
|
||||
XX( 6, EADDRNOTAVAIL, "") \
|
||||
XX( 7, EAFNOSUPPORT, "") \
|
||||
XX( 8, EALREADY, "") \
|
||||
XX( 9, EBADF, "bad file descriptor") \
|
||||
XX( 10, EBUSY, "resource busy or locked") \
|
||||
XX( 11, ECONNABORTED, "software caused connection abort") \
|
||||
XX( 12, ECONNREFUSED, "connection refused") \
|
||||
XX( 13, ECONNRESET, "connection reset by peer") \
|
||||
XX( 14, EDESTADDRREQ, "destination address required") \
|
||||
XX( 15, EFAULT, "bad address in system call argument") \
|
||||
XX( 16, EHOSTUNREACH, "host is unreachable") \
|
||||
XX( 17, EINTR, "interrupted system call") \
|
||||
XX( 18, EINVAL, "invalid argument") \
|
||||
XX( 19, EISCONN, "socket is already connected") \
|
||||
XX( 20, EMFILE, "too many open files") \
|
||||
XX( 21, EMSGSIZE, "message too long") \
|
||||
XX( 22, ENETDOWN, "network is down") \
|
||||
XX( 23, ENETUNREACH, "network is unreachable") \
|
||||
XX( 24, ENFILE, "file table overflow") \
|
||||
XX( 25, ENOBUFS, "no buffer space available") \
|
||||
XX( 26, ENOMEM, "not enough memory") \
|
||||
XX( 27, ENOTDIR, "not a directory") \
|
||||
XX( 28, EISDIR, "illegal operation on a directory") \
|
||||
XX( 29, ENONET, "machine is not on the network") \
|
||||
XX( 31, ENOTCONN, "socket is not connected") \
|
||||
XX( 32, ENOTSOCK, "socket operation on non-socket") \
|
||||
XX( 33, ENOTSUP, "operation not supported on socket") \
|
||||
XX( 34, ENOENT, "no such file or directory") \
|
||||
XX( 35, ENOSYS, "function not implemented") \
|
||||
XX( 36, EPIPE, "broken pipe") \
|
||||
XX( 37, EPROTO, "protocol error") \
|
||||
XX( 38, EPROTONOSUPPORT, "protocol not supported") \
|
||||
XX( 39, EPROTOTYPE, "protocol wrong type for socket") \
|
||||
XX( 40, ETIMEDOUT, "connection timed out") \
|
||||
XX( 41, ECHARSET, "") \
|
||||
XX( 42, EAIFAMNOSUPPORT, "") \
|
||||
XX( 44, EAISERVICE, "") \
|
||||
XX( 45, EAISOCKTYPE, "") \
|
||||
XX( 46, ESHUTDOWN, "") \
|
||||
XX( 47, EEXIST, "file already exists") \
|
||||
XX( 48, ESRCH, "no such process") \
|
||||
XX( 49, ENAMETOOLONG, "name too long") \
|
||||
XX( 50, EPERM, "operation not permitted") \
|
||||
XX( 51, ELOOP, "too many symbolic links encountered") \
|
||||
XX( 52, EXDEV, "cross-device link not permitted") \
|
||||
XX( 53, ENOTEMPTY, "directory not empty") \
|
||||
XX( 54, ENOSPC, "no space left on device") \
|
||||
XX( 55, EIO, "i/o error") \
|
||||
XX( 56, EROFS, "read-only file system" ) \
|
||||
XX( 57, ENODEV, "no such device" ) \
|
||||
#define UV_ERRNO_MAP(XX) \
|
||||
XX( -1, UNKNOWN, "unknown error") \
|
||||
XX( 0, OK, "success") \
|
||||
XX( 1, EOF, "end of file") \
|
||||
XX( 2, EADDRINFO, "getaddrinfo error") \
|
||||
XX( 3, EACCES, "permission denied") \
|
||||
XX( 4, EAGAIN, "no more processes") \
|
||||
XX( 5, EADDRINUSE, "address already in use") \
|
||||
XX( 6, EADDRNOTAVAIL, "") \
|
||||
XX( 7, EAFNOSUPPORT, "") \
|
||||
XX( 8, EALREADY, "") \
|
||||
XX( 9, EBADF, "bad file descriptor") \
|
||||
XX( 10, EBUSY, "resource busy or locked") \
|
||||
XX( 11, ECONNABORTED, "software caused connection abort") \
|
||||
XX( 12, ECONNREFUSED, "connection refused") \
|
||||
XX( 13, ECONNRESET, "connection reset by peer") \
|
||||
XX( 14, EDESTADDRREQ, "destination address required") \
|
||||
XX( 15, EFAULT, "bad address in system call argument") \
|
||||
XX( 16, EHOSTUNREACH, "host is unreachable") \
|
||||
XX( 17, EINTR, "interrupted system call") \
|
||||
XX( 18, EINVAL, "invalid argument") \
|
||||
XX( 19, EISCONN, "socket is already connected") \
|
||||
XX( 20, EMFILE, "too many open files") \
|
||||
XX( 21, EMSGSIZE, "message too long") \
|
||||
XX( 22, ENETDOWN, "network is down") \
|
||||
XX( 23, ENETUNREACH, "network is unreachable") \
|
||||
XX( 24, ENFILE, "file table overflow") \
|
||||
XX( 25, ENOBUFS, "no buffer space available") \
|
||||
XX( 26, ENOMEM, "not enough memory") \
|
||||
XX( 27, ENOTDIR, "not a directory") \
|
||||
XX( 28, EISDIR, "illegal operation on a directory") \
|
||||
XX( 29, ENONET, "machine is not on the network") \
|
||||
XX( 31, ENOTCONN, "socket is not connected") \
|
||||
XX( 32, ENOTSOCK, "socket operation on non-socket") \
|
||||
XX( 33, ENOTSUP, "operation not supported on socket") \
|
||||
XX( 34, ENOENT, "no such file or directory") \
|
||||
XX( 35, ENOSYS, "function not implemented") \
|
||||
XX( 36, EPIPE, "broken pipe") \
|
||||
XX( 37, EPROTO, "protocol error") \
|
||||
XX( 38, EPROTONOSUPPORT, "protocol not supported") \
|
||||
XX( 39, EPROTOTYPE, "protocol wrong type for socket") \
|
||||
XX( 40, ETIMEDOUT, "connection timed out") \
|
||||
XX( 41, ECHARSET, "") \
|
||||
XX( 42, EAIFAMNOSUPPORT, "") \
|
||||
XX( 44, EAISERVICE, "") \
|
||||
XX( 45, EAISOCKTYPE, "") \
|
||||
XX( 46, ESHUTDOWN, "") \
|
||||
XX( 47, EEXIST, "file already exists") \
|
||||
XX( 48, ESRCH, "no such process") \
|
||||
XX( 49, ENAMETOOLONG, "name too long") \
|
||||
XX( 50, EPERM, "operation not permitted") \
|
||||
XX( 51, ELOOP, "too many symbolic links encountered") \
|
||||
XX( 52, EXDEV, "cross-device link not permitted") \
|
||||
XX( 53, ENOTEMPTY, "directory not empty") \
|
||||
XX( 54, ENOSPC, "no space left on device") \
|
||||
XX( 55, EIO, "i/o error") \
|
||||
XX( 56, EROFS, "read-only file system" ) \
|
||||
XX( 57, ENODEV, "no such device" ) \
|
||||
XX( 58, ECANCELED, "operation canceled" )
|
||||
|
||||
|
||||
@@ -128,29 +132,30 @@ typedef enum {
|
||||
} uv_err_code;
|
||||
#undef UV_ERRNO_GEN
|
||||
|
||||
#define UV_HANDLE_TYPE_MAP(XX) \
|
||||
XX(ASYNC, async) \
|
||||
XX(CHECK, check) \
|
||||
XX(FS_EVENT, fs_event) \
|
||||
XX(FS_POLL, fs_poll) \
|
||||
XX(IDLE, idle) \
|
||||
XX(NAMED_PIPE, pipe) \
|
||||
XX(POLL, poll) \
|
||||
XX(PREPARE, prepare) \
|
||||
XX(PROCESS, process) \
|
||||
XX(TCP, tcp) \
|
||||
XX(TIMER, timer) \
|
||||
XX(TTY, tty) \
|
||||
XX(UDP, udp) \
|
||||
#define UV_HANDLE_TYPE_MAP(XX) \
|
||||
XX(ASYNC, async) \
|
||||
XX(CHECK, check) \
|
||||
XX(FS_EVENT, fs_event) \
|
||||
XX(FS_POLL, fs_poll) \
|
||||
XX(IDLE, idle) \
|
||||
XX(NAMED_PIPE, pipe) \
|
||||
XX(POLL, poll) \
|
||||
XX(PREPARE, prepare) \
|
||||
XX(PROCESS, process) \
|
||||
XX(TCP, tcp) \
|
||||
XX(TIMER, timer) \
|
||||
XX(TTY, tty) \
|
||||
XX(UDP, udp) \
|
||||
XX(SIGNAL, signal) \
|
||||
|
||||
#define UV_REQ_TYPE_MAP(XX) \
|
||||
XX(CONNECT, connect) \
|
||||
XX(WRITE, write) \
|
||||
XX(SHUTDOWN, shutdown) \
|
||||
XX(UDP_SEND, udp_send) \
|
||||
XX(FS, fs) \
|
||||
XX(WORK, work) \
|
||||
XX(GETADDRINFO, getaddrinfo) \
|
||||
#define UV_REQ_TYPE_MAP(XX) \
|
||||
XX(CONNECT, connect) \
|
||||
XX(WRITE, write) \
|
||||
XX(SHUTDOWN, shutdown) \
|
||||
XX(UDP_SEND, udp_send) \
|
||||
XX(FS, fs) \
|
||||
XX(WORK, work) \
|
||||
XX(GETADDRINFO, getaddrinfo) \
|
||||
|
||||
typedef enum {
|
||||
UV_UNKNOWN_HANDLE = 0,
|
||||
@@ -189,6 +194,7 @@ typedef struct uv_async_s uv_async_t;
|
||||
typedef struct uv_process_s uv_process_t;
|
||||
typedef struct uv_fs_event_s uv_fs_event_t;
|
||||
typedef struct uv_fs_poll_s uv_fs_poll_t;
|
||||
typedef struct uv_signal_s uv_signal_t;
|
||||
|
||||
/* Request types. */
|
||||
typedef struct uv_req_s uv_req_t;
|
||||
@@ -312,6 +318,9 @@ typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle,
|
||||
const uv_statbuf_t* prev,
|
||||
const uv_statbuf_t* curr);
|
||||
|
||||
typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum);
|
||||
|
||||
|
||||
typedef enum {
|
||||
UV_LEAVE_GROUP = 0,
|
||||
UV_JOIN_GROUP
|
||||
@@ -336,14 +345,14 @@ UV_EXTERN const char* uv_strerror(uv_err_t err);
|
||||
UV_EXTERN const char* uv_err_name(uv_err_t err);
|
||||
|
||||
|
||||
#define UV_REQ_FIELDS \
|
||||
/* public */ \
|
||||
void* data; \
|
||||
/* private */ \
|
||||
ngx_queue_t active_queue; \
|
||||
UV_REQ_PRIVATE_FIELDS \
|
||||
/* read-only */ \
|
||||
uv_req_type type; \
|
||||
#define UV_REQ_FIELDS \
|
||||
/* public */ \
|
||||
void* data; \
|
||||
/* private */ \
|
||||
ngx_queue_t active_queue; \
|
||||
UV_REQ_PRIVATE_FIELDS \
|
||||
/* read-only */ \
|
||||
uv_req_type type; \
|
||||
|
||||
/* Abstract base class of all requests. */
|
||||
struct uv_req_s {
|
||||
@@ -454,13 +463,13 @@ UV_EXTERN size_t uv_strlcpy(char* dst, const char* src, size_t size);
|
||||
UV_EXTERN size_t uv_strlcat(char* dst, const char* src, size_t size);
|
||||
|
||||
|
||||
#define UV_STREAM_FIELDS \
|
||||
/* number of bytes queued for writing */ \
|
||||
size_t write_queue_size; \
|
||||
uv_alloc_cb alloc_cb; \
|
||||
uv_read_cb read_cb; \
|
||||
uv_read2_cb read2_cb; \
|
||||
/* private */ \
|
||||
#define UV_STREAM_FIELDS \
|
||||
/* number of bytes queued for writing */ \
|
||||
size_t write_queue_size; \
|
||||
uv_alloc_cb alloc_cb; \
|
||||
uv_read_cb read_cb; \
|
||||
uv_read2_cb read2_cb; \
|
||||
/* private */ \
|
||||
UV_STREAM_PRIVATE_FIELDS
|
||||
|
||||
/*
|
||||
@@ -1098,8 +1107,7 @@ UV_EXTERN int uv_async_send(uv_async_t* async);
|
||||
/*
|
||||
* uv_timer_t is a subclass of uv_handle_t.
|
||||
*
|
||||
* Wraps libev's ev_timer watcher. Used to get woken up at a specified time
|
||||
* in the future.
|
||||
* Used to get woken up at a specified time in the future.
|
||||
*/
|
||||
struct uv_timer_s {
|
||||
UV_HANDLE_FIELDS
|
||||
@@ -1108,8 +1116,22 @@ struct uv_timer_s {
|
||||
|
||||
UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* timer);
|
||||
|
||||
UV_EXTERN int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb,
|
||||
int64_t timeout, int64_t repeat);
|
||||
/*
|
||||
* Start the timer. `timeout` and `repeat` are in milliseconds.
|
||||
*
|
||||
* If timeout is zero, the callback fires on the next tick of the event loop.
|
||||
*
|
||||
* If repeat is non-zero, the callback fires first after timeout milliseconds
|
||||
* and then repeatedly after repeat milliseconds.
|
||||
*
|
||||
* timeout and repeat are signed integers but that will change in a future
|
||||
* version of libuv. Don't pass in negative values, you'll get a nasty surprise
|
||||
* when that change becomes effective.
|
||||
*/
|
||||
UV_EXTERN int uv_timer_start(uv_timer_t* timer,
|
||||
uv_timer_cb cb,
|
||||
int64_t timeout,
|
||||
int64_t repeat);
|
||||
|
||||
UV_EXTERN int uv_timer_stop(uv_timer_t* timer);
|
||||
|
||||
@@ -1121,10 +1143,10 @@ UV_EXTERN int uv_timer_stop(uv_timer_t* timer);
|
||||
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 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.
|
||||
* Set the repeat value in milliseconds. Note that if the repeat value is set
|
||||
* from a timer 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.
|
||||
*/
|
||||
UV_EXTERN void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat);
|
||||
|
||||
@@ -1529,14 +1551,17 @@ struct uv_fs_event_s {
|
||||
struct uv_fs_poll_s {
|
||||
UV_HANDLE_FIELDS
|
||||
/* Private, don't touch. */
|
||||
int busy_polling; /* TODO(bnoordhuis) Fold into flags field. */
|
||||
unsigned int interval;
|
||||
uint64_t start_time;
|
||||
char* path;
|
||||
uv_fs_poll_cb poll_cb;
|
||||
uv_timer_t timer_handle;
|
||||
uv_fs_t* fs_req;
|
||||
uv_statbuf_t statbuf;
|
||||
void* poll_ctx;
|
||||
/* v0.8 ABI compatibility */
|
||||
char padding[sizeof(int)
|
||||
+ sizeof(unsigned int)
|
||||
+ sizeof(uint64_t)
|
||||
+ sizeof(char*)
|
||||
+ sizeof(uv_fs_poll_cb)
|
||||
+ sizeof(uv_timer_t)
|
||||
+ sizeof(uv_fs_t*)
|
||||
+ sizeof(uv_statbuf_t)
|
||||
- sizeof(void*)];
|
||||
};
|
||||
|
||||
UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle);
|
||||
@@ -1563,6 +1588,46 @@ UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle,
|
||||
|
||||
UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
|
||||
|
||||
|
||||
/*
|
||||
* UNIX signal handling on a per-event loop basis. The implementation is not
|
||||
* ultra efficient so don't go creating a million event loops with a million
|
||||
* signal watchers.
|
||||
*
|
||||
* TODO(bnoordhuis) As of 2012-08-10 only the default event loop supports
|
||||
* signals. That will be fixed.
|
||||
*
|
||||
* Some signal support is available on Windows:
|
||||
*
|
||||
* SIGINT is normally delivered when the user presses CTRL+C. However, like
|
||||
* on Unix, it is not generated when terminal raw mode is enabled.
|
||||
*
|
||||
* SIGBREAK is delivered when the user pressed CTRL+BREAK.
|
||||
*
|
||||
* SIGHUP is generated when the user closes the console window. On SIGHUP the
|
||||
* program is given approximately 10 seconds to perform cleanup. After that
|
||||
* Windows will unconditionally terminate it.
|
||||
*
|
||||
* Watchers for other signals can be successfully created, but these signals
|
||||
* are never generated. These signals are: SIGILL, SIGABRT, SIGFPE, SIGSEGV,
|
||||
* SIGTERM and SIGKILL.
|
||||
*
|
||||
* Note that calls to raise() or abort() to programmatically raise a signal are
|
||||
* not detected by libuv; these will not trigger a signal watcher.
|
||||
*/
|
||||
struct uv_signal_s {
|
||||
UV_HANDLE_FIELDS
|
||||
uv_signal_cb signal_cb;
|
||||
UV_SIGNAL_PRIVATE_FIELDS
|
||||
int signum;
|
||||
};
|
||||
|
||||
/* These functions are no-ops on Windows. */
|
||||
int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle);
|
||||
int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum);
|
||||
int uv_signal_stop(uv_signal_t* handle);
|
||||
|
||||
|
||||
/*
|
||||
* Gets load avg
|
||||
* See: http://en.wikipedia.org/wiki/Load_(computing)
|
||||
@@ -1772,8 +1837,6 @@ struct uv_counters_s {
|
||||
|
||||
struct uv_loop_s {
|
||||
UV_LOOP_PRIVATE_FIELDS
|
||||
/* Diagnostic counters */
|
||||
uv_counters_t counters;
|
||||
/* The last error */
|
||||
uv_err_t last_err;
|
||||
/* Loop reference counting */
|
||||
@@ -1800,6 +1863,7 @@ struct uv_loop_s {
|
||||
#undef UV_FS_REQ_PRIVATE_FIELDS
|
||||
#undef UV_WORK_PRIVATE_FIELDS
|
||||
#undef UV_FS_EVENT_PRIVATE_FIELDS
|
||||
#undef UV_SIGNAL_PRIVATE_FIELDS
|
||||
#undef UV_LOOP_PRIVATE_FIELDS
|
||||
#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS
|
||||
|
||||
|
||||
150
deps/uv/src/fs-poll.c
vendored
150
deps/uv/src/fs-poll.c
vendored
@@ -26,24 +26,29 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct poll_ctx {
|
||||
uv_fs_poll_t* parent_handle; /* NULL if parent has been stopped or closed */
|
||||
int busy_polling;
|
||||
unsigned int interval;
|
||||
uint64_t start_time;
|
||||
uv_loop_t* loop;
|
||||
uv_fs_poll_cb poll_cb;
|
||||
uv_timer_t timer_handle;
|
||||
uv_fs_t fs_req; /* TODO(bnoordhuis) mark fs_req internal */
|
||||
uv_statbuf_t statbuf;
|
||||
char path[1]; /* variable length */
|
||||
};
|
||||
|
||||
static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b);
|
||||
static void timer_cb(uv_timer_t* timer, int status);
|
||||
static void poll_cb(uv_fs_t* req);
|
||||
static void timer_cb(uv_timer_t* timer, int status);
|
||||
static void timer_close_cb(uv_handle_t* handle);
|
||||
|
||||
static uv_statbuf_t zero_statbuf;
|
||||
|
||||
|
||||
int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) {
|
||||
/* TODO(bnoordhuis) Mark fs_req internal. */
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_POLL);
|
||||
loop->counters.fs_poll_init++;
|
||||
|
||||
if (uv_timer_init(loop, &handle->timer_handle))
|
||||
return -1;
|
||||
|
||||
handle->timer_handle.flags |= UV__HANDLE_INTERNAL;
|
||||
uv__handle_unref(&handle->timer_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -52,30 +57,37 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
|
||||
uv_fs_poll_cb cb,
|
||||
const char* path,
|
||||
unsigned int interval) {
|
||||
uv_fs_t* req;
|
||||
struct poll_ctx* ctx;
|
||||
uv_loop_t* loop;
|
||||
size_t len;
|
||||
|
||||
if (uv__is_active(handle))
|
||||
return 0;
|
||||
|
||||
len = strlen(path) + 1;
|
||||
req = malloc(sizeof(*req) + len);
|
||||
loop = handle->loop;
|
||||
len = strlen(path);
|
||||
ctx = calloc(1, sizeof(*ctx) + len);
|
||||
|
||||
if (req == NULL)
|
||||
return uv__set_artificial_error(handle->loop, UV_ENOMEM);
|
||||
if (ctx == NULL)
|
||||
return uv__set_artificial_error(loop, UV_ENOMEM);
|
||||
|
||||
req->data = handle;
|
||||
handle->path = memcpy(req + 1, path, len);
|
||||
handle->fs_req = req;
|
||||
handle->poll_cb = cb;
|
||||
handle->interval = interval ? interval : 1;
|
||||
handle->start_time = uv_now(handle->loop);
|
||||
handle->busy_polling = 0;
|
||||
memset(&handle->statbuf, 0, sizeof(handle->statbuf));
|
||||
ctx->loop = loop;
|
||||
ctx->poll_cb = cb;
|
||||
ctx->interval = interval ? interval : 1;
|
||||
ctx->start_time = uv_now(loop);
|
||||
ctx->parent_handle = handle;
|
||||
memcpy(ctx->path, path, len + 1);
|
||||
|
||||
if (uv_fs_stat(handle->loop, handle->fs_req, handle->path, poll_cb))
|
||||
if (uv_timer_init(loop, &ctx->timer_handle))
|
||||
abort();
|
||||
|
||||
ctx->timer_handle.flags |= UV__HANDLE_INTERNAL;
|
||||
uv__handle_unref(&ctx->timer_handle);
|
||||
|
||||
if (uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb))
|
||||
abort();
|
||||
|
||||
handle->poll_ctx = ctx;
|
||||
uv__handle_start(handle);
|
||||
|
||||
return 0;
|
||||
@@ -83,25 +95,19 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
|
||||
|
||||
|
||||
int uv_fs_poll_stop(uv_fs_poll_t* handle) {
|
||||
struct poll_ctx* ctx;
|
||||
|
||||
if (!uv__is_active(handle))
|
||||
return 0;
|
||||
|
||||
/* Don't free the fs req if it's active. Signal poll_cb that it needs to free
|
||||
* the req by removing the handle backlink.
|
||||
*
|
||||
* TODO(bnoordhuis) Have uv-unix postpone the close callback until the req
|
||||
* finishes so we don't need this pointer / lifecycle hackery. The callback
|
||||
* always runs on the next tick now.
|
||||
*/
|
||||
if (handle->fs_req->data)
|
||||
handle->fs_req->data = NULL;
|
||||
else
|
||||
free(handle->fs_req);
|
||||
ctx = handle->poll_ctx;
|
||||
assert(ctx != NULL);
|
||||
assert(ctx->parent_handle != NULL);
|
||||
|
||||
handle->fs_req = NULL;
|
||||
handle->path = NULL;
|
||||
ctx->parent_handle = NULL;
|
||||
uv_timer_stop(&ctx->timer_handle);
|
||||
|
||||
uv_timer_stop(&handle->timer_handle);
|
||||
handle->poll_ctx = NULL;
|
||||
uv__handle_stop(handle);
|
||||
|
||||
return 0;
|
||||
@@ -110,73 +116,75 @@ int uv_fs_poll_stop(uv_fs_poll_t* handle) {
|
||||
|
||||
void uv__fs_poll_close(uv_fs_poll_t* handle) {
|
||||
uv_fs_poll_stop(handle);
|
||||
uv_close((uv_handle_t*)&handle->timer_handle, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void timer_cb(uv_timer_t* timer, int status) {
|
||||
uv_fs_poll_t* handle;
|
||||
struct poll_ctx* ctx;
|
||||
|
||||
handle = container_of(timer, uv_fs_poll_t, timer_handle);
|
||||
handle->start_time = uv_now(handle->loop);
|
||||
handle->fs_req->data = handle;
|
||||
ctx = container_of(timer, struct poll_ctx, timer_handle);
|
||||
|
||||
if (uv_fs_stat(handle->loop, handle->fs_req, handle->path, poll_cb))
|
||||
if (ctx->parent_handle == NULL) { /* handle has been stopped or closed */
|
||||
uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(ctx->parent_handle->poll_ctx == ctx);
|
||||
ctx->start_time = uv_now(ctx->loop);
|
||||
|
||||
if (uv_fs_stat(ctx->loop, &ctx->fs_req, ctx->path, poll_cb))
|
||||
abort();
|
||||
|
||||
assert(uv__is_active(handle));
|
||||
}
|
||||
|
||||
|
||||
static void poll_cb(uv_fs_t* req) {
|
||||
uv_statbuf_t* statbuf;
|
||||
uv_fs_poll_t* handle;
|
||||
struct poll_ctx* ctx;
|
||||
uint64_t interval;
|
||||
|
||||
handle = req->data;
|
||||
ctx = container_of(req, struct poll_ctx, fs_req);
|
||||
|
||||
if (handle == NULL) /* Handle has been stopped or closed. */
|
||||
goto out;
|
||||
|
||||
assert(req == handle->fs_req);
|
||||
if (ctx->parent_handle == NULL) { /* handle has been stopped or closed */
|
||||
uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
|
||||
uv_fs_req_cleanup(req);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->result != 0) {
|
||||
if (handle->busy_polling != -req->errorno) {
|
||||
uv__set_artificial_error(handle->loop, req->errorno);
|
||||
handle->poll_cb(handle, -1, &handle->statbuf, &zero_statbuf);
|
||||
handle->busy_polling = -req->errorno;
|
||||
if (ctx->busy_polling != -req->errorno) {
|
||||
uv__set_artificial_error(ctx->loop, req->errorno);
|
||||
ctx->poll_cb(ctx->parent_handle, -1, &ctx->statbuf, &zero_statbuf);
|
||||
ctx->busy_polling = -req->errorno;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
statbuf = req->ptr;
|
||||
|
||||
if (handle->busy_polling != 0)
|
||||
if (handle->busy_polling < 0 || !statbuf_eq(&handle->statbuf, statbuf))
|
||||
handle->poll_cb(handle, 0, &handle->statbuf, statbuf);
|
||||
if (ctx->busy_polling != 0)
|
||||
if (ctx->busy_polling < 0 || !statbuf_eq(&ctx->statbuf, statbuf))
|
||||
ctx->poll_cb(ctx->parent_handle, 0, &ctx->statbuf, statbuf);
|
||||
|
||||
handle->statbuf = *statbuf;
|
||||
handle->busy_polling = 1;
|
||||
ctx->statbuf = *statbuf;
|
||||
ctx->busy_polling = 1;
|
||||
|
||||
out:
|
||||
uv_fs_req_cleanup(req);
|
||||
|
||||
if (req->data == NULL) { /* Handle has been stopped or closed. */
|
||||
free(req);
|
||||
return;
|
||||
}
|
||||
|
||||
req->data = NULL; /* Tell uv_fs_poll_stop() it's safe to free the req. */
|
||||
|
||||
/* Reschedule timer, subtract the delay from doing the stat(). */
|
||||
interval = handle->interval;
|
||||
interval -= (uv_now(handle->loop) - handle->start_time) % interval;
|
||||
interval = ctx->interval;
|
||||
interval -= (uv_now(ctx->loop) - ctx->start_time) % interval;
|
||||
|
||||
if (uv_timer_start(&handle->timer_handle, timer_cb, interval, 0))
|
||||
if (uv_timer_start(&ctx->timer_handle, timer_cb, interval, 0))
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
static void timer_close_cb(uv_handle_t* handle) {
|
||||
free(container_of(handle, struct poll_ctx, timer_handle));
|
||||
}
|
||||
|
||||
|
||||
static int statbuf_eq(const uv_statbuf_t* a, const uv_statbuf_t* b) {
|
||||
#ifdef _WIN32
|
||||
return a->st_mtime == b->st_mtime
|
||||
|
||||
2
deps/uv/src/unix/async.c
vendored
2
deps/uv/src/unix/async.c
vendored
@@ -65,8 +65,6 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
||||
return uv__set_sys_error(loop, errno);
|
||||
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC);
|
||||
loop->counters.async_init++;
|
||||
|
||||
handle->async_cb = async_cb;
|
||||
handle->pending = 0;
|
||||
|
||||
|
||||
5
deps/uv/src/unix/core.c
vendored
5
deps/uv/src/unix/core.c
vendored
@@ -116,6 +116,10 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
||||
uv__fs_poll_close((uv_fs_poll_t*)handle);
|
||||
break;
|
||||
|
||||
case UV_SIGNAL:
|
||||
uv__signal_close((uv_signal_t*)handle);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
@@ -143,6 +147,7 @@ static void uv__finish_close(uv_handle_t* handle) {
|
||||
case UV_FS_EVENT:
|
||||
case UV_FS_POLL:
|
||||
case UV_POLL:
|
||||
case UV_SIGNAL:
|
||||
break;
|
||||
|
||||
case UV_NAMED_PIPE:
|
||||
|
||||
12
deps/uv/src/unix/cygwin.c
vendored
12
deps/uv/src/unix/cygwin.c
vendored
@@ -32,10 +32,19 @@
|
||||
#define NANOSEC ((uint64_t) 1e9)
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_hrtime() {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (ts.tv_sec * NANOSEC + ts.tv_nsec);
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
|
||||
void uv_loadavg(double avg[3]) {
|
||||
@@ -73,7 +82,6 @@ int uv_fs_event_init(uv_loop_t* loop,
|
||||
const char* filename,
|
||||
uv_fs_event_cb cb,
|
||||
int flags) {
|
||||
loop->counters.fs_event_init++;
|
||||
uv__set_sys_error(loop, ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
10
deps/uv/src/unix/darwin.c
vendored
10
deps/uv/src/unix/darwin.c
vendored
@@ -43,6 +43,16 @@
|
||||
|
||||
static char *process_title;
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
/* see: http://developer.apple.com/library/mac/#qa/qa1398/_index.html */
|
||||
uint64_t uv_hrtime() {
|
||||
|
||||
11
deps/uv/src/unix/freebsd.c
vendored
11
deps/uv/src/unix/freebsd.c
vendored
@@ -54,10 +54,19 @@
|
||||
static char *process_title;
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_hrtime(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (ts.tv_sec * NANOSEC + ts.tv_nsec);
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
|
||||
|
||||
|
||||
42
deps/uv/src/unix/fs.c
vendored
42
deps/uv/src/unix/fs.c
vendored
@@ -72,6 +72,7 @@ static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type,
|
||||
req->result = 0;
|
||||
req->ptr = NULL;
|
||||
req->path = path ? strdup(path) : NULL;
|
||||
req->file = -1;
|
||||
req->errorno = 0;
|
||||
req->eio = NULL;
|
||||
|
||||
@@ -85,7 +86,7 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
|
||||
if (req->cb)
|
||||
uv__req_unregister(req->loop, req);
|
||||
|
||||
free(req->path);
|
||||
free((void*)req->path);
|
||||
req->path = NULL;
|
||||
|
||||
switch (req->fs_type) {
|
||||
@@ -445,6 +446,20 @@ int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
||||
}
|
||||
|
||||
|
||||
#if defined(__APPLE__) && defined(F_FULLFSYNC)
|
||||
ssize_t uv__fs_fdatasync(uv_file file) {
|
||||
return fcntl(file, F_FULLFSYNC);
|
||||
}
|
||||
|
||||
|
||||
void uv__fs_fdatasync_work(eio_req* eio) {
|
||||
uv_fs_t* req = eio->data;
|
||||
|
||||
eio->result = uv__fs_fdatasync(req->file);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
||||
char* path = NULL;
|
||||
#if defined(__FreeBSD__) \
|
||||
@@ -453,6 +468,31 @@ int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
||||
* do a full fsync instead.
|
||||
*/
|
||||
WRAP_EIO(UV_FS_FDATASYNC, eio_fdatasync, fsync, ARGS1(file))
|
||||
#elif defined(__APPLE__) && defined(F_FULLFSYNC)
|
||||
/* OSX >= 10.6 does have fdatasync, but better use fcntl anyway */
|
||||
uv_fs_req_init(loop, req, UV_FS_FDATASYNC, path, cb);
|
||||
req->file = file;
|
||||
|
||||
if (cb) {
|
||||
/* async */
|
||||
req->eio = eio_custom(uv__fs_fdatasync_work,
|
||||
EIO_PRI_DEFAULT,
|
||||
uv__fs_after,
|
||||
req,
|
||||
&loop->uv_eio_channel);
|
||||
if (req->eio == NULL) {
|
||||
uv__set_sys_error(loop, ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* sync */
|
||||
req->result = uv__fs_fdatasync(file);
|
||||
if (req->result) {
|
||||
uv__set_sys_error(loop, errno);
|
||||
}
|
||||
return req->result;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
WRAP_EIO(UV_FS_FDATASYNC, eio_fdatasync, fdatasync, ARGS1(file))
|
||||
#endif
|
||||
|
||||
16
deps/uv/src/unix/internal.h
vendored
16
deps/uv/src/unix/internal.h
vendored
@@ -82,7 +82,7 @@
|
||||
#define UV__IO_WRITE EV_WRITE
|
||||
#define UV__IO_ERROR EV_ERROR
|
||||
|
||||
/* flags */
|
||||
/* handle flags */
|
||||
enum {
|
||||
UV_CLOSING = 0x01, /* uv_close() called but not finished. */
|
||||
UV_CLOSED = 0x02, /* close(2) finished. */
|
||||
@@ -97,10 +97,14 @@ enum {
|
||||
UV_TCP_SINGLE_ACCEPT = 0x400 /* Only accept() when idle. */
|
||||
};
|
||||
|
||||
/* loop flags */
|
||||
enum {
|
||||
UV_LOOP_EIO_INITIALIZED = 1
|
||||
};
|
||||
|
||||
inline static void uv__req_init(uv_loop_t* loop,
|
||||
uv_req_t* req,
|
||||
uv_req_type type) {
|
||||
loop->counters.req_init++;
|
||||
req->type = type;
|
||||
uv__req_register(loop, req);
|
||||
}
|
||||
@@ -153,6 +157,14 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
|
||||
void uv__run_timers(uv_loop_t* loop);
|
||||
unsigned int uv__next_timeout(uv_loop_t* loop);
|
||||
|
||||
/* signal */
|
||||
void uv__signal_close(uv_signal_t* handle);
|
||||
void uv__signal_unregister(uv_loop_t* loop);
|
||||
|
||||
/* platform specific */
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop);
|
||||
void uv__platform_loop_delete(uv_loop_t* loop);
|
||||
|
||||
/* various */
|
||||
void uv__async_close(uv_async_t* handle);
|
||||
void uv__check_close(uv_check_t* handle);
|
||||
|
||||
2
deps/uv/src/unix/kqueue.c
vendored
2
deps/uv/src/unix/kqueue.c
vendored
@@ -90,8 +90,6 @@ int uv_fs_event_init(uv_loop_t* loop,
|
||||
int flags) {
|
||||
int fd;
|
||||
|
||||
loop->counters.fs_event_init++;
|
||||
|
||||
/* We don't support any flags yet. */
|
||||
assert(!flags);
|
||||
|
||||
|
||||
2
deps/uv/src/unix/linux/inotify.c
vendored
2
deps/uv/src/unix/linux/inotify.c
vendored
@@ -176,8 +176,6 @@ int uv_fs_event_init(uv_loop_t* loop,
|
||||
int events;
|
||||
int wd;
|
||||
|
||||
loop->counters.fs_event_init++;
|
||||
|
||||
/* We don't support any flags yet. */
|
||||
assert(!flags);
|
||||
|
||||
|
||||
246
deps/uv/src/unix/linux/linux-core.c
vendored
246
deps/uv/src/unix/linux/linux-core.c
vendored
@@ -63,15 +63,31 @@ static struct {
|
||||
size_t len;
|
||||
} process_title;
|
||||
|
||||
static void read_models(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);
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
|
||||
loop->inotify_watchers = NULL;
|
||||
loop->inotify_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
if (loop->inotify_fd == -1) return;
|
||||
uv__io_stop(loop, &loop->inotify_read_watcher);
|
||||
close(loop->inotify_fd);
|
||||
loop->inotify_fd = -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* There's probably some way to get time from Linux than gettimeofday(). What
|
||||
* it is, I don't know.
|
||||
*/
|
||||
uint64_t uv_hrtime() {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (ts.tv_sec * NANOSEC + ts.tv_nsec);
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
|
||||
|
||||
@@ -301,84 +317,166 @@ uv_err_t uv_uptime(double* uptime) {
|
||||
|
||||
|
||||
uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK),
|
||||
multiplier = ((uint64_t)1000L / ticks), cpuspeed;
|
||||
int numcpus = 0, i = 0;
|
||||
unsigned long ticks_user, ticks_sys, ticks_idle, ticks_nice, ticks_intr;
|
||||
char line[512], speedPath[256], model[512];
|
||||
FILE *fpStat = fopen("/proc/stat", "r");
|
||||
FILE *fpModel = fopen("/proc/cpuinfo", "r");
|
||||
FILE *fpSpeed;
|
||||
uv_cpu_info_t* cpu_info;
|
||||
unsigned int numcpus;
|
||||
uv_cpu_info_t* ci;
|
||||
|
||||
if (fpModel) {
|
||||
while (fgets(line, 511, fpModel) != NULL) {
|
||||
if (strncmp(line, "model name", 10) == 0) {
|
||||
numcpus++;
|
||||
if (numcpus == 1) {
|
||||
char *p = strchr(line, ':') + 2;
|
||||
strcpy(model, p);
|
||||
model[strlen(model)-1] = 0;
|
||||
}
|
||||
} else if (strncmp(line, "cpu MHz", 7) == 0) {
|
||||
if (numcpus == 1) {
|
||||
sscanf(line, "%*s %*s : %u", &cpuspeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fpModel);
|
||||
}
|
||||
*cpu_infos = NULL;
|
||||
*count = 0;
|
||||
|
||||
*cpu_infos = (uv_cpu_info_t*)malloc(numcpus * sizeof(uv_cpu_info_t));
|
||||
if (!(*cpu_infos)) {
|
||||
return uv__new_artificial_error(UV_ENOMEM);
|
||||
}
|
||||
numcpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
assert(numcpus != (unsigned int) -1);
|
||||
assert(numcpus != 0);
|
||||
|
||||
ci = calloc(numcpus, sizeof(*ci));
|
||||
if (ci == NULL)
|
||||
return uv__new_sys_error(ENOMEM);
|
||||
|
||||
read_speeds(numcpus, ci);
|
||||
read_models(numcpus, ci);
|
||||
read_times(numcpus, ci);
|
||||
|
||||
*cpu_infos = ci;
|
||||
*count = numcpus;
|
||||
|
||||
cpu_info = *cpu_infos;
|
||||
|
||||
if (fpStat) {
|
||||
while (fgets(line, 511, fpStat) != NULL) {
|
||||
if (strncmp(line, "cpu ", 4) == 0) {
|
||||
continue;
|
||||
} else if (strncmp(line, "cpu", 3) != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
sscanf(line, "%*s %lu %lu %lu %lu %*s %lu",
|
||||
&ticks_user, &ticks_nice, &ticks_sys, &ticks_idle, &ticks_intr);
|
||||
snprintf(speedPath, sizeof(speedPath),
|
||||
"/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_max_freq", i);
|
||||
|
||||
fpSpeed = fopen(speedPath, "r");
|
||||
|
||||
if (fpSpeed) {
|
||||
if (fgets(line, 511, fpSpeed) != NULL) {
|
||||
sscanf(line, "%u", &cpuspeed);
|
||||
cpuspeed /= 1000;
|
||||
}
|
||||
fclose(fpSpeed);
|
||||
}
|
||||
|
||||
cpu_info->cpu_times.user = ticks_user * multiplier;
|
||||
cpu_info->cpu_times.nice = ticks_nice * multiplier;
|
||||
cpu_info->cpu_times.sys = ticks_sys * multiplier;
|
||||
cpu_info->cpu_times.idle = ticks_idle * multiplier;
|
||||
cpu_info->cpu_times.irq = ticks_intr * multiplier;
|
||||
|
||||
cpu_info->model = strdup(model);
|
||||
cpu_info->speed = cpuspeed;
|
||||
|
||||
cpu_info++;
|
||||
}
|
||||
fclose(fpStat);
|
||||
}
|
||||
|
||||
return uv_ok_;
|
||||
}
|
||||
|
||||
|
||||
static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
unsigned int num;
|
||||
|
||||
for (num = 0; num < numcpus; num++)
|
||||
ci[num].speed = read_cpufreq(num) / 1000;
|
||||
}
|
||||
|
||||
|
||||
static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
static const char marker[] = "model name\t: ";
|
||||
#elif defined(__arm__)
|
||||
static const char marker[] = "Processor\t: ";
|
||||
#elif defined(__mips__)
|
||||
static const char marker[] = "cpu model\t\t: ";
|
||||
#else
|
||||
# warning uv_cpu_info() is not supported on this architecture.
|
||||
static const char marker[] = "(dummy)";
|
||||
#endif
|
||||
unsigned int num;
|
||||
char buf[1024];
|
||||
char* model;
|
||||
FILE* fp;
|
||||
|
||||
fp = fopen("/proc/cpuinfo", "r");
|
||||
if (fp == NULL)
|
||||
return;
|
||||
|
||||
num = 0;
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
if (num >= numcpus)
|
||||
break;
|
||||
|
||||
if (strncmp(buf, marker, sizeof(marker) - 1))
|
||||
continue;
|
||||
|
||||
model = buf + sizeof(marker) - 1;
|
||||
model = strndup(model, strlen(model) - 1); /* strip newline */
|
||||
ci[num++].model = model;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
static void read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
unsigned long clock_ticks;
|
||||
struct uv_cpu_times_s ts;
|
||||
unsigned long user;
|
||||
unsigned long nice;
|
||||
unsigned long sys;
|
||||
unsigned long idle;
|
||||
unsigned long dummy;
|
||||
unsigned long irq;
|
||||
unsigned int num;
|
||||
unsigned int len;
|
||||
char buf[1024];
|
||||
FILE* fp;
|
||||
|
||||
clock_ticks = sysconf(_SC_CLK_TCK);
|
||||
assert(clock_ticks != (unsigned long) -1);
|
||||
assert(clock_ticks != 0);
|
||||
|
||||
fp = fopen("/proc/stat", "r");
|
||||
if (fp == NULL)
|
||||
return;
|
||||
|
||||
if (!fgets(buf, sizeof(buf), fp))
|
||||
abort();
|
||||
|
||||
num = 0;
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
if (num >= numcpus)
|
||||
break;
|
||||
|
||||
if (strncmp(buf, "cpu", 3))
|
||||
break;
|
||||
|
||||
/* skip "cpu<num> " marker */
|
||||
{
|
||||
unsigned int n = num;
|
||||
for (len = sizeof("cpu0"); n /= 10; len++);
|
||||
assert(sscanf(buf, "cpu%u ", &n) == 1 && n == num);
|
||||
}
|
||||
|
||||
/* Line contains user, nice, system, idle, iowait, irq, softirq, steal,
|
||||
* guest, guest_nice but we're only interested in the first four + irq.
|
||||
*
|
||||
* Don't use %*s to skip fields or %ll to read straight into the uint64_t
|
||||
* fields, they're not allowed in C89 mode.
|
||||
*/
|
||||
if (6 != sscanf(buf + len,
|
||||
"%lu %lu %lu %lu %lu %lu",
|
||||
&user,
|
||||
&nice,
|
||||
&sys,
|
||||
&idle,
|
||||
&dummy,
|
||||
&irq))
|
||||
abort();
|
||||
|
||||
ts.user = clock_ticks * user;
|
||||
ts.nice = clock_ticks * nice;
|
||||
ts.sys = clock_ticks * sys;
|
||||
ts.idle = clock_ticks * idle;
|
||||
ts.irq = clock_ticks * irq;
|
||||
ci[num++].cpu_times = ts;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
static unsigned long read_cpufreq(unsigned int cpunum) {
|
||||
unsigned long val;
|
||||
char buf[1024];
|
||||
FILE* fp;
|
||||
|
||||
snprintf(buf,
|
||||
sizeof(buf),
|
||||
"/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq",
|
||||
cpunum);
|
||||
|
||||
fp = fopen(buf, "r");
|
||||
if (fp == NULL)
|
||||
return 0;
|
||||
|
||||
val = 0;
|
||||
fscanf(fp, "%lu", &val);
|
||||
fclose(fp);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
int i;
|
||||
|
||||
|
||||
1
deps/uv/src/unix/loop-watcher.c
vendored
1
deps/uv/src/unix/loop-watcher.c
vendored
@@ -25,7 +25,6 @@
|
||||
#define UV_LOOP_WATCHER_DEFINE(name, type) \
|
||||
int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_##type); \
|
||||
loop->counters.name##_init++; \
|
||||
handle->name##_cb = NULL; \
|
||||
return 0; \
|
||||
} \
|
||||
|
||||
38
deps/uv/src/unix/loop.c
vendored
38
deps/uv/src/unix/loop.c
vendored
@@ -28,10 +28,13 @@
|
||||
|
||||
|
||||
int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
||||
unsigned int i;
|
||||
int flags;
|
||||
|
||||
#if HAVE_KQUEUE
|
||||
int flags = EVBACKEND_KQUEUE;
|
||||
flags = EVBACKEND_KQUEUE;
|
||||
#else
|
||||
int flags = EVFLAG_AUTO;
|
||||
flags = EVFLAG_AUTO;
|
||||
#endif
|
||||
|
||||
memset(loop, 0, sizeof(*loop));
|
||||
@@ -44,6 +47,7 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
||||
ngx_queue_init(&loop->prepare_handles);
|
||||
ngx_queue_init(&loop->handle_queue);
|
||||
loop->closing_handles = NULL;
|
||||
loop->signal_ctx = NULL;
|
||||
loop->time = uv_hrtime() / 1000000;
|
||||
loop->async_pipefd[0] = -1;
|
||||
loop->async_pipefd[1] = -1;
|
||||
@@ -51,28 +55,22 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
||||
ev_set_userdata(loop->ev, loop);
|
||||
eio_channel_init(&loop->uv_eio_channel, loop);
|
||||
|
||||
#if __linux__
|
||||
loop->inotify_watchers = NULL;
|
||||
loop->inotify_fd = -1;
|
||||
#endif
|
||||
#if HAVE_PORTS_FS
|
||||
loop->fs_fd = -1;
|
||||
#endif
|
||||
uv_signal_init(loop, &loop->child_watcher);
|
||||
uv__handle_unref(&loop->child_watcher);
|
||||
loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++)
|
||||
ngx_queue_init(loop->process_handles + i);
|
||||
|
||||
if (uv__platform_loop_init(loop, default_loop))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__loop_delete(uv_loop_t* loop) {
|
||||
uv__platform_loop_delete(loop);
|
||||
uv__signal_unregister(loop);
|
||||
ev_loop_destroy(loop->ev);
|
||||
#if __linux__
|
||||
if (loop->inotify_fd != -1) {
|
||||
uv__io_stop(loop, &loop->inotify_read_watcher);
|
||||
close(loop->inotify_fd);
|
||||
loop->inotify_fd = -1;
|
||||
}
|
||||
#endif
|
||||
#if HAVE_PORTS_FS
|
||||
if (loop->fs_fd != -1)
|
||||
close(loop->fs_fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
11
deps/uv/src/unix/netbsd.c
vendored
11
deps/uv/src/unix/netbsd.c
vendored
@@ -35,10 +35,19 @@
|
||||
#define NANOSEC ((uint64_t) 1e9)
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_hrtime(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (ts.tv_sec * NANOSEC + ts.tv_nsec);
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
|
||||
void uv_loadavg(double avg[3]) {
|
||||
|
||||
11
deps/uv/src/unix/openbsd.c
vendored
11
deps/uv/src/unix/openbsd.c
vendored
@@ -43,10 +43,19 @@
|
||||
static char *process_title;
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_hrtime(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (ts.tv_sec * NANOSEC + ts.tv_nsec);
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
|
||||
|
||||
|
||||
1
deps/uv/src/unix/pipe.c
vendored
1
deps/uv/src/unix/pipe.c
vendored
@@ -34,7 +34,6 @@ static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, int events);
|
||||
|
||||
int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
|
||||
uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
|
||||
loop->counters.pipe_init++;
|
||||
handle->shutdown_req = NULL;
|
||||
handle->connect_req = NULL;
|
||||
handle->pipe_fname = NULL;
|
||||
|
||||
2
deps/uv/src/unix/poll.c
vendored
2
deps/uv/src/unix/poll.c
vendored
@@ -54,8 +54,6 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, int events) {
|
||||
|
||||
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
|
||||
uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
|
||||
loop->counters.poll_init++;
|
||||
|
||||
handle->fd = fd;
|
||||
handle->poll_cb = NULL;
|
||||
uv__io_init(&handle->io_watcher, uv__poll_io, fd, 0);
|
||||
|
||||
298
deps/uv/src/unix/process.c
vendored
298
deps/uv/src/unix/process.c
vendored
@@ -22,13 +22,16 @@
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <TargetConditionals.h>
|
||||
@@ -42,26 +45,71 @@ extern char **environ;
|
||||
#endif
|
||||
|
||||
|
||||
static void uv__chld(EV_P_ ev_child* watcher, int revents) {
|
||||
int status = watcher->rstatus;
|
||||
int exit_status = 0;
|
||||
int term_signal = 0;
|
||||
uv_process_t *process = watcher->data;
|
||||
static ngx_queue_t* uv__process_queue(uv_loop_t* loop, int pid) {
|
||||
assert(pid > 0);
|
||||
return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles);
|
||||
}
|
||||
|
||||
assert(&process->child_watcher == watcher);
|
||||
assert(revents & EV_CHILD);
|
||||
|
||||
ev_child_stop(EV_A_ &process->child_watcher);
|
||||
static uv_process_t* uv__process_find(uv_loop_t* loop, int pid) {
|
||||
uv_process_t* handle;
|
||||
ngx_queue_t* h;
|
||||
ngx_queue_t* q;
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
exit_status = WEXITSTATUS(status);
|
||||
h = uv__process_queue(loop, pid);
|
||||
|
||||
ngx_queue_foreach(q, h) {
|
||||
handle = ngx_queue_data(q, uv_process_t, queue);
|
||||
if (handle->pid == pid) return handle;
|
||||
}
|
||||
|
||||
if (WIFSIGNALED(status)) {
|
||||
term_signal = WTERMSIG(status);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void uv__chld(uv_signal_t* handle, int signum) {
|
||||
uv_process_t* process;
|
||||
int exit_status;
|
||||
int term_signal;
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
assert(signum == SIGCHLD);
|
||||
|
||||
for (;;) {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
|
||||
if (pid == 0)
|
||||
return;
|
||||
|
||||
if (pid == -1) {
|
||||
if (errno == ECHILD)
|
||||
return; /* XXX stop signal watcher? */
|
||||
else
|
||||
abort();
|
||||
}
|
||||
|
||||
process = uv__process_find(handle->loop, pid);
|
||||
if (process == NULL)
|
||||
continue; /* XXX bug? abort? */
|
||||
|
||||
if (process->exit_cb == NULL)
|
||||
continue;
|
||||
|
||||
exit_status = 0;
|
||||
term_signal = 0;
|
||||
|
||||
if (WIFEXITED(status))
|
||||
exit_status = WEXITSTATUS(status);
|
||||
|
||||
if (WIFSIGNALED(status))
|
||||
term_signal = WTERMSIG(status);
|
||||
|
||||
if (process->errorno) {
|
||||
uv__set_sys_error(process->loop, process->errorno);
|
||||
exit_status = -1; /* execve() failed */
|
||||
}
|
||||
|
||||
if (process->exit_cb) {
|
||||
process->exit_cb(process, exit_status, term_signal);
|
||||
}
|
||||
}
|
||||
@@ -122,8 +170,7 @@ int uv__make_pipe(int fds[2], int flags) {
|
||||
* Used for initializing stdio streams like options.stdin_stream. Returns
|
||||
* zero on success.
|
||||
*/
|
||||
static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2],
|
||||
int writable) {
|
||||
static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
|
||||
int fd = -1;
|
||||
switch (container->flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
|
||||
UV_INHERIT_STREAM)) {
|
||||
@@ -151,7 +198,7 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2],
|
||||
return -1;
|
||||
}
|
||||
|
||||
fds[writable ? 1 : 0] = fd;
|
||||
fds[1] = fd;
|
||||
|
||||
return 0;
|
||||
default:
|
||||
@@ -174,16 +221,19 @@ static int uv__process_stdio_flags(uv_stdio_container_t* container,
|
||||
}
|
||||
|
||||
|
||||
static int uv__process_open_stream(uv_stdio_container_t* container, int fds[2],
|
||||
static int uv__process_open_stream(uv_stdio_container_t* container,
|
||||
int fds[2],
|
||||
int writable) {
|
||||
int fd = fds[writable ? 1 : 0];
|
||||
int child_fd = fds[writable ? 0 : 1];
|
||||
int child_fd;
|
||||
int flags;
|
||||
int fd;
|
||||
|
||||
fd = fds[0];
|
||||
child_fd = fds[1];
|
||||
|
||||
/* No need to create stream */
|
||||
if (!(container->flags & UV_CREATE_PIPE) || fd < 0) {
|
||||
if (!(container->flags & UV_CREATE_PIPE) || fd < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(child_fd >= 0);
|
||||
close(child_fd);
|
||||
@@ -197,62 +247,78 @@ static int uv__process_open_stream(uv_stdio_container_t* container, int fds[2],
|
||||
|
||||
static void uv__process_close_stream(uv_stdio_container_t* container) {
|
||||
if (!(container->flags & UV_CREATE_PIPE)) return;
|
||||
|
||||
uv__stream_close((uv_stream_t*)container->data.stream);
|
||||
}
|
||||
|
||||
|
||||
static void uv__write_int(int fd, int val) {
|
||||
ssize_t n;
|
||||
|
||||
do
|
||||
n = write(fd, &val, sizeof(val));
|
||||
while (n == -1 && errno == EINTR);
|
||||
|
||||
if (n == -1 && errno == EPIPE)
|
||||
return; /* parent process has quit */
|
||||
|
||||
assert(n == sizeof(val));
|
||||
}
|
||||
|
||||
|
||||
static void uv__process_child_init(uv_process_options_t options,
|
||||
int stdio_count,
|
||||
int* pipes) {
|
||||
int (*pipes)[2],
|
||||
int error_fd) {
|
||||
int close_fd;
|
||||
int use_fd;
|
||||
int i;
|
||||
|
||||
if (options.flags & UV_PROCESS_DETACHED) {
|
||||
if (options.flags & UV_PROCESS_DETACHED)
|
||||
setsid();
|
||||
}
|
||||
|
||||
/* Dup fds */
|
||||
for (i = 0; i < stdio_count; i++) {
|
||||
/*
|
||||
* stdin has swapped ends of pipe
|
||||
* (it's the only one readable stream)
|
||||
*/
|
||||
int close_fd = i == 0 ? pipes[i * 2 + 1] : pipes[i * 2];
|
||||
int use_fd = i == 0 ? pipes[i * 2] : pipes[i * 2 + 1];
|
||||
close_fd = pipes[i][0];
|
||||
use_fd = pipes[i][1];
|
||||
|
||||
if (use_fd >= 0) {
|
||||
if (use_fd >= 0)
|
||||
close(close_fd);
|
||||
} else if (i < 3) {
|
||||
/* `/dev/null` stdin, stdout, stderr even if they've flag UV_IGNORE */
|
||||
else if (i >= 3)
|
||||
continue;
|
||||
else {
|
||||
/* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
|
||||
* set
|
||||
*/
|
||||
use_fd = open("/dev/null", i == 0 ? O_RDONLY : O_RDWR);
|
||||
|
||||
if (use_fd < 0) {
|
||||
if (use_fd == -1) {
|
||||
uv__write_int(error_fd, errno);
|
||||
perror("failed to open stdio");
|
||||
_exit(127);
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i != use_fd) {
|
||||
if (i == use_fd)
|
||||
uv__cloexec(use_fd, 0);
|
||||
else {
|
||||
dup2(use_fd, i);
|
||||
close(use_fd);
|
||||
} else {
|
||||
uv__cloexec(use_fd, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.cwd && chdir(options.cwd)) {
|
||||
uv__write_int(error_fd, errno);
|
||||
perror("chdir()");
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
|
||||
uv__write_int(error_fd, errno);
|
||||
perror("setgid()");
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
|
||||
uv__write_int(error_fd, errno);
|
||||
perror("setuid()");
|
||||
_exit(127);
|
||||
}
|
||||
@@ -260,63 +326,57 @@ static void uv__process_child_init(uv_process_options_t options,
|
||||
environ = options.env;
|
||||
|
||||
execvp(options.file, options.args);
|
||||
uv__write_int(error_fd, errno);
|
||||
perror("execvp()");
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
|
||||
#ifndef SPAWN_WAIT_EXEC
|
||||
# define SPAWN_WAIT_EXEC 1
|
||||
#endif
|
||||
|
||||
int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
||||
uv_process_options_t options) {
|
||||
/*
|
||||
* Save environ in the case that we get it clobbered
|
||||
* by the child process.
|
||||
*/
|
||||
char** save_our_env = environ;
|
||||
|
||||
int stdio_count = options.stdio_count < 3 ? 3 : options.stdio_count;
|
||||
int* pipes = malloc(2 * stdio_count * sizeof(int));
|
||||
|
||||
#if SPAWN_WAIT_EXEC
|
||||
int uv_spawn(uv_loop_t* loop,
|
||||
uv_process_t* process,
|
||||
const uv_process_options_t options) {
|
||||
int signal_pipe[2] = { -1, -1 };
|
||||
struct pollfd pfd;
|
||||
#endif
|
||||
int status;
|
||||
int (*pipes)[2];
|
||||
int stdio_count;
|
||||
ngx_queue_t* q;
|
||||
ssize_t r;
|
||||
pid_t pid;
|
||||
int i;
|
||||
|
||||
if (pipes == NULL) {
|
||||
errno = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
assert(options.file != NULL);
|
||||
assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
|
||||
UV_PROCESS_DETACHED |
|
||||
UV_PROCESS_SETGID |
|
||||
UV_PROCESS_SETUID)));
|
||||
|
||||
|
||||
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
|
||||
loop->counters.process_init++;
|
||||
uv__handle_start(process);
|
||||
ngx_queue_init(&process->queue);
|
||||
|
||||
process->exit_cb = options.exit_cb;
|
||||
stdio_count = options.stdio_count;
|
||||
if (stdio_count < 3)
|
||||
stdio_count = 3;
|
||||
|
||||
/* Init pipe pairs */
|
||||
for (i = 0; i < stdio_count; i++) {
|
||||
pipes[i * 2] = -1;
|
||||
pipes[i * 2 + 1] = -1;
|
||||
pipes = malloc(stdio_count * sizeof(*pipes));
|
||||
if (pipes == NULL) {
|
||||
errno = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Create socketpairs/pipes, or use raw fd */
|
||||
for (i = 0; i < options.stdio_count; i++) {
|
||||
if (uv__process_init_stdio(&options.stdio[i], pipes + i * 2, i != 0)) {
|
||||
for (i = 0; i < stdio_count; i++) {
|
||||
pipes[i][0] = -1;
|
||||
pipes[i][1] = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < options.stdio_count; i++)
|
||||
if (uv__process_init_stdio(options.stdio + i, pipes[i]))
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* swap stdin file descriptors, it's the only writable stream */
|
||||
{
|
||||
int* p = pipes[0];
|
||||
int t = p[0];
|
||||
p[0] = p[1];
|
||||
p[1] = t;
|
||||
}
|
||||
|
||||
/* This pipe is used by the parent to wait until
|
||||
@@ -337,81 +397,68 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
||||
*
|
||||
* To avoid ambiguity, we create a pipe with both ends
|
||||
* marked close-on-exec. Then, after the call to `fork()`,
|
||||
* the parent polls the read end until it sees POLLHUP.
|
||||
* the parent polls the read end until it EOFs or errors with EPIPE.
|
||||
*/
|
||||
#if SPAWN_WAIT_EXEC
|
||||
if (uv__make_pipe(signal_pipe, UV__F_NONBLOCK))
|
||||
if (uv__make_pipe(signal_pipe, 0))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid == -1) {
|
||||
#if SPAWN_WAIT_EXEC
|
||||
close(signal_pipe[0]);
|
||||
close(signal_pipe[1]);
|
||||
#endif
|
||||
environ = save_our_env;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
/* Child */
|
||||
uv__process_child_init(options, stdio_count, pipes);
|
||||
|
||||
/* Execution never reaches here. */
|
||||
uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Parent. */
|
||||
|
||||
/* Restore environment. */
|
||||
environ = save_our_env;
|
||||
|
||||
#if SPAWN_WAIT_EXEC
|
||||
/* POLLHUP signals child has exited or execve()'d. */
|
||||
close(signal_pipe[1]);
|
||||
do {
|
||||
pfd.fd = signal_pipe[0];
|
||||
pfd.events = POLLIN|POLLHUP;
|
||||
pfd.revents = 0;
|
||||
errno = 0, status = poll(&pfd, 1, -1);
|
||||
}
|
||||
while (status == -1 && (errno == EINTR || errno == ENOMEM));
|
||||
|
||||
assert((status == 1) && "poll() on pipe read end failed");
|
||||
process->errorno = 0;
|
||||
do
|
||||
r = read(signal_pipe[0], &process->errorno, sizeof(process->errorno));
|
||||
while (r == -1 && errno == EINTR);
|
||||
|
||||
if (r == 0)
|
||||
; /* okay, EOF */
|
||||
else if (r == sizeof(process->errorno))
|
||||
; /* okay, read errorno */
|
||||
else if (r == -1 && errno == EPIPE)
|
||||
; /* okay, got EPIPE */
|
||||
else
|
||||
abort();
|
||||
|
||||
close(signal_pipe[0]);
|
||||
#endif
|
||||
|
||||
process->pid = pid;
|
||||
|
||||
ev_child_init(&process->child_watcher, uv__chld, pid, 0);
|
||||
ev_child_start(process->loop->ev, &process->child_watcher);
|
||||
process->child_watcher.data = process;
|
||||
|
||||
for (i = 0; i < options.stdio_count; i++) {
|
||||
if (uv__process_open_stream(&options.stdio[i], pipes + i * 2, i == 0)) {
|
||||
int j;
|
||||
/* Close all opened streams */
|
||||
for (j = 0; j < i; j++) {
|
||||
uv__process_close_stream(&options.stdio[j]);
|
||||
}
|
||||
|
||||
if (uv__process_open_stream(options.stdio + i, pipes[i], i == 0)) {
|
||||
while (i--) uv__process_close_stream(options.stdio + i);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
free(pipes);
|
||||
q = uv__process_queue(loop, pid);
|
||||
ngx_queue_insert_tail(q, &process->queue);
|
||||
|
||||
process->pid = pid;
|
||||
process->exit_cb = options.exit_cb;
|
||||
uv__handle_start(process);
|
||||
|
||||
free(pipes);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
uv__set_sys_error(process->loop, errno);
|
||||
|
||||
for (i = 0; i < stdio_count; i++) {
|
||||
close(pipes[i * 2]);
|
||||
close(pipes[i * 2 + 1]);
|
||||
close(pipes[i][0]);
|
||||
close(pipes[i][1]);
|
||||
}
|
||||
|
||||
free(pipes);
|
||||
|
||||
return -1;
|
||||
@@ -442,6 +489,7 @@ uv_err_t uv_kill(int pid, int signum) {
|
||||
|
||||
|
||||
void uv__process_close(uv_process_t* handle) {
|
||||
ev_child_stop(handle->loop->ev, &handle->child_watcher);
|
||||
/* TODO stop signal watcher when this is the last handle */
|
||||
ngx_queue_remove(&handle->queue);
|
||||
uv__handle_stop(handle);
|
||||
}
|
||||
|
||||
269
deps/uv/src/unix/signal.c
vendored
Normal file
269
deps/uv/src/unix/signal.c
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
/* 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 "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
struct signal_ctx {
|
||||
int pipefd[2];
|
||||
uv__io_t io_watcher;
|
||||
unsigned int nqueues;
|
||||
ngx_queue_t queues[1]; /* variable length */
|
||||
};
|
||||
|
||||
static void uv__signal_handler(int signum);
|
||||
static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, int events);
|
||||
static struct signal_ctx* uv__signal_ctx_new(uv_loop_t* loop);
|
||||
static void uv__signal_ctx_delete(struct signal_ctx* ctx);
|
||||
static void uv__signal_write(int fd, unsigned int val);
|
||||
static unsigned int uv__signal_read(int fd);
|
||||
static unsigned int uv__signal_max(void);
|
||||
|
||||
|
||||
int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_SIGNAL);
|
||||
handle->signum = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum_) {
|
||||
struct signal_ctx* ctx;
|
||||
struct sigaction sa;
|
||||
unsigned int signum;
|
||||
uv_loop_t* loop;
|
||||
ngx_queue_t* q;
|
||||
|
||||
/* XXX doing this check in uv_signal_init() - the logical place for it -
|
||||
* leads to an infinite loop when uv__loop_init() inits a signal watcher
|
||||
*/
|
||||
/* FIXME */
|
||||
assert(handle->loop == uv_default_loop() &&
|
||||
"uv_signal_t is currently only supported by the default loop");
|
||||
|
||||
loop = handle->loop;
|
||||
signum = signum_;
|
||||
|
||||
if (uv__is_active(handle))
|
||||
return uv__set_artificial_error(loop, UV_EBUSY);
|
||||
|
||||
if (signal_cb == NULL)
|
||||
return uv__set_artificial_error(loop, UV_EINVAL);
|
||||
|
||||
if (signum <= 0)
|
||||
return uv__set_artificial_error(loop, UV_EINVAL);
|
||||
|
||||
ctx = loop->signal_ctx;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = uv__signal_ctx_new(loop);
|
||||
|
||||
if (ctx == NULL)
|
||||
return uv__set_artificial_error(loop, UV_ENOMEM);
|
||||
|
||||
loop->signal_ctx = ctx;
|
||||
}
|
||||
|
||||
if (signum > ctx->nqueues)
|
||||
return uv__set_artificial_error(loop, UV_EINVAL);
|
||||
|
||||
q = ctx->queues + signum;
|
||||
|
||||
if (!ngx_queue_empty(q))
|
||||
goto skip;
|
||||
|
||||
/* XXX use a separate signal stack? */
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = uv__signal_handler;
|
||||
|
||||
/* XXX save old action so we can restore it later on? */
|
||||
if (sigaction(signum, &sa, NULL))
|
||||
return uv__set_artificial_error(loop, UV_EINVAL);
|
||||
|
||||
skip:
|
||||
ngx_queue_insert_tail(q, &handle->queue);
|
||||
uv__handle_start(handle);
|
||||
handle->signum = signum;
|
||||
handle->signal_cb = signal_cb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_signal_stop(uv_signal_t* handle) {
|
||||
struct signal_ctx* ctx;
|
||||
struct sigaction sa;
|
||||
unsigned int signum;
|
||||
uv_loop_t* loop;
|
||||
|
||||
if (!uv__is_active(handle))
|
||||
return 0;
|
||||
|
||||
signum = handle->signum;
|
||||
loop = handle->loop;
|
||||
ctx = loop->signal_ctx;
|
||||
assert(signum > 0);
|
||||
assert(signum <= ctx->nqueues);
|
||||
|
||||
ngx_queue_remove(&handle->queue);
|
||||
uv__handle_stop(handle);
|
||||
handle->signum = 0;
|
||||
|
||||
if (!ngx_queue_empty(ctx->queues + signum))
|
||||
goto skip;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = SIG_DFL; /* XXX restore previous action? */
|
||||
|
||||
if (sigaction(signum, &sa, NULL))
|
||||
return uv__set_artificial_error(loop, UV_EINVAL);
|
||||
|
||||
skip:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__signal_close(uv_signal_t* handle) {
|
||||
uv_signal_stop(handle);
|
||||
}
|
||||
|
||||
|
||||
void uv__signal_unregister(uv_loop_t* loop) {
|
||||
uv__signal_ctx_delete(loop->signal_ctx);
|
||||
loop->signal_ctx = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void uv__signal_handler(int signum) {
|
||||
struct signal_ctx* ctx = uv_default_loop()->signal_ctx;
|
||||
uv__signal_write(ctx->pipefd[1], (unsigned int) signum);
|
||||
}
|
||||
|
||||
|
||||
static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, int events) {
|
||||
struct signal_ctx* ctx;
|
||||
unsigned int signum;
|
||||
uv_signal_t* h;
|
||||
ngx_queue_t* q;
|
||||
|
||||
ctx = container_of(w, struct signal_ctx, io_watcher);
|
||||
signum = uv__signal_read(ctx->pipefd[0]);
|
||||
assert(signum > 0);
|
||||
assert(signum <= ctx->nqueues);
|
||||
|
||||
ngx_queue_foreach(q, ctx->queues + signum) {
|
||||
h = ngx_queue_data(q, uv_signal_t, queue);
|
||||
h->signal_cb(h, signum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct signal_ctx* uv__signal_ctx_new(uv_loop_t* loop) {
|
||||
struct signal_ctx* ctx;
|
||||
unsigned int nqueues;
|
||||
unsigned int i;
|
||||
|
||||
nqueues = uv__signal_max();
|
||||
assert(nqueues > 0);
|
||||
|
||||
/* The first ctx->queues entry is never used. It wastes a few bytes of memory
|
||||
* but it saves us from having to substract 1 from the signum all the time -
|
||||
* which inevitably someone will forget to do.
|
||||
*/
|
||||
ctx = calloc(1, sizeof(*ctx) + sizeof(ctx->queues[0]) * (nqueues + 1));
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
|
||||
if (uv__make_pipe(ctx->pipefd, UV__F_NONBLOCK)) {
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uv__io_init(&ctx->io_watcher, uv__signal_event, ctx->pipefd[0], UV__IO_READ);
|
||||
uv__io_start(loop, &ctx->io_watcher);
|
||||
ctx->nqueues = nqueues;
|
||||
|
||||
for (i = 1; i <= nqueues; i++)
|
||||
ngx_queue_init(ctx->queues + i);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
static void uv__signal_ctx_delete(struct signal_ctx* ctx) {
|
||||
if (ctx == NULL) return;
|
||||
close(ctx->pipefd[0]);
|
||||
close(ctx->pipefd[1]);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
|
||||
static void uv__signal_write(int fd, unsigned int val) {
|
||||
ssize_t n;
|
||||
|
||||
do
|
||||
n = write(fd, &val, sizeof(val));
|
||||
while (n == -1 && errno == EINTR);
|
||||
|
||||
if (n == sizeof(val))
|
||||
return;
|
||||
|
||||
if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
|
||||
return; /* pipe full - nothing we can do about that */
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
static unsigned int uv__signal_read(int fd) {
|
||||
unsigned int val;
|
||||
ssize_t n;
|
||||
|
||||
do
|
||||
n = read(fd, &val, sizeof(val));
|
||||
while (n == -1 && errno == EINTR);
|
||||
|
||||
if (n == sizeof(val))
|
||||
return val;
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
static unsigned int uv__signal_max(void) {
|
||||
#if defined(_SC_RTSIG_MAX)
|
||||
int max = sysconf(_SC_RTSIG_MAX);
|
||||
if (max != -1) return max;
|
||||
#endif
|
||||
#if defined(SIGRTMAX)
|
||||
return SIGRTMAX;
|
||||
#elif defined(NSIG)
|
||||
return NSIG;
|
||||
#else
|
||||
return 32;
|
||||
#endif
|
||||
}
|
||||
15
deps/uv/src/unix/stream.c
vendored
15
deps/uv/src/unix/stream.c
vendored
@@ -57,8 +57,6 @@ void uv__stream_init(uv_loop_t* loop,
|
||||
uv_stream_t* stream,
|
||||
uv_handle_type type) {
|
||||
uv__handle_init(loop, (uv_handle_t*)stream, type);
|
||||
loop->counters.stream_init++;
|
||||
|
||||
stream->alloc_cb = NULL;
|
||||
stream->close_cb = NULL;
|
||||
stream->connection_cb = NULL;
|
||||
@@ -489,7 +487,6 @@ start:
|
||||
} else {
|
||||
/* Successful write */
|
||||
|
||||
/* Update the counters. */
|
||||
while (n >= 0) {
|
||||
uv_buf_t* buf = &(req->bufs[req->write_index]);
|
||||
size_t len = buf->len;
|
||||
@@ -834,10 +831,16 @@ static void uv__stream_connect(uv_stream_t* stream) {
|
||||
}
|
||||
|
||||
|
||||
int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
|
||||
uv_stream_t* send_handle, uv_write_cb cb) {
|
||||
int uv_write2(uv_write_t* req,
|
||||
uv_stream_t* stream,
|
||||
uv_buf_t bufs[],
|
||||
int bufcnt,
|
||||
uv_stream_t* send_handle,
|
||||
uv_write_cb cb) {
|
||||
int empty_queue;
|
||||
|
||||
assert(bufcnt > 0);
|
||||
|
||||
assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
|
||||
stream->type == UV_TTY) &&
|
||||
"uv_write (unix) does not yet support other types of streams");
|
||||
@@ -864,7 +867,7 @@ int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
|
||||
req->send_handle = send_handle;
|
||||
ngx_queue_init(&req->queue);
|
||||
|
||||
if (bufcnt <= UV_REQ_BUFSML_SIZE)
|
||||
if (bufcnt <= (int) ARRAY_SIZE(req->bufsml))
|
||||
req->bufs = req->bufsml;
|
||||
else
|
||||
req->bufs = malloc(sizeof(uv_buf_t) * bufcnt);
|
||||
|
||||
22
deps/uv/src/unix/sunos.c
vendored
22
deps/uv/src/unix/sunos.c
vendored
@@ -63,6 +63,19 @@
|
||||
#endif
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
|
||||
loop->fs_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
if (loop->fs_fd == -1) return;
|
||||
close(loop->fs_fd);
|
||||
loop->fs_fd = -1;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_hrtime() {
|
||||
return (gethrtime());
|
||||
}
|
||||
@@ -183,8 +196,6 @@ int uv_fs_event_init(uv_loop_t* loop,
|
||||
int portfd;
|
||||
int first_run = 0;
|
||||
|
||||
loop->counters.fs_event_init++;
|
||||
|
||||
/* We don't support any flags yet. */
|
||||
assert(!flags);
|
||||
if (loop->fs_fd == -1) {
|
||||
@@ -233,7 +244,6 @@ int uv_fs_event_init(uv_loop_t* loop,
|
||||
const char* filename,
|
||||
uv_fs_event_cb cb,
|
||||
int flags) {
|
||||
loop->counters.fs_event_init++;
|
||||
uv__set_sys_error(loop, ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
@@ -344,8 +354,10 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
cpu_info->model = NULL;
|
||||
} else {
|
||||
knp = (kstat_named_t *) kstat_data_lookup(ksp, (char *)"clock_MHz");
|
||||
assert(knp->data_type == KSTAT_DATA_INT32);
|
||||
cpu_info->speed = knp->value.i32;
|
||||
assert(knp->data_type == KSTAT_DATA_INT32 ||
|
||||
knp->data_type == KSTAT_DATA_INT64);
|
||||
cpu_info->speed = (knp->data_type == KSTAT_DATA_INT32) ? knp->value.i32
|
||||
: knp->value.i64;
|
||||
|
||||
knp = (kstat_named_t *) kstat_data_lookup(ksp, (char *)"brand");
|
||||
assert(knp->data_type == KSTAT_DATA_STRING);
|
||||
|
||||
1
deps/uv/src/unix/tcp.c
vendored
1
deps/uv/src/unix/tcp.c
vendored
@@ -30,7 +30,6 @@
|
||||
|
||||
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
|
||||
uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
|
||||
loop->counters.tcp_init++;
|
||||
tcp->idle_handle = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
2
deps/uv/src/unix/timer.c
vendored
2
deps/uv/src/unix/timer.c
vendored
@@ -39,8 +39,6 @@ RB_GENERATE_STATIC(uv__timers, uv_timer_s, tree_entry, uv__timer_cmp)
|
||||
|
||||
|
||||
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
|
||||
loop->counters.timer_init++;
|
||||
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
|
||||
handle->timer_cb = NULL;
|
||||
|
||||
|
||||
1
deps/uv/src/unix/tty.c
vendored
1
deps/uv/src/unix/tty.c
vendored
@@ -45,7 +45,6 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
|
||||
tty->flags |= UV_STREAM_BLOCKING;
|
||||
}
|
||||
|
||||
loop->counters.tty_init++;
|
||||
tty->mode = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
6
deps/uv/src/unix/udp.c
vendored
6
deps/uv/src/unix/udp.c
vendored
@@ -418,6 +418,8 @@ static int uv__udp_send(uv_udp_send_t* req,
|
||||
struct sockaddr* addr,
|
||||
socklen_t addrlen,
|
||||
uv_udp_send_cb send_cb) {
|
||||
assert(bufcnt > 0);
|
||||
|
||||
if (uv__udp_maybe_deferred_bind(handle, addr->sa_family))
|
||||
return -1;
|
||||
|
||||
@@ -429,7 +431,7 @@ static int uv__udp_send(uv_udp_send_t* req,
|
||||
req->handle = handle;
|
||||
req->bufcnt = bufcnt;
|
||||
|
||||
if (bufcnt <= UV_REQ_BUFSML_SIZE) {
|
||||
if (bufcnt <= (int) ARRAY_SIZE(req->bufsml)) {
|
||||
req->bufs = req->bufsml;
|
||||
}
|
||||
else if ((req->bufs = malloc(bufcnt * sizeof(bufs[0]))) == NULL) {
|
||||
@@ -453,8 +455,6 @@ int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
|
||||
memset(handle, 0, sizeof *handle);
|
||||
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
|
||||
loop->counters.udp_init++;
|
||||
|
||||
handle->fd = -1;
|
||||
ngx_queue_init(&handle->write_queue);
|
||||
ngx_queue_init(&handle->write_completed_queue);
|
||||
|
||||
4
deps/uv/src/unix/uv-eio.c
vendored
4
deps/uv/src/unix/uv-eio.c
vendored
@@ -83,8 +83,8 @@ static void uv__eio_init(void) {
|
||||
|
||||
|
||||
void uv_eio_init(uv_loop_t* loop) {
|
||||
if (loop->counters.eio_init) return;
|
||||
loop->counters.eio_init = 1;
|
||||
if (loop->flags & UV_LOOP_EIO_INITIALIZED) return;
|
||||
loop->flags |= UV_LOOP_EIO_INITIALIZED;
|
||||
|
||||
uv_idle_init(loop, &loop->uv_eio_poller);
|
||||
uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
|
||||
|
||||
1
deps/uv/src/uv-common.h
vendored
1
deps/uv/src/uv-common.h
vendored
@@ -158,7 +158,6 @@ UNUSED static void uv__handle_unref(uv_handle_t* h) {
|
||||
UNUSED static void uv__handle_init(uv_loop_t* loop,
|
||||
uv_handle_t* handle,
|
||||
uv_handle_type type) {
|
||||
loop->counters.handle_init++;
|
||||
handle->loop = loop;
|
||||
handle->type = type;
|
||||
handle->flags = UV__HANDLE_REF; /* ref the loop when active */
|
||||
|
||||
34
deps/uv/src/win/async.c
vendored
34
deps/uv/src/win/async.c
vendored
@@ -23,39 +23,11 @@
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
#include "atomicops-inl.h"
|
||||
#include "handle-inl.h"
|
||||
#include "req-inl.h"
|
||||
|
||||
|
||||
/* Atomic set operation on char */
|
||||
#ifdef _MSC_VER /* MSVC */
|
||||
|
||||
/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */
|
||||
/* efficient than InterlockedExchange, but InterlockedExchange8 does not */
|
||||
/* exist, and interlocked operations on larger targets might require the */
|
||||
/* target to be aligned. */
|
||||
#pragma intrinsic(_InterlockedOr8)
|
||||
|
||||
static char __declspec(inline) uv_atomic_exchange_set(char volatile* target) {
|
||||
return _InterlockedOr8(target, 1);
|
||||
}
|
||||
|
||||
#else /* GCC */
|
||||
|
||||
/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
|
||||
static inline char uv_atomic_exchange_set(char volatile* target) {
|
||||
const char one = 1;
|
||||
char old_value;
|
||||
__asm__ __volatile__ ("lock xchgb %0, %1\n\t"
|
||||
: "=r"(old_value), "=m"(*target)
|
||||
: "0"(one), "m"(*target)
|
||||
: "memory");
|
||||
return old_value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) {
|
||||
if (handle->flags & UV_HANDLE_CLOSING &&
|
||||
!handle->async_sent) {
|
||||
@@ -78,8 +50,6 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
||||
req->type = UV_WAKEUP;
|
||||
req->data = handle;
|
||||
|
||||
loop->counters.async_init++;
|
||||
|
||||
uv__handle_start(handle);
|
||||
|
||||
return 0;
|
||||
@@ -107,7 +77,7 @@ int uv_async_send(uv_async_t* handle) {
|
||||
/* or closed handle. */
|
||||
assert(!(handle->flags & UV_HANDLE_CLOSING));
|
||||
|
||||
if (!uv_atomic_exchange_set(&handle->async_sent)) {
|
||||
if (!uv__atomic_exchange_set(&handle->async_sent)) {
|
||||
POST_COMPLETION_FOR_REQ(loop, &handle->async_req);
|
||||
}
|
||||
|
||||
|
||||
56
deps/uv/src/win/atomicops-inl.h
vendored
Normal file
56
deps/uv/src/win/atomicops-inl.h
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef UV_WIN_ATOMICOPS_INL_H_
|
||||
#define UV_WIN_ATOMICOPS_INL_H_
|
||||
|
||||
#include "uv.h"
|
||||
|
||||
|
||||
/* Atomic set operation on char */
|
||||
#ifdef _MSC_VER /* MSVC */
|
||||
|
||||
/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */
|
||||
/* efficient than InterlockedExchange, but InterlockedExchange8 does not */
|
||||
/* exist, and interlocked operations on larger targets might require the */
|
||||
/* target to be aligned. */
|
||||
#pragma intrinsic(_InterlockedOr8)
|
||||
|
||||
static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) {
|
||||
return _InterlockedOr8(target, 1);
|
||||
}
|
||||
|
||||
#else /* GCC */
|
||||
|
||||
/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
|
||||
static inline char uv__atomic_exchange_set(char volatile* target) {
|
||||
const char one = 1;
|
||||
char old_value;
|
||||
__asm__ __volatile__ ("lock xchgb %0, %1\n\t"
|
||||
: "=r"(old_value), "=m"(*target)
|
||||
: "0"(one), "m"(*target)
|
||||
: "memory");
|
||||
return old_value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* UV_WIN_ATOMICOPS_INL_H_ */
|
||||
5
deps/uv/src/win/core.c
vendored
5
deps/uv/src/win/core.c
vendored
@@ -55,6 +55,9 @@ static void uv_init(void) {
|
||||
/* Initialize FS */
|
||||
uv_fs_init();
|
||||
|
||||
/* Initialize signal stuff */
|
||||
uv_signals_init();
|
||||
|
||||
/* Initialize console */
|
||||
uv_console_init();
|
||||
|
||||
@@ -96,8 +99,6 @@ static void uv_loop_init(uv_loop_t* loop) {
|
||||
loop->active_udp_streams = 0;
|
||||
|
||||
loop->last_err = uv_ok_;
|
||||
|
||||
memset(&loop->counters, 0, sizeof loop->counters);
|
||||
}
|
||||
|
||||
|
||||
|
||||
2
deps/uv/src/win/dl.c
vendored
2
deps/uv/src/win/dl.c
vendored
@@ -26,7 +26,7 @@ static int uv__dlerror(uv_lib_t* lib, int errorno);
|
||||
|
||||
|
||||
int uv_dlopen(const char* filename, uv_lib_t* lib) {
|
||||
wchar_t filename_w[32768];
|
||||
WCHAR filename_w[32768];
|
||||
|
||||
lib->handle = NULL;
|
||||
lib->errmsg = NULL;
|
||||
|
||||
4
deps/uv/src/win/error.c
vendored
4
deps/uv/src/win/error.c
vendored
@@ -110,8 +110,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
|
||||
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_OPERATION_ABORTED: return UV_ECANCELED;
|
||||
case WSAEINTR: return UV_ECANCELED;
|
||||
case ERROR_INVALID_DATA: return UV_EINVAL;
|
||||
case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
|
||||
case WSAEINVAL: return UV_EINVAL;
|
||||
|
||||
36
deps/uv/src/win/fs-event.c
vendored
36
deps/uv/src/win/fs-event.c
vendored
@@ -55,8 +55,6 @@ static void uv_fs_event_init_handle(uv_loop_t* loop, uv_fs_event_t* handle,
|
||||
}
|
||||
|
||||
uv__handle_start(handle);
|
||||
|
||||
loop->counters.fs_event_init++;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,15 +88,15 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
|
||||
}
|
||||
|
||||
|
||||
static int uv_split_path(const wchar_t* filename, wchar_t** dir,
|
||||
wchar_t** file) {
|
||||
static int uv_split_path(const WCHAR* filename, WCHAR** dir,
|
||||
WCHAR** file) {
|
||||
int len = wcslen(filename);
|
||||
int i = len;
|
||||
while (i > 0 && filename[--i] != '\\' && filename[i] != '/');
|
||||
|
||||
if (i == 0) {
|
||||
if (dir) {
|
||||
*dir = (wchar_t*)malloc((MAX_PATH + 1) * sizeof(wchar_t));
|
||||
*dir = (WCHAR*)malloc((MAX_PATH + 1) * sizeof(WCHAR));
|
||||
if (!*dir) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
@@ -113,7 +111,7 @@ static int uv_split_path(const wchar_t* filename, wchar_t** dir,
|
||||
*file = wcsdup(filename);
|
||||
} else {
|
||||
if (dir) {
|
||||
*dir = (wchar_t*)malloc((i + 1) * sizeof(wchar_t));
|
||||
*dir = (WCHAR*)malloc((i + 1) * sizeof(WCHAR));
|
||||
if (!*dir) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
@@ -121,7 +119,7 @@ static int uv_split_path(const wchar_t* filename, wchar_t** dir,
|
||||
(*dir)[i] = L'\0';
|
||||
}
|
||||
|
||||
*file = (wchar_t*)malloc((len - i) * sizeof(wchar_t));
|
||||
*file = (WCHAR*)malloc((len - i) * sizeof(WCHAR));
|
||||
if (!*file) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
@@ -137,8 +135,8 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
|
||||
const char* filename, uv_fs_event_cb cb, int flags) {
|
||||
int name_size, is_path_dir;
|
||||
DWORD attr, last_error;
|
||||
wchar_t* dir = NULL, *dir_to_watch, *filenamew = NULL;
|
||||
wchar_t short_path[MAX_PATH];
|
||||
WCHAR* dir = NULL, *dir_to_watch, *filenamew = NULL;
|
||||
WCHAR short_path[MAX_PATH];
|
||||
|
||||
/* We don't support any flags yet. */
|
||||
assert(!flags);
|
||||
@@ -146,14 +144,14 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
|
||||
uv_fs_event_init_handle(loop, handle, filename, cb);
|
||||
|
||||
/* Convert name to UTF16. */
|
||||
name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(wchar_t);
|
||||
filenamew = (wchar_t*)malloc(name_size);
|
||||
name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(WCHAR);
|
||||
filenamew = (WCHAR*)malloc(name_size);
|
||||
if (!filenamew) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
if (!uv_utf8_to_utf16(filename, filenamew,
|
||||
name_size / sizeof(wchar_t))) {
|
||||
name_size / sizeof(WCHAR))) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
@@ -294,7 +292,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
||||
FILE_NOTIFY_INFORMATION* file_info;
|
||||
int sizew, size, result;
|
||||
char* filename = NULL;
|
||||
wchar_t* filenamew, *long_filenamew = NULL;
|
||||
WCHAR* filenamew, *long_filenamew = NULL;
|
||||
DWORD offset = 0;
|
||||
|
||||
assert(req->type == UV_FS_EVENT_REQ);
|
||||
@@ -323,9 +321,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
||||
*/
|
||||
if (handle->dirw ||
|
||||
_wcsnicmp(handle->filew, file_info->FileName,
|
||||
file_info->FileNameLength / sizeof(wchar_t)) == 0 ||
|
||||
file_info->FileNameLength / sizeof(WCHAR)) == 0 ||
|
||||
_wcsnicmp(handle->short_filew, file_info->FileName,
|
||||
file_info->FileNameLength / sizeof(wchar_t)) == 0) {
|
||||
file_info->FileNameLength / sizeof(WCHAR)) == 0) {
|
||||
|
||||
if (handle->dirw) {
|
||||
/*
|
||||
@@ -337,9 +335,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
||||
file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
|
||||
/* Construct a full path to the file. */
|
||||
size = wcslen(handle->dirw) +
|
||||
file_info->FileNameLength / sizeof(wchar_t) + 2;
|
||||
file_info->FileNameLength / sizeof(WCHAR) + 2;
|
||||
|
||||
filenamew = (wchar_t*)malloc(size * sizeof(wchar_t));
|
||||
filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
|
||||
if (!filenamew) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
@@ -353,7 +351,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
||||
size = GetLongPathNameW(filenamew, NULL, 0);
|
||||
|
||||
if (size) {
|
||||
long_filenamew = (wchar_t*)malloc(size * sizeof(wchar_t));
|
||||
long_filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
|
||||
if (!long_filenamew) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
@@ -388,7 +386,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
||||
*/
|
||||
if (!long_filenamew) {
|
||||
filenamew = file_info->FileName;
|
||||
sizew = file_info->FileNameLength / sizeof(wchar_t);
|
||||
sizew = file_info->FileNameLength / sizeof(WCHAR);
|
||||
}
|
||||
} else {
|
||||
/* Removed or renamed callbacks don't provide filename. */
|
||||
|
||||
22
deps/uv/src/win/getaddrinfo.c
vendored
22
deps/uv/src/win/getaddrinfo.c
vendored
@@ -37,13 +37,13 @@
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
size_t ai_addrlen;
|
||||
wchar_t* ai_canonname;
|
||||
WCHAR* ai_canonname;
|
||||
struct sockaddr* ai_addr;
|
||||
struct addrinfoW* ai_next;
|
||||
} ADDRINFOW, *PADDRINFOW;
|
||||
|
||||
DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const wchar_t* node,
|
||||
const wchar_t* service,
|
||||
DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const WCHAR* node,
|
||||
const WCHAR* service,
|
||||
const ADDRINFOW* hints,
|
||||
PADDRINFOW* result);
|
||||
|
||||
@@ -271,7 +271,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
|
||||
/* calculate required memory size for all input values */
|
||||
if (node != NULL) {
|
||||
nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(wchar_t));
|
||||
nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(WCHAR));
|
||||
if (nodesize == 0) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
goto error;
|
||||
@@ -280,7 +280,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
|
||||
if (service != NULL) {
|
||||
servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
|
||||
sizeof(wchar_t));
|
||||
sizeof(WCHAR));
|
||||
if (servicesize == 0) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
goto error;
|
||||
@@ -303,10 +303,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
/* convert node string to UTF16 into allocated memory and save pointer in */
|
||||
/* the reques. */
|
||||
if (node != NULL) {
|
||||
req->node = (wchar_t*)alloc_ptr;
|
||||
req->node = (WCHAR*)alloc_ptr;
|
||||
if (uv_utf8_to_utf16(node,
|
||||
(wchar_t*) alloc_ptr,
|
||||
nodesize / sizeof(wchar_t)) == 0) {
|
||||
(WCHAR*) alloc_ptr,
|
||||
nodesize / sizeof(WCHAR)) == 0) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
goto error;
|
||||
}
|
||||
@@ -318,10 +318,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
/* convert service string to UTF16 into allocated memory and save pointer */
|
||||
/* in the req. */
|
||||
if (service != NULL) {
|
||||
req->service = (wchar_t*)alloc_ptr;
|
||||
req->service = (WCHAR*)alloc_ptr;
|
||||
if (uv_utf8_to_utf16(service,
|
||||
(wchar_t*) alloc_ptr,
|
||||
servicesize / sizeof(wchar_t)) == 0) {
|
||||
(WCHAR*) alloc_ptr,
|
||||
servicesize / sizeof(WCHAR)) == 0) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
goto error;
|
||||
}
|
||||
|
||||
4
deps/uv/src/win/handle-inl.h
vendored
4
deps/uv/src/win/handle-inl.h
vendored
@@ -123,6 +123,10 @@ INLINE static void uv_process_endgames(uv_loop_t* loop) {
|
||||
uv_async_endgame(loop, (uv_async_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_SIGNAL:
|
||||
uv_signal_endgame(loop, (uv_signal_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_PROCESS:
|
||||
uv_process_endgame(loop, (uv_process_t*) handle);
|
||||
break;
|
||||
|
||||
4
deps/uv/src/win/handle.c
vendored
4
deps/uv/src/win/handle.c
vendored
@@ -124,6 +124,10 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
|
||||
uv_async_close(loop, (uv_async_t*) handle);
|
||||
return;
|
||||
|
||||
case UV_SIGNAL:
|
||||
uv_signal_close(loop, (uv_signal_t*) handle);
|
||||
return;
|
||||
|
||||
case UV_PROCESS:
|
||||
uv_process_close(loop, (uv_process_t*) handle);
|
||||
return;
|
||||
|
||||
25
deps/uv/src/win/internal.h
vendored
25
deps/uv/src/win/internal.h
vendored
@@ -74,9 +74,10 @@
|
||||
#define UV_HANDLE_PIPESERVER 0x02000000
|
||||
|
||||
/* Only used by uv_tty_t handles. */
|
||||
#define UV_HANDLE_TTY_RAW 0x01000000
|
||||
#define UV_HANDLE_TTY_SAVED_POSITION 0x02000000
|
||||
#define UV_HANDLE_TTY_SAVED_ATTRIBUTES 0x04000000
|
||||
#define UV_HANDLE_TTY_READABLE 0x01000000
|
||||
#define UV_HANDLE_TTY_RAW 0x02000000
|
||||
#define UV_HANDLE_TTY_SAVED_POSITION 0x04000000
|
||||
#define UV_HANDLE_TTY_SAVED_ATTRIBUTES 0x08000000
|
||||
|
||||
/* Only used by uv_poll_t handles. */
|
||||
#define UV_HANDLE_POLL_SLOW 0x02000000
|
||||
@@ -134,7 +135,7 @@ void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
|
||||
/*
|
||||
* Pipes
|
||||
*/
|
||||
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
uv_err_t uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
char* name, size_t nameSize);
|
||||
|
||||
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
|
||||
@@ -231,11 +232,23 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
|
||||
uv_req_t* req);
|
||||
|
||||
|
||||
/*
|
||||
* Signal watcher
|
||||
*/
|
||||
void uv_signals_init();
|
||||
int uv__signal_dispatch(int signum);
|
||||
|
||||
void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle);
|
||||
void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle);
|
||||
|
||||
void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
|
||||
uv_req_t* req);
|
||||
|
||||
|
||||
/*
|
||||
* Spawn
|
||||
*/
|
||||
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle);
|
||||
void uv_process_proc_close(uv_loop_t* loop, uv_process_t* handle);
|
||||
void uv_process_close(uv_loop_t* loop, uv_process_t* handle);
|
||||
void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle);
|
||||
|
||||
@@ -287,7 +300,7 @@ uv_err_code uv_translate_sys_error(int sys_errno);
|
||||
/*
|
||||
* Process stdio handles.
|
||||
*/
|
||||
int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
|
||||
uv_err_t uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
|
||||
BYTE** buffer_ptr);
|
||||
void uv__stdio_destroy(BYTE* buffer);
|
||||
void uv__stdio_noinherit(BYTE* buffer);
|
||||
|
||||
1
deps/uv/src/win/loop-watcher.c
vendored
1
deps/uv/src/win/loop-watcher.c
vendored
@@ -39,7 +39,6 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
||||
#define UV_LOOP_WATCHER_DEFINE(name, NAME) \
|
||||
int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
|
||||
uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME); \
|
||||
loop->counters.name##_init++; \
|
||||
\
|
||||
return 0; \
|
||||
} \
|
||||
|
||||
35
deps/uv/src/win/pipe.c
vendored
35
deps/uv/src/win/pipe.c
vendored
@@ -88,8 +88,6 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req);
|
||||
|
||||
loop->counters.pipe_init++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -159,11 +157,11 @@ static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
|
||||
}
|
||||
|
||||
|
||||
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
uv_err_t uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
char* name, size_t nameSize) {
|
||||
HANDLE pipeHandle;
|
||||
int errorno;
|
||||
int err;
|
||||
uv_err_t err;
|
||||
char* ptr = (char*)handle;
|
||||
|
||||
for (;;) {
|
||||
@@ -181,9 +179,8 @@ int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
|
||||
errorno = GetLastError();
|
||||
if (errorno != ERROR_PIPE_BUSY && errorno != ERROR_ACCESS_DENIED) {
|
||||
uv__set_sys_error(loop, errorno);
|
||||
err = -1;
|
||||
goto done;
|
||||
err = uv__new_sys_error(errorno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Pipe name collision. Increment the pointer and try again. */
|
||||
@@ -194,17 +191,17 @@ int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||
loop->iocp,
|
||||
(ULONG_PTR)handle,
|
||||
0) == NULL) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
err = -1;
|
||||
goto done;
|
||||
err = uv__new_sys_error(GetLastError());
|
||||
goto error;
|
||||
}
|
||||
|
||||
uv_pipe_connection_init(handle);
|
||||
handle->handle = pipeHandle;
|
||||
err = 0;
|
||||
|
||||
done:
|
||||
if (err && pipeHandle != INVALID_HANDLE_VALUE) {
|
||||
return uv_ok_;
|
||||
|
||||
error:
|
||||
if (pipeHandle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(pipeHandle);
|
||||
}
|
||||
|
||||
@@ -433,13 +430,13 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
||||
}
|
||||
|
||||
/* Convert name to UTF16. */
|
||||
nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
|
||||
handle->name = (wchar_t*)malloc(nameSize);
|
||||
nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
|
||||
handle->name = (WCHAR*)malloc(nameSize);
|
||||
if (!handle->name) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
|
||||
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
@@ -545,13 +542,13 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
|
||||
req->cb = cb;
|
||||
|
||||
/* Convert name to UTF16. */
|
||||
nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
|
||||
handle->name = (wchar_t*)malloc(nameSize);
|
||||
nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
|
||||
handle->name = (WCHAR*)malloc(nameSize);
|
||||
if (!handle->name) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
|
||||
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
|
||||
errorno = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
2
deps/uv/src/win/poll.c
vendored
2
deps/uv/src/win/poll.c
vendored
@@ -558,8 +558,6 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
|
||||
handle->poll_req_2.type = UV_POLL_REQ;
|
||||
handle->poll_req_2.data = handle;
|
||||
|
||||
loop->counters.poll_init++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
66
deps/uv/src/win/process-stdio.c
vendored
66
deps/uv/src/win/process-stdio.c
vendored
@@ -94,13 +94,14 @@ void uv_disable_stdio_inheritance(void) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
|
||||
HANDLE* child_pipe_ptr, unsigned int flags) {
|
||||
static uv_err_t uv__create_stdio_pipe_pair(uv_loop_t* loop,
|
||||
uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) {
|
||||
char pipe_name[64];
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
DWORD server_access = 0;
|
||||
DWORD client_access = 0;
|
||||
HANDLE child_pipe = INVALID_HANDLE_VALUE;
|
||||
uv_err_t err;
|
||||
|
||||
if (flags & UV_READABLE_PIPE) {
|
||||
server_access |= PIPE_ACCESS_OUTBOUND;
|
||||
@@ -112,13 +113,13 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
|
||||
}
|
||||
|
||||
/* Create server pipe handle. */
|
||||
if (uv_stdio_pipe_server(loop,
|
||||
server_pipe,
|
||||
server_access,
|
||||
pipe_name,
|
||||
sizeof(pipe_name)) < 0) {
|
||||
err = uv_stdio_pipe_server(loop,
|
||||
server_pipe,
|
||||
server_access,
|
||||
pipe_name,
|
||||
sizeof(pipe_name));
|
||||
if (err.code != UV_OK)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Create child pipe handle. */
|
||||
sa.nLength = sizeof sa;
|
||||
@@ -133,7 +134,7 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
|
||||
server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0,
|
||||
NULL);
|
||||
if (child_pipe == INVALID_HANDLE_VALUE) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
err = uv__new_sys_error(GetLastError());
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -157,13 +158,13 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
|
||||
/* both ends of the pipe created. */
|
||||
if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
|
||||
if (GetLastError() != ERROR_PIPE_CONNECTED) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
err = uv__new_sys_error(GetLastError());
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
*child_pipe_ptr = child_pipe;
|
||||
return 0;
|
||||
return uv_ok_;
|
||||
|
||||
error:
|
||||
if (server_pipe->handle != INVALID_HANDLE_VALUE) {
|
||||
@@ -174,7 +175,7 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
|
||||
CloseHandle(child_pipe);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +228,7 @@ static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__create_nul_handle(uv_loop_t* loop, HANDLE* handle_ptr,
|
||||
uv_err_t uv__create_nul_handle(HANDLE* handle_ptr,
|
||||
DWORD access) {
|
||||
HANDLE handle;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
@@ -244,36 +245,34 @@ static int uv__create_nul_handle(uv_loop_t* loop, HANDLE* handle_ptr,
|
||||
0,
|
||||
NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
return -1;
|
||||
return uv__new_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
*handle_ptr = handle;
|
||||
return 0;
|
||||
return uv_ok_;
|
||||
}
|
||||
|
||||
|
||||
int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
|
||||
uv_err_t uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
|
||||
BYTE** buffer_ptr) {
|
||||
BYTE* buffer;
|
||||
int count, i;
|
||||
uv_err_t err;
|
||||
|
||||
count = options->stdio_count;
|
||||
|
||||
if (count < 0 || count > 255) {
|
||||
/* Only support FDs 0-255 */
|
||||
uv__set_artificial_error(loop, UV_ENOTSUP);
|
||||
return -1;
|
||||
return uv__new_artificial_error(UV_ENOTSUP);
|
||||
} else if (count < 3) {
|
||||
/* There should always be at least 3 stdio handles. */
|
||||
count = 3;
|
||||
}
|
||||
|
||||
/* Allocate the child stdio buffer */
|
||||
buffer = malloc(CHILD_STDIO_SIZE(count));
|
||||
buffer = (BYTE*) malloc(CHILD_STDIO_SIZE(count));
|
||||
if (buffer == NULL) {
|
||||
uv__set_artificial_error(loop, UV_ENOMEM);
|
||||
return -1;
|
||||
return uv__new_artificial_error(UV_ENOMEM);
|
||||
}
|
||||
|
||||
/* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */
|
||||
@@ -304,11 +303,12 @@ int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
|
||||
if (i <= 2) {
|
||||
DWORD access = (i == 0) ? FILE_GENERIC_READ :
|
||||
FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES;
|
||||
if (uv__create_nul_handle(loop,
|
||||
&CHILD_STDIO_HANDLE(buffer, i),
|
||||
access) < 0) {
|
||||
|
||||
err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i),
|
||||
access);
|
||||
if (err.code != UV_OK)
|
||||
goto error;
|
||||
}
|
||||
|
||||
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
|
||||
}
|
||||
break;
|
||||
@@ -326,12 +326,12 @@ int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
|
||||
assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION));
|
||||
assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER));
|
||||
|
||||
if (uv__create_stdio_pipe_pair(loop,
|
||||
parent_pipe,
|
||||
&child_pipe,
|
||||
fdopt.flags) < 0) {
|
||||
err = uv__create_stdio_pipe_pair(loop,
|
||||
parent_pipe,
|
||||
&child_pipe,
|
||||
fdopt.flags);
|
||||
if (err.code != UV_OK)
|
||||
goto error;
|
||||
}
|
||||
|
||||
CHILD_STDIO_HANDLE(buffer, i) = child_pipe;
|
||||
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE;
|
||||
@@ -430,11 +430,11 @@ int uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
|
||||
}
|
||||
|
||||
*buffer_ptr = buffer;
|
||||
return 0;
|
||||
return uv_ok_;
|
||||
|
||||
error:
|
||||
uv__stdio_destroy(buffer);
|
||||
return -1;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
488
deps/uv/src/win/process.c
vendored
488
deps/uv/src/win/process.c
vendored
@@ -36,7 +36,7 @@
|
||||
|
||||
typedef struct env_var {
|
||||
const char* narrow;
|
||||
const wchar_t* wide;
|
||||
const WCHAR* wide;
|
||||
int len; /* including null or '=' */
|
||||
int supplied;
|
||||
int value_len;
|
||||
@@ -45,38 +45,52 @@ typedef struct env_var {
|
||||
#define E_V(str) { str "=", L##str, sizeof(str), 0, 0 }
|
||||
|
||||
|
||||
#define UTF8_TO_UTF16(s, t) \
|
||||
size = uv_utf8_to_utf16(s, NULL, 0) * sizeof(wchar_t); \
|
||||
t = (wchar_t*)malloc(size); \
|
||||
if (!t) { \
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); \
|
||||
} \
|
||||
if (!uv_utf8_to_utf16(s, t, size / sizeof(wchar_t))) { \
|
||||
uv__set_sys_error(loop, GetLastError()); \
|
||||
err = -1; \
|
||||
goto done; \
|
||||
static uv_err_t uv_utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) {
|
||||
int ws_len, r;
|
||||
WCHAR* ws;
|
||||
|
||||
ws_len = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
s,
|
||||
-1,
|
||||
NULL,
|
||||
0);
|
||||
if (ws_len <= 0) {
|
||||
return uv__new_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
ws = (WCHAR*) malloc(ws_len * sizeof(WCHAR));
|
||||
if (ws == NULL) {
|
||||
return uv__new_artificial_error(UV_ENOMEM);
|
||||
}
|
||||
|
||||
r = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
s,
|
||||
-1,
|
||||
ws,
|
||||
ws_len);
|
||||
assert(r == ws_len);
|
||||
|
||||
*ws_ptr = ws;
|
||||
return uv_ok_;
|
||||
}
|
||||
|
||||
|
||||
static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
|
||||
uv__handle_init(loop, (uv_handle_t*) handle, UV_PROCESS);
|
||||
handle->exit_cb = NULL;
|
||||
handle->pid = 0;
|
||||
handle->spawn_error = uv_ok_;
|
||||
handle->exit_signal = 0;
|
||||
handle->wait_handle = INVALID_HANDLE_VALUE;
|
||||
handle->process_handle = INVALID_HANDLE_VALUE;
|
||||
handle->close_handle = INVALID_HANDLE_VALUE;
|
||||
handle->child_stdio_buffer = NULL;
|
||||
handle->exit_cb_pending = 0;
|
||||
|
||||
uv_req_init(loop, (uv_req_t*)&handle->exit_req);
|
||||
handle->exit_req.type = UV_PROCESS_EXIT;
|
||||
handle->exit_req.data = handle;
|
||||
uv_req_init(loop, (uv_req_t*)&handle->close_req);
|
||||
handle->close_req.type = UV_PROCESS_CLOSE;
|
||||
handle->close_req.data = handle;
|
||||
|
||||
loop->counters.handle_init++;
|
||||
loop->counters.process_init++;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,15 +101,15 @@ static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
|
||||
/*
|
||||
* Helper function for search_path
|
||||
*/
|
||||
static wchar_t* search_path_join_test(const wchar_t* dir,
|
||||
static WCHAR* search_path_join_test(const WCHAR* dir,
|
||||
int dir_len,
|
||||
const wchar_t* name,
|
||||
const WCHAR* name,
|
||||
int name_len,
|
||||
const wchar_t* ext,
|
||||
const WCHAR* ext,
|
||||
int ext_len,
|
||||
const wchar_t* cwd,
|
||||
const WCHAR* cwd,
|
||||
int cwd_len) {
|
||||
wchar_t *result, *result_pos;
|
||||
WCHAR *result, *result_pos;
|
||||
DWORD attrs;
|
||||
|
||||
if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
|
||||
@@ -121,7 +135,7 @@ static wchar_t* search_path_join_test(const wchar_t* dir,
|
||||
}
|
||||
|
||||
/* Allocate buffer for output */
|
||||
result = result_pos = (wchar_t*)malloc(sizeof(wchar_t) *
|
||||
result = result_pos = (WCHAR*)malloc(sizeof(WCHAR) *
|
||||
(cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1));
|
||||
|
||||
/* Copy cwd */
|
||||
@@ -178,14 +192,14 @@ static wchar_t* search_path_join_test(const wchar_t* dir,
|
||||
/*
|
||||
* Helper function for search_path
|
||||
*/
|
||||
static wchar_t* path_search_walk_ext(const wchar_t *dir,
|
||||
static WCHAR* path_search_walk_ext(const WCHAR *dir,
|
||||
int dir_len,
|
||||
const wchar_t *name,
|
||||
const WCHAR *name,
|
||||
int name_len,
|
||||
wchar_t *cwd,
|
||||
WCHAR *cwd,
|
||||
int cwd_len,
|
||||
int name_has_ext) {
|
||||
wchar_t* result;
|
||||
WCHAR* result;
|
||||
|
||||
/* If the name itself has a nonempty extension, try this extension first */
|
||||
if (name_has_ext) {
|
||||
@@ -259,14 +273,14 @@ static wchar_t* path_search_walk_ext(const wchar_t *dir,
|
||||
*
|
||||
* TODO: correctly interpret UNC paths
|
||||
*/
|
||||
static wchar_t* search_path(const wchar_t *file,
|
||||
wchar_t *cwd,
|
||||
const wchar_t *path) {
|
||||
static WCHAR* search_path(const WCHAR *file,
|
||||
WCHAR *cwd,
|
||||
const WCHAR *path) {
|
||||
int file_has_dir;
|
||||
wchar_t* result = NULL;
|
||||
wchar_t *file_name_start;
|
||||
wchar_t *dot;
|
||||
const wchar_t *dir_start, *dir_end, *dir_path;
|
||||
WCHAR* result = NULL;
|
||||
WCHAR *file_name_start;
|
||||
WCHAR *dot;
|
||||
const WCHAR *dir_start, *dir_end, *dir_path;
|
||||
int dir_len;
|
||||
int name_has_ext;
|
||||
|
||||
@@ -283,7 +297,7 @@ static wchar_t* search_path(const wchar_t *file,
|
||||
|
||||
/* Find the start of the filename so we can split the directory from the */
|
||||
/* name. */
|
||||
for (file_name_start = (wchar_t*)file + file_len;
|
||||
for (file_name_start = (WCHAR*)file + file_len;
|
||||
file_name_start > file
|
||||
&& file_name_start[-1] != L'\\'
|
||||
&& file_name_start[-1] != L'/'
|
||||
@@ -365,10 +379,10 @@ static wchar_t* search_path(const wchar_t *file,
|
||||
* Quotes command line arguments
|
||||
* Returns a pointer to the end (next char to be written) of the buffer
|
||||
*/
|
||||
wchar_t* quote_cmd_arg(const wchar_t *source, wchar_t *target) {
|
||||
WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) {
|
||||
int len = wcslen(source),
|
||||
i, quote_hit;
|
||||
wchar_t* start;
|
||||
WCHAR* start;
|
||||
|
||||
/*
|
||||
* Check if the string must be quoted;
|
||||
@@ -438,61 +452,92 @@ wchar_t* quote_cmd_arg(const wchar_t *source, wchar_t *target) {
|
||||
}
|
||||
|
||||
|
||||
wchar_t* make_program_args(char** args, int verbatim_arguments) {
|
||||
wchar_t* dst;
|
||||
wchar_t* ptr;
|
||||
uv_err_t make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
|
||||
char** arg;
|
||||
size_t size = 0;
|
||||
size_t len;
|
||||
WCHAR* dst = NULL;
|
||||
WCHAR* temp_buffer = NULL;
|
||||
size_t dst_len = 0;
|
||||
size_t temp_buffer_len = 0;
|
||||
WCHAR* pos;
|
||||
int arg_count = 0;
|
||||
wchar_t* buffer;
|
||||
int arg_size;
|
||||
int buffer_size = 0;
|
||||
uv_err_t err = uv_ok_;
|
||||
|
||||
/* Count the required size. */
|
||||
for (arg = args; *arg; arg++) {
|
||||
arg_size = uv_utf8_to_utf16(*arg, NULL, 0) * sizeof(wchar_t);
|
||||
size += arg_size;
|
||||
buffer_size = arg_size > buffer_size ? arg_size : buffer_size;
|
||||
DWORD arg_len;
|
||||
|
||||
arg_len = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
*arg,
|
||||
-1,
|
||||
NULL,
|
||||
0);
|
||||
if (arg_len == 0) {
|
||||
return uv__new_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
dst_len += arg_len;
|
||||
|
||||
if (arg_len > temp_buffer_len)
|
||||
temp_buffer_len = arg_len;
|
||||
|
||||
arg_count++;
|
||||
}
|
||||
|
||||
/* Adjust for potential quotes. Also assume the worst-case scenario
|
||||
/* Adjust for potential quotes. Also assume the worst-case scenario */
|
||||
/* that every character needs escaping, so we need twice as much space. */
|
||||
size = size * 2 + arg_count * 2;
|
||||
dst_len = dst_len * 2 + arg_count * 2;
|
||||
|
||||
dst = (wchar_t*)malloc(size);
|
||||
if (!dst) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
/* Allocate buffer for the final command line. */
|
||||
dst = (WCHAR*) malloc(dst_len * sizeof(WCHAR));
|
||||
if (dst == NULL) {
|
||||
err = uv__new_artificial_error(UV_ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
|
||||
buffer = (wchar_t*)malloc(buffer_size);
|
||||
if (!buffer) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
/* Allocate temporary working buffer. */
|
||||
temp_buffer = (WCHAR*) malloc(temp_buffer_len * sizeof(WCHAR));
|
||||
if (temp_buffer == NULL) {
|
||||
err = uv__new_artificial_error(UV_ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ptr = dst;
|
||||
pos = dst;
|
||||
for (arg = args; *arg; arg++) {
|
||||
len = uv_utf8_to_utf16(*arg, buffer, (size_t)(size - (ptr - dst)));
|
||||
if (!len) {
|
||||
DWORD arg_len;
|
||||
|
||||
/* Convert argument to wide char. */
|
||||
arg_len = MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
*arg,
|
||||
-1,
|
||||
temp_buffer,
|
||||
dst + dst_len - pos);
|
||||
if (arg_len == 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (verbatim_arguments) {
|
||||
wcscpy(ptr, buffer);
|
||||
ptr += len - 1;
|
||||
/* Copy verbatim. */
|
||||
wcscpy(pos, temp_buffer);
|
||||
pos += arg_len - 1;
|
||||
} else {
|
||||
ptr = quote_cmd_arg(buffer, ptr);
|
||||
/* Quote/escape, if needed. */
|
||||
pos = quote_cmd_arg(temp_buffer, pos);
|
||||
}
|
||||
*ptr++ = *(arg + 1) ? L' ' : L'\0';
|
||||
|
||||
*pos++ = *(arg + 1) ? L' ' : L'\0';
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
return dst;
|
||||
free(temp_buffer);
|
||||
|
||||
*dst_ptr = dst;
|
||||
return uv_ok_;
|
||||
|
||||
error:
|
||||
free(dst);
|
||||
free(buffer);
|
||||
return NULL;
|
||||
free(temp_buffer);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -526,11 +571,11 @@ static void check_required_vars_contains_var(env_var_t* required, int size,
|
||||
* these get defined if the input environment block does not contain any
|
||||
* values for them.
|
||||
*/
|
||||
wchar_t* make_program_env(char** env_block) {
|
||||
wchar_t* dst;
|
||||
wchar_t* ptr;
|
||||
WCHAR* make_program_env(char** env_block) {
|
||||
WCHAR* dst;
|
||||
WCHAR* ptr;
|
||||
char** env;
|
||||
int env_len = 1 * sizeof(wchar_t); /* room for closing null */
|
||||
int env_len = 1 * sizeof(WCHAR); /* room for closing null */
|
||||
int len;
|
||||
int i;
|
||||
DWORD var_size;
|
||||
@@ -545,18 +590,18 @@ wchar_t* make_program_env(char** env_block) {
|
||||
check_required_vars_contains_var(required_vars,
|
||||
ARRAY_SIZE(required_vars),
|
||||
*env);
|
||||
env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(wchar_t));
|
||||
env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(required_vars); ++i) {
|
||||
if (!required_vars[i].supplied) {
|
||||
env_len += required_vars[i].len * sizeof(wchar_t);
|
||||
env_len += required_vars[i].len * sizeof(WCHAR);
|
||||
var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0);
|
||||
if (var_size == 0) {
|
||||
uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
|
||||
}
|
||||
required_vars[i].value_len = (int)var_size;
|
||||
env_len += (int)var_size * sizeof(wchar_t);
|
||||
env_len += (int)var_size * sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -600,74 +645,17 @@ wchar_t* make_program_env(char** env_block) {
|
||||
* a child process has exited.
|
||||
*/
|
||||
static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {
|
||||
uv_process_t* process = (uv_process_t*)data;
|
||||
uv_loop_t* loop = process->loop;
|
||||
|
||||
assert(didTimeout == FALSE);
|
||||
assert(process);
|
||||
|
||||
/* Post completed */
|
||||
POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called on Windows thread-pool thread to indicate that
|
||||
* UnregisterWaitEx has completed.
|
||||
*/
|
||||
static void CALLBACK close_wait_callback(void* data, BOOLEAN didTimeout) {
|
||||
uv_process_t* process = (uv_process_t*)data;
|
||||
uv_loop_t* loop = process->loop;
|
||||
|
||||
assert(didTimeout == FALSE);
|
||||
assert(process);
|
||||
|
||||
/* Post completed */
|
||||
POST_COMPLETION_FOR_REQ(loop, &process->close_req);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called on windows thread pool when CreateProcess failed. It writes an error
|
||||
* message to the process' intended stderr and then posts a PROCESS_EXIT
|
||||
* packet to the completion port.
|
||||
*/
|
||||
static DWORD WINAPI spawn_failure(void* data) {
|
||||
char syscall[] = "CreateProcessW: ";
|
||||
char unknown[] = "unknown error\n";
|
||||
uv_process_t* process = (uv_process_t*) data;
|
||||
uv_loop_t* loop = process->loop;
|
||||
HANDLE child_stderr = uv__stdio_handle(process->child_stdio_buffer, 2);
|
||||
char* buf = NULL;
|
||||
DWORD count, written;
|
||||
|
||||
if (child_stderr != INVALID_HANDLE_VALUE) {
|
||||
WriteFile(child_stderr, syscall, sizeof(syscall) - 1, &written, NULL);
|
||||
assert(didTimeout == FALSE);
|
||||
assert(process);
|
||||
assert(!process->exit_cb_pending);
|
||||
|
||||
count = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
process->spawn_errno,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR) &buf,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (buf != NULL && count > 0) {
|
||||
WriteFile(child_stderr, buf, count, &written, NULL);
|
||||
LocalFree(buf);
|
||||
} else {
|
||||
WriteFile(child_stderr, unknown, sizeof(unknown) - 1, &written, NULL);
|
||||
}
|
||||
|
||||
FlushFileBuffers(child_stderr);
|
||||
}
|
||||
process->exit_cb_pending = 1;
|
||||
|
||||
/* Post completed */
|
||||
POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -675,8 +663,13 @@ static DWORD WINAPI spawn_failure(void* data) {
|
||||
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
|
||||
DWORD exit_code;
|
||||
|
||||
/* FIXME: race condition. */
|
||||
assert(handle->exit_cb_pending);
|
||||
handle->exit_cb_pending = 0;
|
||||
|
||||
/* If we're closing, don't call the exit callback. Just schedule a close */
|
||||
/* callback now. */
|
||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||
uv_want_endgame(loop, (uv_handle_t*) handle);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -686,71 +679,68 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
|
||||
handle->wait_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (handle->process_handle == INVALID_HANDLE_VALUE ||
|
||||
!GetExitCodeProcess(handle->process_handle, &exit_code)) {
|
||||
/* The process never even started in the first place, or we were unable */
|
||||
/* to obtain the exit code. */
|
||||
exit_code = 127;
|
||||
}
|
||||
|
||||
/* Set the handle to inactive: no callbacks will be made after the exit */
|
||||
/* callback.*/
|
||||
uv__handle_stop(handle);
|
||||
|
||||
if (handle->spawn_error.code != UV_OK) {
|
||||
/* Spawning failed. */
|
||||
exit_code = (DWORD) -1;
|
||||
} else if (!GetExitCodeProcess(handle->process_handle, &exit_code)) {
|
||||
/* Unable to to obtain the exit code. This should never happen. */
|
||||
exit_code = (DWORD) -1;
|
||||
}
|
||||
|
||||
/* Fire the exit callback. */
|
||||
if (handle->exit_cb) {
|
||||
loop->last_err = handle->spawn_error;
|
||||
handle->exit_cb(handle, exit_code, handle->exit_signal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Called on main thread after UnregisterWaitEx finishes. */
|
||||
void uv_process_proc_close(uv_loop_t* loop, uv_process_t* handle) {
|
||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||
}
|
||||
|
||||
|
||||
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
|
||||
uv__handle_start(handle);
|
||||
|
||||
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
|
||||
handle->close_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
UnregisterWaitEx(handle->wait_handle, handle->close_handle);
|
||||
handle->wait_handle = NULL;
|
||||
/* This blocks until either the wait was cancelled, or the callback has */
|
||||
/* completed. */
|
||||
BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE);
|
||||
if (!r) {
|
||||
/* This should never happen, and if it happens, we can't recover... */
|
||||
uv_fatal_error(GetLastError(), "UnregisterWaitEx");
|
||||
}
|
||||
|
||||
RegisterWaitForSingleObject(&handle->wait_handle, handle->close_handle,
|
||||
close_wait_callback, (void*)handle, INFINITE,
|
||||
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
|
||||
} else {
|
||||
handle->wait_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (!handle->exit_cb_pending) {
|
||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) {
|
||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||
uv__handle_stop(handle);
|
||||
assert(!handle->exit_cb_pending);
|
||||
assert(handle->flags & UV_HANDLE_CLOSING);
|
||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||
|
||||
/* Clean-up the process handle. */
|
||||
CloseHandle(handle->process_handle);
|
||||
uv__handle_stop(handle);
|
||||
|
||||
/* Clean up the child stdio ends that may have been left open. */
|
||||
if (handle->child_stdio_buffer != NULL) {
|
||||
uv__stdio_destroy(handle->child_stdio_buffer);
|
||||
}
|
||||
/* Clean-up the process handle. */
|
||||
CloseHandle(handle->process_handle);
|
||||
|
||||
uv__handle_close(handle);
|
||||
}
|
||||
uv__handle_close(handle);
|
||||
}
|
||||
|
||||
|
||||
int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
||||
uv_process_options_t options) {
|
||||
int i, size, err = 0, keep_child_stdio_open = 0;
|
||||
wchar_t* path = NULL;
|
||||
int i;
|
||||
uv_err_t err = uv_ok_;
|
||||
WCHAR* path = NULL;
|
||||
BOOL result;
|
||||
wchar_t* application_path = NULL, *application = NULL, *arguments = NULL,
|
||||
WCHAR* application_path = NULL, *application = NULL, *arguments = NULL,
|
||||
*env = NULL, *cwd = NULL;
|
||||
STARTUPINFOW startup;
|
||||
PROCESS_INFORMATION info;
|
||||
@@ -761,6 +751,12 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (options.file == NULL ||
|
||||
options.args == NULL) {
|
||||
uv__set_artificial_error(loop, UV_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(options.file != NULL);
|
||||
assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
|
||||
UV_PROCESS_DETACHED |
|
||||
@@ -768,57 +764,84 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
||||
UV_PROCESS_SETUID)));
|
||||
|
||||
uv_process_init(loop, process);
|
||||
|
||||
process->exit_cb = options.exit_cb;
|
||||
UTF8_TO_UTF16(options.file, application);
|
||||
arguments = options.args ? make_program_args(options.args,
|
||||
options.flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS) : NULL;
|
||||
env = options.env ? make_program_env(options.env) : NULL;
|
||||
|
||||
err = uv_utf8_to_utf16_alloc(options.file, &application);
|
||||
if (err.code != UV_OK)
|
||||
goto done;
|
||||
|
||||
err = make_program_args(options.args,
|
||||
options.flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
|
||||
&arguments);
|
||||
if (err.code != UV_OK)
|
||||
goto done;
|
||||
|
||||
if (options.cwd) {
|
||||
UTF8_TO_UTF16(options.cwd, cwd);
|
||||
} else {
|
||||
size = GetCurrentDirectoryW(0, NULL) * sizeof(wchar_t);
|
||||
if (size) {
|
||||
cwd = (wchar_t*)malloc(size);
|
||||
if (!cwd) {
|
||||
uv__set_artificial_error(loop, UV_ENOMEM);
|
||||
err = -1;
|
||||
goto done;
|
||||
}
|
||||
/* Explicit cwd */
|
||||
err = uv_utf8_to_utf16_alloc(options.cwd, &cwd);
|
||||
if (err.code != UV_OK)
|
||||
goto done;
|
||||
|
||||
GetCurrentDirectoryW(size, cwd);
|
||||
} else {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
err = -1;
|
||||
} else {
|
||||
/* Inherit cwd */
|
||||
DWORD cwd_len, r;
|
||||
|
||||
cwd_len = GetCurrentDirectoryW(0, NULL);
|
||||
if (!cwd_len) {
|
||||
err = uv__new_sys_error(GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR));
|
||||
if (cwd == NULL) {
|
||||
err = uv__new_artificial_error(UV_ENOMEM);
|
||||
goto done;
|
||||
}
|
||||
|
||||
r = GetCurrentDirectoryW(cwd_len, cwd);
|
||||
if (r == 0 || r >= cwd_len) {
|
||||
err = uv__new_sys_error(GetLastError());
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get PATH env. variable. */
|
||||
size = GetEnvironmentVariableW(L"PATH", NULL, 0) + 1;
|
||||
path = (wchar_t*)malloc(size * sizeof(wchar_t));
|
||||
if (!path) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
/* Get PATH environment variable. */
|
||||
{
|
||||
DWORD path_len, r;
|
||||
|
||||
path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
|
||||
if (path_len == 0) {
|
||||
err = uv__new_sys_error(GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
path = (WCHAR*) malloc(path_len * sizeof(WCHAR));
|
||||
if (path == NULL) {
|
||||
err = uv__new_artificial_error(UV_ENOMEM);
|
||||
goto done;
|
||||
}
|
||||
|
||||
r = GetEnvironmentVariableW(L"PATH", path, path_len);
|
||||
if (r == 0 || r >= path_len) {
|
||||
err = uv__new_sys_error(GetLastError());
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
GetEnvironmentVariableW(L"PATH", path, size * sizeof(wchar_t));
|
||||
path[size - 1] = L'\0';
|
||||
|
||||
application_path = search_path(application,
|
||||
cwd,
|
||||
path);
|
||||
|
||||
if (!application_path) {
|
||||
/* CreateProcess will fail, but this allows us to pass this error to */
|
||||
/* the user asynchronously. */
|
||||
application_path = application;
|
||||
if (application_path == NULL) {
|
||||
/* Not found. */
|
||||
err = uv__new_artificial_error(UV_ENOENT);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (uv__stdio_create(loop, &options, &process->child_stdio_buffer) < 0) {
|
||||
err = -1;
|
||||
goto done;
|
||||
}
|
||||
err = uv__stdio_create(loop, &options, &process->child_stdio_buffer);
|
||||
if (err.code != UV_OK)
|
||||
goto done;
|
||||
|
||||
startup.cb = sizeof(startup);
|
||||
startup.lpReserved = NULL;
|
||||
@@ -871,60 +894,37 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
||||
CloseHandle(info.hThread);
|
||||
|
||||
} else {
|
||||
/* CreateProcessW failed, but this failure should be delivered */
|
||||
/* 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();
|
||||
keep_child_stdio_open = 1;
|
||||
if (!QueueUserWorkItem(spawn_failure, process, WT_EXECUTEDEFAULT)) {
|
||||
uv_fatal_error(GetLastError(), "QueueUserWorkItem");
|
||||
}
|
||||
/* CreateProcessW failed. */
|
||||
err = uv__new_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
done:
|
||||
free(application);
|
||||
if (application_path != application) {
|
||||
free(application_path);
|
||||
}
|
||||
free(application_path);
|
||||
free(arguments);
|
||||
free(cwd);
|
||||
free(env);
|
||||
free(path);
|
||||
|
||||
/* Under normal circumstances we should close the stdio handles now - the */
|
||||
/* the child now has its own duplicates, or something went horribly wrong */
|
||||
/* The only exception is when CreateProcess has failed, then we actually */
|
||||
/* need to keep the stdio handles to report the error asynchronously. */
|
||||
if (process->child_stdio_buffer == NULL) {
|
||||
/* Something went wrong before child stdio was initialized. */
|
||||
} else if (!keep_child_stdio_open) {
|
||||
process->spawn_error = err;
|
||||
|
||||
if (process->child_stdio_buffer != NULL) {
|
||||
/* Clean up child stdio handles. */
|
||||
uv__stdio_destroy(process->child_stdio_buffer);
|
||||
process->child_stdio_buffer = NULL;
|
||||
} else {
|
||||
/* We're keeping the handles open, the thread pool is going to have */
|
||||
/* it's way with them. But at least make them non-inheritable. */
|
||||
uv__stdio_noinherit(process->child_stdio_buffer);
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
/* Spawn was succesful. The handle will be active until the exit */
|
||||
/* is made or the handle is closed, whichever happens first. */
|
||||
uv__handle_start(process);
|
||||
} else {
|
||||
/* Spawn was not successful. Clean up. */
|
||||
if (process->wait_handle != INVALID_HANDLE_VALUE) {
|
||||
UnregisterWait(process->wait_handle);
|
||||
process->wait_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
/* Make the handle active. It will remain active until the exit callback */
|
||||
/* is made or the handle is closed, whichever happens first. */
|
||||
uv__handle_start(process);
|
||||
|
||||
if (process->process_handle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(process->process_handle);
|
||||
process->process_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
/* If an error happened, queue the exit req. */
|
||||
if (err.code != UV_OK) {
|
||||
process->exit_cb_pending = 1;
|
||||
uv_insert_pending_req(loop, (uv_req_t*) &process->exit_req);
|
||||
}
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
9
deps/uv/src/win/req-inl.h
vendored
9
deps/uv/src/win/req-inl.h
vendored
@@ -80,7 +80,6 @@
|
||||
|
||||
|
||||
INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
|
||||
loop->counters.req_init++;
|
||||
req->type = UV_UNKNOWN_REQ;
|
||||
SET_REQ_SUCCESS(req);
|
||||
}
|
||||
@@ -188,6 +187,10 @@ INLINE static void uv_process_reqs(uv_loop_t* loop) {
|
||||
uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_SIGNAL_REQ:
|
||||
uv_process_signal_req(loop, (uv_signal_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_POLL_REQ:
|
||||
uv_process_poll_req(loop, (uv_poll_t*) req->data, req);
|
||||
break;
|
||||
@@ -200,10 +203,6 @@ INLINE static void uv_process_reqs(uv_loop_t* loop) {
|
||||
uv_process_proc_exit(loop, (uv_process_t*) req->data);
|
||||
break;
|
||||
|
||||
case UV_PROCESS_CLOSE:
|
||||
uv_process_proc_close(loop, (uv_process_t*) req->data);
|
||||
break;
|
||||
|
||||
case UV_FS:
|
||||
uv_process_fs_req(loop, (uv_fs_t*) req);
|
||||
break;
|
||||
|
||||
349
deps/uv/src/win/signal.c
vendored
Normal file
349
deps/uv/src/win/signal.c
vendored
Normal file
@@ -0,0 +1,349 @@
|
||||
/* 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 <assert.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
#include "handle-inl.h"
|
||||
#include "req-inl.h"
|
||||
|
||||
|
||||
RB_HEAD(uv_signal_tree_s, uv_signal_s);
|
||||
|
||||
static struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree);
|
||||
static ssize_t volatile uv__signal_control_handler_refs = 0;
|
||||
static CRITICAL_SECTION uv__signal_lock;
|
||||
|
||||
|
||||
void uv_signals_init() {
|
||||
InitializeCriticalSection(&uv__signal_lock);
|
||||
}
|
||||
|
||||
|
||||
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
|
||||
/* Compare signums first so all watchers with the same signnum end up */
|
||||
/* adjacent. */
|
||||
if (w1->signum < w2->signum) return -1;
|
||||
if (w1->signum > w2->signum) return 1;
|
||||
|
||||
/* Sort by loop pointer, so we can easily look up the first item after */
|
||||
/* { .signum = x, .loop = NULL } */
|
||||
if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1;
|
||||
if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1;
|
||||
|
||||
if ((uintptr_t) w1 < (uintptr_t) w2) return -1;
|
||||
if ((uintptr_t) w1 > (uintptr_t) w2) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare);
|
||||
|
||||
|
||||
/*
|
||||
* Dispatches signal {signum} to all active uv_signal_t watchers in all loops.
|
||||
* Returns 1 if the signal was dispatched to any watcher, or 0 if there were
|
||||
* no active signal watchers observing this signal.
|
||||
*/
|
||||
int uv__signal_dispatch(int signum) {
|
||||
uv_signal_t lookup;
|
||||
uv_signal_t* handle;
|
||||
int dispatched = 0;
|
||||
|
||||
EnterCriticalSection(&uv__signal_lock);
|
||||
|
||||
lookup.signum = signum;
|
||||
lookup.loop = NULL;
|
||||
|
||||
for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup);
|
||||
handle != NULL && handle->signum == signum;
|
||||
handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) {
|
||||
unsigned long previous = InterlockedExchange(&handle->pending_signum, signum);
|
||||
|
||||
if (!previous) {
|
||||
POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req);
|
||||
}
|
||||
|
||||
dispatched = 1;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&uv__signal_lock);
|
||||
|
||||
return dispatched;
|
||||
}
|
||||
|
||||
|
||||
static BOOL WINAPI uv__signal_control_handler(DWORD type) {
|
||||
switch (type) {
|
||||
case CTRL_C_EVENT:
|
||||
return uv__signal_dispatch(SIGINT);
|
||||
|
||||
case CTRL_BREAK_EVENT:
|
||||
return uv__signal_dispatch(SIGBREAK);
|
||||
|
||||
case CTRL_CLOSE_EVENT:
|
||||
if (uv__signal_dispatch(SIGHUP)) {
|
||||
/* Windows will terminate the process after the control handler */
|
||||
/* returns. After that it will just terminate our process. Therefore */
|
||||
/* block the signal handler so the main loop has some time to pick */
|
||||
/* up the signal and do something for a few seconds. */
|
||||
Sleep(INFINITE);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case CTRL_LOGOFF_EVENT:
|
||||
case CTRL_SHUTDOWN_EVENT:
|
||||
/* These signals are only sent to services. Services have their own */
|
||||
/* notification mechanism, so there's no point in handling these. */
|
||||
|
||||
default:
|
||||
/* We don't handle these. */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uv_err_t uv__signal_register_control_handler() {
|
||||
/* When this function is called, the uv__signal_lock must be held. */
|
||||
|
||||
/* If the console control handler has already been hooked, just add a */
|
||||
/* reference. */
|
||||
if (uv__signal_control_handler_refs > 0)
|
||||
return uv_ok_;
|
||||
|
||||
if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE))
|
||||
return uv__new_sys_error(GetLastError());
|
||||
|
||||
uv__signal_control_handler_refs++;
|
||||
|
||||
return uv_ok_;
|
||||
}
|
||||
|
||||
|
||||
static void uv__signal_unregister_control_handler() {
|
||||
/* When this function is called, the uv__signal_lock must be held. */
|
||||
BOOL r;
|
||||
|
||||
/* Don't unregister if the number of console control handlers exceeds one. */
|
||||
/* Just remove a reference in that case. */
|
||||
if (uv__signal_control_handler_refs > 1) {
|
||||
uv__signal_control_handler_refs--;
|
||||
return;
|
||||
}
|
||||
|
||||
assert(uv__signal_control_handler_refs == 1);
|
||||
|
||||
r = SetConsoleCtrlHandler(uv__signal_control_handler, FALSE);
|
||||
/* This should never fail; if it does it is probably a bug in libuv. */
|
||||
assert(r);
|
||||
|
||||
uv__signal_control_handler_refs--;
|
||||
}
|
||||
|
||||
|
||||
static uv_err_t uv__signal_register(int signum) {
|
||||
switch (signum) {
|
||||
case SIGINT:
|
||||
case SIGBREAK:
|
||||
case SIGHUP:
|
||||
return uv__signal_register_control_handler();
|
||||
|
||||
case SIGILL:
|
||||
case SIGABRT_COMPAT:
|
||||
case SIGFPE:
|
||||
case SIGSEGV:
|
||||
case SIGTERM:
|
||||
case SIGABRT:
|
||||
/* Signal is never raised. */
|
||||
return uv_ok_;
|
||||
|
||||
default:
|
||||
/* Invalid signal. */
|
||||
return uv__new_artificial_error(UV_EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void uv__signal_unregister(int signum) {
|
||||
switch (signum) {
|
||||
case SIGINT:
|
||||
case SIGBREAK:
|
||||
case SIGHUP:
|
||||
uv__signal_unregister_control_handler();
|
||||
return;
|
||||
|
||||
case SIGILL:
|
||||
case SIGABRT_COMPAT:
|
||||
case SIGFPE:
|
||||
case SIGSEGV:
|
||||
case SIGTERM:
|
||||
case SIGABRT:
|
||||
/* Nothing is registered for this signal. */
|
||||
return;
|
||||
|
||||
default:
|
||||
/* Libuv bug. */
|
||||
assert(0 && "Invalid signum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
|
||||
uv_req_t* req;
|
||||
|
||||
uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
|
||||
handle->pending_signum = 0;
|
||||
handle->signum = 0;
|
||||
handle->signal_cb = NULL;
|
||||
|
||||
req = &handle->signal_req;
|
||||
uv_req_init(loop, req);
|
||||
req->type = UV_SIGNAL_REQ;
|
||||
req->data = handle;
|
||||
|
||||
uv__handle_start(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_signal_stop(uv_signal_t* handle) {
|
||||
uv_signal_t* removed_handle;
|
||||
|
||||
/* If the watcher wasn't started, this is a no-op. */
|
||||
if (handle->signum == 0)
|
||||
return 0;
|
||||
|
||||
EnterCriticalSection(&uv__signal_lock);
|
||||
|
||||
uv__signal_unregister(handle->signum);
|
||||
|
||||
removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle);
|
||||
assert(removed_handle == handle);
|
||||
|
||||
LeaveCriticalSection(&uv__signal_lock);
|
||||
|
||||
handle->signum = 0;
|
||||
uv__handle_stop(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
|
||||
uv_err_t err;
|
||||
|
||||
/* If the user supplies signum == 0, then return an error already. If the */
|
||||
/* signum is otherwise invalid then uv__signal_register will find out */
|
||||
/* eventually. */
|
||||
if (signum == 0) {
|
||||
uv__set_artificial_error(handle->loop, UV_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Short circuit: if the signal watcher is already watching {signum} don't */
|
||||
/* go through the process of deregistering and registering the handler. */
|
||||
/* Additionally, this avoids pending signals getting lost in the (small) */
|
||||
/* time frame that handle->signum == 0. */
|
||||
if (signum == handle->signum) {
|
||||
handle->signal_cb = signal_cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the signal handler was already active, stop it first. */
|
||||
if (handle->signum != 0) {
|
||||
int r = uv_signal_stop(handle);
|
||||
/* uv_signal_stop is infallible. */
|
||||
assert(r == 0);
|
||||
}
|
||||
|
||||
EnterCriticalSection(&uv__signal_lock);
|
||||
|
||||
err = uv__signal_register(signum);
|
||||
if (err.code != UV_OK) {
|
||||
/* Uh-oh, didn't work. */
|
||||
handle->loop->last_err = err;
|
||||
LeaveCriticalSection(&uv__signal_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle->signum = signum;
|
||||
RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle);
|
||||
|
||||
LeaveCriticalSection(&uv__signal_lock);
|
||||
|
||||
handle->signal_cb = signal_cb;
|
||||
uv__handle_start(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
|
||||
uv_req_t* req) {
|
||||
unsigned long dispatched_signum;
|
||||
|
||||
assert(handle->type == UV_SIGNAL);
|
||||
assert(req->type == UV_SIGNAL_REQ);
|
||||
|
||||
dispatched_signum = InterlockedExchange(&handle->pending_signum, 0);
|
||||
assert(dispatched_signum != 0);
|
||||
|
||||
/* Check if the pending signal equals the signum that we are watching for. */
|
||||
/* These can get out of sync when the handler is stopped and restarted */
|
||||
/* while the signal_req is pending. */
|
||||
if (dispatched_signum == handle->signum)
|
||||
handle->signal_cb(handle, dispatched_signum);
|
||||
|
||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||
/* When it is closing, it must be stopped at this point. */
|
||||
assert(handle->signum == 0);
|
||||
uv_want_endgame(loop, (uv_handle_t*) handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) {
|
||||
uv_signal_stop(handle);
|
||||
|
||||
if (handle->pending_signum == 0) {
|
||||
uv__handle_start(handle);
|
||||
uv_want_endgame(loop, (uv_handle_t*) handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) {
|
||||
assert(handle->flags & UV_HANDLE_CLOSING);
|
||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||
|
||||
assert(handle->signum == 0);
|
||||
assert(handle->pending_signum == 0);
|
||||
|
||||
handle->flags |= UV_HANDLE_CLOSED;
|
||||
|
||||
uv__handle_stop(handle);
|
||||
uv__handle_close(handle);
|
||||
}
|
||||
2
deps/uv/src/win/stream-inl.h
vendored
2
deps/uv/src/win/stream-inl.h
vendored
@@ -36,8 +36,6 @@ INLINE static void uv_stream_init(uv_loop_t* loop,
|
||||
uv__handle_init(loop, (uv_handle_t*) handle, type);
|
||||
handle->write_queue_size = 0;
|
||||
handle->activecnt = 0;
|
||||
|
||||
loop->counters.stream_init++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
2
deps/uv/src/win/tcp.c
vendored
2
deps/uv/src/win/tcp.c
vendored
@@ -149,8 +149,6 @@ int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
|
||||
handle->func_connectex = NULL;
|
||||
handle->processed_accepts = 0;
|
||||
|
||||
loop->counters.tcp_init++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
2
deps/uv/src/win/timer.c
vendored
2
deps/uv/src/win/timer.c
vendored
@@ -71,8 +71,6 @@ int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
|
||||
handle->timer_cb = NULL;
|
||||
handle->repeat = 0;
|
||||
|
||||
loop->counters.timer_init++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
118
deps/uv/src/win/tty.c
vendored
118
deps/uv/src/win/tty.c
vendored
@@ -89,54 +89,70 @@ void uv_console_init() {
|
||||
|
||||
|
||||
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
|
||||
HANDLE win_handle;
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
DWORD original_console_mode = 0;
|
||||
CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
|
||||
|
||||
loop->counters.tty_init++;
|
||||
|
||||
win_handle = (HANDLE) _get_osfhandle(fd);
|
||||
if (win_handle == INVALID_HANDLE_VALUE) {
|
||||
uv__set_sys_error(loop, ERROR_INVALID_HANDLE);
|
||||
handle = (HANDLE) _get_osfhandle(fd);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
uv__set_artificial_error(loop, UV_EBADF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!GetConsoleMode(win_handle, &tty->original_console_mode)) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
if (readable) {
|
||||
/* Try to obtain the original console mode fromt he input handle. */
|
||||
if (!GetConsoleMode(handle, &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)) {
|
||||
} else {
|
||||
/* Obtain the screen buffer info with the output handle. */
|
||||
if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) {
|
||||
uv__set_sys_error(loop, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update the virtual window. We must hold the tty_output_lock because the */
|
||||
/* virtual window state is shared between all uv_tty handles. */
|
||||
EnterCriticalSection(&uv_tty_output_lock);
|
||||
uv_tty_update_virtual_window(&info);
|
||||
uv_tty_update_virtual_window(&screen_buffer_info);
|
||||
LeaveCriticalSection(&uv_tty_output_lock);
|
||||
}
|
||||
|
||||
|
||||
uv_stream_init(loop, (uv_stream_t*) tty, UV_TTY);
|
||||
uv_connection_init((uv_stream_t*) tty);
|
||||
|
||||
tty->handle = win_handle;
|
||||
tty->read_line_handle = NULL;
|
||||
tty->read_line_buffer = uv_null_buf_;
|
||||
tty->read_raw_wait = NULL;
|
||||
tty->handle = handle;
|
||||
tty->reqs_pending = 0;
|
||||
tty->flags |= UV_HANDLE_BOUND;
|
||||
|
||||
/* Init keycode-to-vt100 mapper state. */
|
||||
tty->last_key_len = 0;
|
||||
tty->last_key_offset = 0;
|
||||
tty->last_utf16_high_surrogate = 0;
|
||||
memset(&tty->last_input_record, 0, sizeof tty->last_input_record);
|
||||
if (readable) {
|
||||
/* Initialize TTY input specific fields. */
|
||||
tty->original_console_mode = original_console_mode;
|
||||
tty->flags |= UV_HANDLE_TTY_READABLE;
|
||||
tty->read_line_handle = NULL;
|
||||
tty->read_line_buffer = uv_null_buf_;
|
||||
tty->read_raw_wait = NULL;
|
||||
|
||||
/* Init utf8-to-utf16 conversion state. */
|
||||
tty->utf8_bytes_left = 0;
|
||||
tty->utf8_codepoint = 0;
|
||||
/* Init keycode-to-vt100 mapper state. */
|
||||
tty->last_key_len = 0;
|
||||
tty->last_key_offset = 0;
|
||||
tty->last_utf16_high_surrogate = 0;
|
||||
memset(&tty->last_input_record, 0, sizeof tty->last_input_record);
|
||||
} else {
|
||||
/* TTY output specific fields. */
|
||||
/* Init utf8-to-utf16 conversion state. */
|
||||
tty->utf8_bytes_left = 0;
|
||||
tty->utf8_codepoint = 0;
|
||||
|
||||
/* Initialize eol conversion state */
|
||||
tty->previous_eol = 0;
|
||||
/* Initialize eol conversion state */
|
||||
tty->previous_eol = 0;
|
||||
|
||||
/* Init ANSI parser state. */
|
||||
tty->ansi_parser_state = ANSI_NORMAL;
|
||||
/* Init ANSI parser state. */
|
||||
tty->ansi_parser_state = ANSI_NORMAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -148,6 +164,11 @@ int uv_tty_set_mode(uv_tty_t* tty, int mode) {
|
||||
uv_alloc_cb alloc_cb;
|
||||
uv_read_cb read_cb;
|
||||
|
||||
if (!(tty->flags & UV_HANDLE_TTY_READABLE)) {
|
||||
uv__set_artificial_error(tty->loop, UV_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -444,6 +465,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
off_t buf_used;
|
||||
|
||||
assert(handle->type == UV_TTY);
|
||||
assert(handle->flags & UV_HANDLE_TTY_READABLE);
|
||||
handle->flags &= ~UV_HANDLE_READ_PENDING;
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_READING) ||
|
||||
@@ -683,6 +705,7 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
uv_buf_t buf;
|
||||
|
||||
assert(handle->type == UV_TTY);
|
||||
assert(handle->flags & UV_HANDLE_TTY_READABLE);
|
||||
|
||||
buf = handle->read_line_buffer;
|
||||
|
||||
@@ -726,6 +749,8 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
|
||||
void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
uv_req_t* req) {
|
||||
assert(handle->type == UV_TTY);
|
||||
assert(handle->flags & UV_HANDLE_TTY_READABLE);
|
||||
|
||||
/* If the read_line_buffer member is zero, it must have been an raw read. */
|
||||
/* Otherwise it was a line-buffered read. */
|
||||
@@ -742,6 +767,11 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_TTY_READABLE)) {
|
||||
uv__set_artificial_error(handle->loop, UV_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle->flags |= UV_HANDLE_READING;
|
||||
INCREASE_ACTIVE_COUNT(loop, handle);
|
||||
handle->read_cb = read_cb;
|
||||
@@ -769,6 +799,10 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
|
||||
|
||||
int uv_tty_read_stop(uv_tty_t* handle) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
if (!(handle->flags & UV_HANDLE_TTY_READABLE)) {
|
||||
uv__set_artificial_error(handle->loop, UV_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (handle->flags & UV_HANDLE_READING) {
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
@@ -1678,6 +1712,11 @@ int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
|
||||
uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
|
||||
DWORD error;
|
||||
|
||||
if (handle->flags & UV_HANDLE_TTY_READABLE) {
|
||||
uv__set_artificial_error(handle->loop, UV_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((handle->flags & UV_HANDLE_SHUTTING) ||
|
||||
(handle->flags & UV_HANDLE_CLOSING)) {
|
||||
uv__set_sys_error(loop, WSAESHUTDOWN);
|
||||
@@ -1729,11 +1768,16 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||
|
||||
|
||||
void uv_tty_close(uv_tty_t* handle) {
|
||||
handle->flags |= UV_HANDLE_SHUTTING;
|
||||
|
||||
uv_tty_read_stop(handle);
|
||||
CloseHandle(handle->handle);
|
||||
|
||||
if (handle->flags & UV_HANDLE_TTY_READABLE) {
|
||||
/* Readable TTY handle */
|
||||
uv_tty_read_stop(handle);
|
||||
} else {
|
||||
/* Writable TTY handle */
|
||||
handle->flags |= UV_HANDLE_SHUTTING;
|
||||
}
|
||||
|
||||
uv__handle_start(handle);
|
||||
|
||||
if (handle->reqs_pending == 0) {
|
||||
@@ -1743,7 +1787,7 @@ void uv_tty_close(uv_tty_t* handle) {
|
||||
|
||||
|
||||
void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
|
||||
if ((handle->flags && UV_HANDLE_CONNECTION) &&
|
||||
if (!(handle->flags && UV_HANDLE_TTY_READABLE) &&
|
||||
handle->shutdown_req != NULL &&
|
||||
handle->write_reqs_pending == 0) {
|
||||
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
|
||||
@@ -1768,11 +1812,13 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
|
||||
handle->reqs_pending == 0) {
|
||||
/* The console handle duplicate used for line reading should be destroyed */
|
||||
/* by uv_tty_read_stop. */
|
||||
assert(handle->read_line_handle == NULL);
|
||||
assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
|
||||
handle->read_line_handle == NULL);
|
||||
|
||||
/* The wait handle used for raw reading should be unregistered when the */
|
||||
/* wait callback runs. */
|
||||
assert(handle->read_raw_wait == NULL);
|
||||
assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
|
||||
handle->read_raw_wait == NULL);
|
||||
|
||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||
uv__handle_stop(handle);
|
||||
|
||||
2
deps/uv/src/win/udp.c
vendored
2
deps/uv/src/win/udp.c
vendored
@@ -135,8 +135,6 @@ int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
|
||||
handle->recv_req.type = UV_UDP_RECV;
|
||||
handle->recv_req.data = handle;
|
||||
|
||||
loop->counters.udp_init++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
12
deps/uv/src/win/util.c
vendored
12
deps/uv/src/win/util.c
vendored
@@ -74,7 +74,7 @@ void uv__util_init() {
|
||||
}
|
||||
|
||||
|
||||
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
|
||||
int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
|
||||
char* utf8Buffer, size_t utf8Size) {
|
||||
return WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
@@ -87,7 +87,7 @@ int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
|
||||
}
|
||||
|
||||
|
||||
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
|
||||
int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
|
||||
size_t utf16Size) {
|
||||
return MultiByteToWideChar(CP_UTF8,
|
||||
0,
|
||||
@@ -113,7 +113,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
|
||||
utf16_buffer_len = (int) *size_ptr;
|
||||
}
|
||||
|
||||
utf16_buffer = (wchar_t*) malloc(sizeof(WCHAR) * utf16_buffer_len);
|
||||
utf16_buffer = (WCHAR*) malloc(sizeof(WCHAR) * utf16_buffer_len);
|
||||
if (!utf16_buffer) {
|
||||
return -1;
|
||||
}
|
||||
@@ -340,7 +340,7 @@ char** uv_setup_args(int argc, char** argv) {
|
||||
uv_err_t uv_set_process_title(const char* title) {
|
||||
uv_err_t err;
|
||||
int length;
|
||||
wchar_t* title_w = NULL;
|
||||
WCHAR* title_w = NULL;
|
||||
|
||||
uv__once_init();
|
||||
|
||||
@@ -352,7 +352,7 @@ uv_err_t uv_set_process_title(const char* title) {
|
||||
}
|
||||
|
||||
/* Convert to wide-char string */
|
||||
title_w = (wchar_t*)malloc(sizeof(wchar_t) * length);
|
||||
title_w = (WCHAR*)malloc(sizeof(WCHAR) * length);
|
||||
if (!title_w) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
@@ -387,7 +387,7 @@ done:
|
||||
|
||||
|
||||
static int uv__get_process_title() {
|
||||
wchar_t title_w[MAX_TITLE_LENGTH];
|
||||
WCHAR title_w[MAX_TITLE_LENGTH];
|
||||
int length;
|
||||
|
||||
if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
|
||||
|
||||
2
deps/uv/test/benchmark-fs-stat.c
vendored
2
deps/uv/test/benchmark-fs-stat.c
vendored
@@ -26,7 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NUM_SYNC_REQS (10 * 1e5)
|
||||
#define NUM_ASYNC_REQS (1 * 1e5)
|
||||
#define NUM_ASYNC_REQS (1 * (int) 1e5)
|
||||
#define MAX_CONCURRENT_REQS 32
|
||||
|
||||
#define sync_stat(req, path) \
|
||||
|
||||
1
deps/uv/test/benchmark-sizes.c
vendored
1
deps/uv/test/benchmark-sizes.c
vendored
@@ -36,6 +36,7 @@ BENCHMARK_IMPL(sizes) {
|
||||
LOGF("uv_idle_t: %u bytes\n", (unsigned int) sizeof(uv_idle_t));
|
||||
LOGF("uv_async_t: %u bytes\n", (unsigned int) sizeof(uv_async_t));
|
||||
LOGF("uv_timer_t: %u bytes\n", (unsigned int) sizeof(uv_timer_t));
|
||||
LOGF("uv_fs_poll_t: %u bytes\n", (unsigned int) sizeof(uv_fs_poll_t));
|
||||
LOGF("uv_fs_event_t: %u bytes\n", (unsigned int) sizeof(uv_fs_event_t));
|
||||
LOGF("uv_process_t: %u bytes\n", (unsigned int) sizeof(uv_process_t));
|
||||
LOGF("uv_poll_t: %u bytes\n", (unsigned int) sizeof(uv_poll_t));
|
||||
|
||||
8
deps/uv/test/runner-win.c
vendored
8
deps/uv/test/runner-win.c
vendored
@@ -103,8 +103,8 @@ int process_start(char *name, char *part, process_info_t *p) {
|
||||
goto error;
|
||||
|
||||
if (part) {
|
||||
if (_snwprintf((wchar_t*)args,
|
||||
sizeof(args) / sizeof(wchar_t),
|
||||
if (_snwprintf((WCHAR*)args,
|
||||
sizeof(args) / sizeof(WCHAR),
|
||||
L"\"%s\" %S %S",
|
||||
image,
|
||||
name,
|
||||
@@ -112,8 +112,8 @@ int process_start(char *name, char *part, process_info_t *p) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if (_snwprintf((wchar_t*)args,
|
||||
sizeof(args) / sizeof(wchar_t),
|
||||
if (_snwprintf((WCHAR*)args,
|
||||
sizeof(args) / sizeof(WCHAR),
|
||||
L"\"%s\" %S",
|
||||
image,
|
||||
name) < 0) {
|
||||
|
||||
2
deps/uv/test/runner.c
vendored
2
deps/uv/test/runner.c
vendored
@@ -42,7 +42,7 @@ const char* fmt(double d) {
|
||||
char* p;
|
||||
|
||||
p = (char *) calloc(1, 32) + 31; /* leaks memory */
|
||||
v = d;
|
||||
v = (uint64_t) d;
|
||||
|
||||
#if 0 /* works but we don't care about fractional precision */
|
||||
if (d - v >= 0.01) {
|
||||
|
||||
215
deps/uv/test/test-counters-init.c
vendored
215
deps/uv/test/test-counters-init.c
vendored
@@ -1,215 +0,0 @@
|
||||
/* 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.
|
||||
*/
|
||||
#define UNIX (defined(__unix__) || defined(__POSIX__) || defined(__APPLE__))
|
||||
#include "task.h"
|
||||
#include "uv.h"
|
||||
#include <fcntl.h>
|
||||
|
||||
#if UNIX
|
||||
#include <unistd.h> /* unlink, rmdir, etc. */
|
||||
#else
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
# define unlink _unlink
|
||||
# define rmdir _rmdir
|
||||
# define stat _stati64
|
||||
# define open _open
|
||||
# define write _write
|
||||
# define lseek _lseek
|
||||
# define close _close
|
||||
#endif
|
||||
|
||||
static char exepath[1024];
|
||||
static size_t exepath_size = 1024;
|
||||
static char* args[3];
|
||||
static uv_fs_t open_req;
|
||||
static uv_tcp_t tcp;
|
||||
static uv_udp_t udp;
|
||||
static uv_pipe_t uvpipe;
|
||||
static uv_tty_t tty;
|
||||
static uv_prepare_t prepare;
|
||||
static uv_check_t check;
|
||||
static uv_idle_t idle;
|
||||
static uv_async_t async;
|
||||
static uv_timer_t timer;
|
||||
static uv_fs_event_t fs_event;
|
||||
static uv_process_t process;
|
||||
static uv_process_options_t options;
|
||||
static uv_fs_t fs_req;
|
||||
|
||||
static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {
|
||||
ASSERT(exit_status == 1);
|
||||
ASSERT(term_signal == 0);
|
||||
uv_close((uv_handle_t*)process, NULL);
|
||||
}
|
||||
|
||||
static void init_process_options(char* test, uv_exit_cb exit_cb) {
|
||||
int r = uv_exepath(exepath, &exepath_size);
|
||||
ASSERT(r == 0);
|
||||
exepath[exepath_size] = '\0';
|
||||
args[0] = exepath;
|
||||
args[1] = test;
|
||||
args[2] = NULL;
|
||||
options.file = exepath;
|
||||
options.args = args;
|
||||
options.exit_cb = exit_cb;
|
||||
}
|
||||
|
||||
static void create_dir(uv_loop_t* loop, const char* name) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
r = uv_fs_rmdir(loop, &req, name, NULL);
|
||||
r = uv_fs_mkdir(loop, &req, name, 0755, NULL);
|
||||
ASSERT(r == 0 || uv_last_error(loop).code == UV_EEXIST);
|
||||
uv_fs_req_cleanup(&req);
|
||||
}
|
||||
|
||||
static void create_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &open_req);
|
||||
ASSERT(req->fs_type == UV_FS_OPEN);
|
||||
ASSERT(req->result != -1);
|
||||
uv_fs_req_cleanup(req);
|
||||
unlink("test_file");
|
||||
}
|
||||
|
||||
TEST_IMPL(counters_init) {
|
||||
int r;
|
||||
uint64_t eio_init_prev;
|
||||
uint64_t req_init_prev;
|
||||
uint64_t handle_init_prev;
|
||||
uint64_t stream_init_prev;
|
||||
uint64_t tcp_init_prev;
|
||||
uint64_t udp_init_prev;
|
||||
uint64_t pipe_init_prev;
|
||||
uint64_t tty_init_prev;
|
||||
uint64_t prepare_init_prev;
|
||||
uint64_t check_init_prev;
|
||||
uint64_t idle_init_prev;
|
||||
uint64_t async_init_prev;
|
||||
uint64_t timer_init_prev;
|
||||
uint64_t process_init_prev;
|
||||
uint64_t fs_event_init_prev;
|
||||
|
||||
/* req_init and eio_init test by uv_fs_open() */
|
||||
unlink("test_file");
|
||||
req_init_prev = uv_default_loop()->counters.req_init;
|
||||
eio_init_prev = uv_default_loop()->counters.eio_init;
|
||||
r = uv_fs_open(uv_default_loop(), &open_req, "test_file", O_WRONLY | O_CREAT,
|
||||
S_IREAD | S_IWRITE, create_cb);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(open_req.result == 0);
|
||||
ASSERT(uv_default_loop()->counters.req_init == ++req_init_prev);
|
||||
#ifndef _WIN32
|
||||
ASSERT(uv_default_loop()->counters.eio_init == ++eio_init_prev);
|
||||
#endif
|
||||
|
||||
/* tcp_init, stream_init and handle_init test by uv_tcp_init() */
|
||||
tcp_init_prev = uv_default_loop()->counters.tcp_init;
|
||||
stream_init_prev = uv_default_loop()->counters.stream_init;
|
||||
handle_init_prev = uv_default_loop()->counters.handle_init;
|
||||
r = uv_tcp_init(uv_default_loop(), &tcp);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.tcp_init == ++tcp_init_prev);
|
||||
ASSERT(uv_default_loop()->counters.stream_init == ++stream_init_prev);
|
||||
ASSERT(uv_default_loop()->counters.handle_init == ++handle_init_prev);
|
||||
uv_close((uv_handle_t*)&tcp, NULL);
|
||||
|
||||
/* udp_init test by uv_udp_init() */
|
||||
udp_init_prev = uv_default_loop()->counters.udp_init;
|
||||
r = uv_udp_init(uv_default_loop(), &udp);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.udp_init == ++udp_init_prev);
|
||||
uv_close((uv_handle_t*)&udp, NULL);
|
||||
|
||||
/* pipe_init uv_pipe_init() */
|
||||
pipe_init_prev = uv_default_loop()->counters.pipe_init;
|
||||
uv_pipe_init(uv_default_loop(), &uvpipe, 0);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.pipe_init == ++pipe_init_prev);
|
||||
uv_close((uv_handle_t*)&uvpipe, NULL);
|
||||
|
||||
/* tty_init test by uv_tty_init()*/
|
||||
tty_init_prev = uv_default_loop()->counters.tty_init;
|
||||
r = uv_tty_init(uv_default_loop(), &tty, 1, 0);
|
||||
/* uv_tty_init() always returns -1 in run_test in Windows
|
||||
so that we avoid to check return value.
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
ASSERT(r == 0);
|
||||
uv_close((uv_handle_t*)&tty, NULL);
|
||||
#endif
|
||||
ASSERT(uv_default_loop()->counters.tty_init == ++tty_init_prev);
|
||||
|
||||
/* prepare_init test by uv_prepare_init() */
|
||||
prepare_init_prev = uv_default_loop()->counters.prepare_init;
|
||||
r = uv_prepare_init(uv_default_loop(), &prepare);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.prepare_init == ++prepare_init_prev);
|
||||
uv_close((uv_handle_t*)&prepare, NULL);
|
||||
|
||||
/* check_init test by uv_check_init() */
|
||||
check_init_prev = uv_default_loop()->counters.check_init;
|
||||
r = uv_check_init(uv_default_loop(), &check);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.check_init == ++check_init_prev);
|
||||
uv_close((uv_handle_t*)&check, NULL);
|
||||
|
||||
/* idle_init test by uv_idle_init() */
|
||||
idle_init_prev = uv_default_loop()->counters.idle_init;
|
||||
r = uv_idle_init(uv_default_loop(), &idle);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.idle_init == ++idle_init_prev);
|
||||
uv_close((uv_handle_t*)&idle, NULL);
|
||||
|
||||
/* async_init test by uv_async_init() */
|
||||
async_init_prev = uv_default_loop()->counters.async_init;
|
||||
r = uv_async_init(uv_default_loop(), &async, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.async_init == ++async_init_prev);
|
||||
uv_close((uv_handle_t*)&async, NULL);
|
||||
|
||||
/* timer_init test by uv_timer_init() */
|
||||
timer_init_prev = uv_default_loop()->counters.timer_init;
|
||||
r = uv_timer_init(uv_default_loop(), &timer);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.timer_init == ++timer_init_prev);
|
||||
uv_close((uv_handle_t*)&timer, NULL);
|
||||
|
||||
/* process_init test by uv_spawn() */
|
||||
process_init_prev = uv_default_loop()->counters.process_init;
|
||||
init_process_options("spawn_helper1", exit_cb);
|
||||
r = uv_spawn(uv_default_loop(), &process, options);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.process_init == ++process_init_prev);
|
||||
r = uv_run(uv_default_loop());
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* fs_event_init test by uv_fs_event_init() */
|
||||
create_dir(uv_default_loop(), "watch_dir");
|
||||
fs_event_init_prev = uv_default_loop()->counters.fs_event_init;
|
||||
r = uv_fs_event_init(uv_default_loop(), &fs_event, "watch_dir", NULL, 0);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.fs_event_init == ++fs_event_init_prev);
|
||||
uv_fs_rmdir(uv_default_loop(), &fs_req, "watch_dir", NULL);
|
||||
uv_fs_req_cleanup(&fs_req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
deps/uv/test/test-delayed-accept.c
vendored
9
deps/uv/test/test-delayed-accept.c
vendored
@@ -50,7 +50,6 @@ static void close_cb(uv_handle_t* handle) {
|
||||
static void do_accept(uv_timer_t* timer_handle, int status) {
|
||||
uv_tcp_t* server;
|
||||
uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle);
|
||||
uint64_t tcpcnt;
|
||||
int r;
|
||||
|
||||
ASSERT(timer_handle != NULL);
|
||||
@@ -60,15 +59,10 @@ static void do_accept(uv_timer_t* timer_handle, int status) {
|
||||
r = uv_tcp_init(uv_default_loop(), accepted_handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* Test to that uv_default_loop()->counters.tcp_init does not increase across the uv_accept. */
|
||||
tcpcnt = uv_default_loop()->counters.tcp_init;
|
||||
|
||||
server = (uv_tcp_t*)timer_handle->data;
|
||||
r = uv_accept((uv_stream_t*)server, (uv_stream_t*)accepted_handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(uv_default_loop()->counters.tcp_init == tcpcnt);
|
||||
|
||||
do_accept_called++;
|
||||
|
||||
/* Immediately close the accepted handle. */
|
||||
@@ -115,9 +109,6 @@ static void start_server() {
|
||||
|
||||
r = uv_tcp_init(uv_default_loop(), server);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_default_loop()->counters.tcp_init == 1);
|
||||
ASSERT(uv_default_loop()->counters.handle_init == 1);
|
||||
|
||||
r = uv_tcp_bind(server, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
|
||||
10
deps/uv/test/test-list.h
vendored
10
deps/uv/test/test-list.h
vendored
@@ -123,6 +123,7 @@ TEST_DECLARE (getsockname_tcp)
|
||||
TEST_DECLARE (getsockname_udp)
|
||||
TEST_DECLARE (fail_always)
|
||||
TEST_DECLARE (pass_always)
|
||||
TEST_DECLARE (spawn_fails)
|
||||
TEST_DECLARE (spawn_exit_code)
|
||||
TEST_DECLARE (spawn_stdout)
|
||||
TEST_DECLARE (spawn_stdin)
|
||||
@@ -174,11 +175,12 @@ TEST_DECLARE (thread_rwlock)
|
||||
TEST_DECLARE (thread_create)
|
||||
TEST_DECLARE (strlcpy)
|
||||
TEST_DECLARE (strlcat)
|
||||
TEST_DECLARE (counters_init)
|
||||
TEST_DECLARE (dlerror)
|
||||
TEST_DECLARE (poll_duplex)
|
||||
TEST_DECLARE (poll_unidirectional)
|
||||
TEST_DECLARE (poll_close)
|
||||
TEST_DECLARE (we_get_signal)
|
||||
TEST_DECLARE (we_get_signals)
|
||||
#ifdef _WIN32
|
||||
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
|
||||
TEST_DECLARE (argument_escaping)
|
||||
@@ -350,6 +352,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (poll_unidirectional)
|
||||
TEST_ENTRY (poll_close)
|
||||
|
||||
TEST_ENTRY (spawn_fails)
|
||||
TEST_ENTRY (spawn_exit_code)
|
||||
TEST_ENTRY (spawn_stdout)
|
||||
TEST_ENTRY (spawn_stdin)
|
||||
@@ -364,6 +367,10 @@ TASK_LIST_START
|
||||
TEST_ENTRY (spawn_stdout_to_file)
|
||||
TEST_ENTRY (fs_poll)
|
||||
TEST_ENTRY (kill)
|
||||
|
||||
TEST_ENTRY (we_get_signal)
|
||||
TEST_ENTRY (we_get_signals)
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
|
||||
TEST_ENTRY (argument_escaping)
|
||||
@@ -411,7 +418,6 @@ TASK_LIST_START
|
||||
TEST_ENTRY (thread_create)
|
||||
TEST_ENTRY (strlcpy)
|
||||
TEST_ENTRY (strlcat)
|
||||
TEST_ENTRY (counters_init)
|
||||
TEST_ENTRY (dlerror)
|
||||
#if 0
|
||||
/* These are for testing the test runner. */
|
||||
|
||||
162
deps/uv/test/test-signal.c
vendored
Normal file
162
deps/uv/test/test-signal.c
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
/* 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 _WIN32
|
||||
|
||||
TEST_IMPL(we_get_signal) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(we_get_signals) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !_WIN32 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* This test does not pretend to be cross-platform. */
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define NSIGNALS 10
|
||||
|
||||
struct timer_ctx {
|
||||
unsigned int ncalls;
|
||||
uv_timer_t handle;
|
||||
int signum;
|
||||
};
|
||||
|
||||
struct signal_ctx {
|
||||
enum { CLOSE, STOP } stop_or_close;
|
||||
unsigned int ncalls;
|
||||
uv_signal_t handle;
|
||||
int signum;
|
||||
};
|
||||
|
||||
|
||||
static void signal_cb(uv_signal_t* handle, int signum) {
|
||||
struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
|
||||
ASSERT(signum == ctx->signum);
|
||||
|
||||
if (++ctx->ncalls == NSIGNALS) {
|
||||
if (ctx->stop_or_close == STOP)
|
||||
uv_signal_stop(handle);
|
||||
else if (ctx->stop_or_close == CLOSE)
|
||||
uv_close((uv_handle_t*)handle, NULL);
|
||||
else
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void timer_cb(uv_timer_t* handle, int status) {
|
||||
struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle);
|
||||
|
||||
raise(ctx->signum);
|
||||
|
||||
if (++ctx->ncalls == NSIGNALS)
|
||||
uv_close((uv_handle_t*)handle, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void start_watcher(uv_loop_t* loop, int signum, struct signal_ctx* ctx) {
|
||||
ctx->ncalls = 0;
|
||||
ctx->signum = signum;
|
||||
ctx->stop_or_close = CLOSE;
|
||||
ASSERT(0 == uv_signal_init(loop, &ctx->handle));
|
||||
ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum));
|
||||
}
|
||||
|
||||
|
||||
static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) {
|
||||
ctx->ncalls = 0;
|
||||
ctx->signum = signum;
|
||||
ASSERT(0 == uv_timer_init(loop, &ctx->handle));
|
||||
ASSERT(0 == uv_timer_start(&ctx->handle, timer_cb, 5, 5));
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(we_get_signal) {
|
||||
struct signal_ctx sc;
|
||||
struct timer_ctx tc;
|
||||
uv_loop_t* loop;
|
||||
|
||||
loop = uv_default_loop();
|
||||
start_timer(loop, SIGCHLD, &tc);
|
||||
start_watcher(loop, SIGCHLD, &sc);
|
||||
sc.stop_or_close = STOP; /* stop, don't close the signal handle */
|
||||
ASSERT(0 == uv_run(loop));
|
||||
ASSERT(tc.ncalls == NSIGNALS);
|
||||
ASSERT(sc.ncalls == NSIGNALS);
|
||||
|
||||
start_timer(loop, SIGCHLD, &tc);
|
||||
ASSERT(0 == uv_run(loop));
|
||||
ASSERT(tc.ncalls == NSIGNALS);
|
||||
ASSERT(sc.ncalls == NSIGNALS);
|
||||
|
||||
sc.ncalls = 0;
|
||||
sc.stop_or_close = CLOSE; /* now close it when it's done */
|
||||
uv_signal_start(&sc.handle, signal_cb, SIGCHLD);
|
||||
|
||||
start_timer(loop, SIGCHLD, &tc);
|
||||
ASSERT(0 == uv_run(loop));
|
||||
ASSERT(tc.ncalls == NSIGNALS);
|
||||
ASSERT(sc.ncalls == NSIGNALS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(we_get_signals) {
|
||||
struct signal_ctx sc[4];
|
||||
struct timer_ctx tc[2];
|
||||
uv_loop_t* loop;
|
||||
unsigned int i;
|
||||
|
||||
loop = uv_default_loop();
|
||||
start_watcher(loop, SIGUSR1, sc + 0);
|
||||
start_watcher(loop, SIGUSR1, sc + 1);
|
||||
start_watcher(loop, SIGUSR2, sc + 2);
|
||||
start_watcher(loop, SIGUSR2, sc + 3);
|
||||
start_timer(loop, SIGUSR1, tc + 0);
|
||||
start_timer(loop, SIGUSR2, tc + 1);
|
||||
ASSERT(0 == uv_run(loop));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sc); i++)
|
||||
ASSERT(sc[i].ncalls == NSIGNALS);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tc); i++)
|
||||
ASSERT(tc[i].ncalls == NSIGNALS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
56
deps/uv/test/test-spawn.c
vendored
56
deps/uv/test/test-spawn.c
vendored
@@ -65,7 +65,7 @@ static void exit_cb_failure_expected(uv_process_t* process, int exit_status,
|
||||
int term_signal) {
|
||||
printf("exit_cb\n");
|
||||
exit_cb_called++;
|
||||
ASSERT(exit_status == 127);
|
||||
ASSERT(exit_status == -1);
|
||||
ASSERT(term_signal == 0);
|
||||
uv_close((uv_handle_t*)process, close_cb);
|
||||
}
|
||||
@@ -145,6 +145,17 @@ static void timer_cb(uv_timer_t* handle, int status) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(spawn_fails) {
|
||||
init_process_options("", exit_cb_failure_expected);
|
||||
options.file = options.args[0] = "program-that-had-better-not-exist";
|
||||
ASSERT(0 == uv_spawn(uv_default_loop(), &process, options));
|
||||
ASSERT(0 != uv_is_active((uv_handle_t*)&process));
|
||||
ASSERT(0 == uv_run(uv_default_loop()));
|
||||
ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(spawn_exit_code) {
|
||||
int r;
|
||||
|
||||
@@ -578,11 +589,11 @@ TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
|
||||
}
|
||||
|
||||
|
||||
wchar_t* make_program_args(char** args, int verbatim_arguments);
|
||||
wchar_t* quote_cmd_arg(const wchar_t *source, wchar_t *target);
|
||||
uv_err_t make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr);
|
||||
WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target);
|
||||
|
||||
TEST_IMPL(argument_escaping) {
|
||||
const wchar_t* test_str[] = {
|
||||
const WCHAR* test_str[] = {
|
||||
L"HelloWorld",
|
||||
L"Hello World",
|
||||
L"Hello\"World",
|
||||
@@ -594,12 +605,13 @@ TEST_IMPL(argument_escaping) {
|
||||
L"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\""
|
||||
};
|
||||
const int count = sizeof(test_str) / sizeof(*test_str);
|
||||
wchar_t** test_output;
|
||||
wchar_t* command_line;
|
||||
wchar_t** cracked;
|
||||
WCHAR** test_output;
|
||||
WCHAR* command_line;
|
||||
WCHAR** cracked;
|
||||
size_t total_size = 0;
|
||||
int i;
|
||||
int num_args;
|
||||
uv_err_t result;
|
||||
|
||||
char* verbatim[] = {
|
||||
"cmd.exe",
|
||||
@@ -607,18 +619,18 @@ TEST_IMPL(argument_escaping) {
|
||||
"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"",
|
||||
NULL
|
||||
};
|
||||
wchar_t* verbatim_output;
|
||||
wchar_t* non_verbatim_output;
|
||||
WCHAR* verbatim_output;
|
||||
WCHAR* non_verbatim_output;
|
||||
|
||||
test_output = calloc(count, sizeof(wchar_t*));
|
||||
test_output = calloc(count, sizeof(WCHAR*));
|
||||
for (i = 0; i < count; ++i) {
|
||||
test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(wchar_t));
|
||||
test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR));
|
||||
quote_cmd_arg(test_str[i], test_output[i]);
|
||||
wprintf(L"input : %s\n", test_str[i]);
|
||||
wprintf(L"output: %s\n", test_output[i]);
|
||||
total_size += wcslen(test_output[i]) + 1;
|
||||
}
|
||||
command_line = calloc(total_size + 1, sizeof(wchar_t));
|
||||
command_line = calloc(total_size + 1, sizeof(WCHAR));
|
||||
for (i = 0; i < count; ++i) {
|
||||
wcscat(command_line, test_output[i]);
|
||||
wcscat(command_line, L" ");
|
||||
@@ -638,8 +650,10 @@ TEST_IMPL(argument_escaping) {
|
||||
free(test_output[i]);
|
||||
}
|
||||
|
||||
verbatim_output = make_program_args(verbatim, 1);
|
||||
non_verbatim_output = make_program_args(verbatim, 0);
|
||||
result = make_program_args(verbatim, 1, &verbatim_output);
|
||||
ASSERT(result.code == UV_OK);
|
||||
result = make_program_args(verbatim, 0, &non_verbatim_output);
|
||||
ASSERT(result.code == UV_OK);
|
||||
|
||||
wprintf(L" verbatim_output: %s\n", verbatim_output);
|
||||
wprintf(L"non_verbatim_output: %s\n", non_verbatim_output);
|
||||
@@ -653,7 +667,7 @@ TEST_IMPL(argument_escaping) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
wchar_t* make_program_env(char** env_block);
|
||||
WCHAR* make_program_env(char** env_block);
|
||||
|
||||
TEST_IMPL(environment_creation) {
|
||||
int i;
|
||||
@@ -666,22 +680,22 @@ TEST_IMPL(environment_creation) {
|
||||
NULL
|
||||
};
|
||||
|
||||
wchar_t expected[512];
|
||||
wchar_t* ptr = expected;
|
||||
wchar_t* result;
|
||||
wchar_t* str;
|
||||
WCHAR expected[512];
|
||||
WCHAR* ptr = expected;
|
||||
WCHAR* result;
|
||||
WCHAR* str;
|
||||
|
||||
for (i = 0; i < sizeof(environment) / sizeof(environment[0]) - 1; i++) {
|
||||
ptr += uv_utf8_to_utf16(environment[i], ptr, expected + sizeof(expected) - ptr);
|
||||
}
|
||||
|
||||
memcpy(ptr, L"SYSTEMROOT=", sizeof(L"SYSTEMROOT="));
|
||||
ptr += sizeof(L"SYSTEMROOT=")/sizeof(wchar_t) - 1;
|
||||
ptr += sizeof(L"SYSTEMROOT=")/sizeof(WCHAR) - 1;
|
||||
ptr += GetEnvironmentVariableW(L"SYSTEMROOT", ptr, expected + sizeof(expected) - ptr);
|
||||
++ptr;
|
||||
|
||||
memcpy(ptr, L"SYSTEMDRIVE=", sizeof(L"SYSTEMDRIVE="));
|
||||
ptr += sizeof(L"SYSTEMDRIVE=")/sizeof(wchar_t) - 1;
|
||||
ptr += sizeof(L"SYSTEMDRIVE=")/sizeof(WCHAR) - 1;
|
||||
ptr += GetEnvironmentVariableW(L"SYSTEMDRIVE", ptr, expected + sizeof(expected) - ptr);
|
||||
++ptr;
|
||||
*ptr = '\0';
|
||||
|
||||
2
deps/uv/test/test-tcp-unexpected-read.c
vendored
2
deps/uv/test/test-tcp-unexpected-read.c
vendored
@@ -107,7 +107,7 @@ TEST_IMPL(tcp_unexpected_read) {
|
||||
* start busy looping when the server sends a message and the client isn't
|
||||
* reading.
|
||||
*/
|
||||
ASSERT(ticks <= 10);
|
||||
ASSERT(ticks <= 20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
10
deps/uv/uv.gyp
vendored
10
deps/uv/uv.gyp
vendored
@@ -59,6 +59,7 @@
|
||||
'sources': [
|
||||
'include/uv-private/uv-win.h',
|
||||
'src/win/async.c',
|
||||
'src/win/atomicops-inl.h',
|
||||
'src/win/core.c',
|
||||
'src/win/dl.c',
|
||||
'src/win/error.c',
|
||||
@@ -76,6 +77,7 @@
|
||||
'src/win/process-stdio.c',
|
||||
'src/win/req.c',
|
||||
'src/win/req-inl.h',
|
||||
'src/win/signal.c',
|
||||
'src/win/stream.c',
|
||||
'src/win/stream-inl.h',
|
||||
'src/win/tcp.c',
|
||||
@@ -109,6 +111,10 @@
|
||||
'include/uv-private/eio.h',
|
||||
'include/uv-private/ev.h',
|
||||
'include/uv-private/uv-unix.h',
|
||||
'include/uv-private/uv-linux.h',
|
||||
'include/uv-private/uv-sunos.h',
|
||||
'include/uv-private/uv-darwin.h',
|
||||
'include/uv-private/uv-bsd.h',
|
||||
'src/unix/async.c',
|
||||
'src/unix/core.c',
|
||||
'src/unix/dl.c',
|
||||
@@ -127,6 +133,7 @@
|
||||
'src/unix/pipe.c',
|
||||
'src/unix/poll.c',
|
||||
'src/unix/process.c',
|
||||
'src/unix/signal.c',
|
||||
'src/unix/stream.c',
|
||||
'src/unix/tcp.c',
|
||||
'src/unix/thread.c',
|
||||
@@ -256,6 +263,7 @@
|
||||
'test/test-semaphore.c',
|
||||
'test/test-shutdown-close.c',
|
||||
'test/test-shutdown-eof.c',
|
||||
'test/test-signal.c',
|
||||
'test/test-spawn.c',
|
||||
'test/test-fs-poll.c',
|
||||
'test/test-stdio-over-pipes.c',
|
||||
@@ -275,6 +283,7 @@
|
||||
'test/test-tcp-unexpected-read.c',
|
||||
'test/test-threadpool.c',
|
||||
'test/test-mutexes.c',
|
||||
'test/test-signal.c',
|
||||
'test/test-thread.c',
|
||||
'test/test-timer-again.c',
|
||||
'test/test-timer.c',
|
||||
@@ -284,7 +293,6 @@
|
||||
'test/test-udp-options.c',
|
||||
'test/test-udp-send-and-recv.c',
|
||||
'test/test-udp-multicast-join.c',
|
||||
'test/test-counters-init.c',
|
||||
'test/test-dlerror.c',
|
||||
'test/test-udp-multicast-ttl.c',
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user