noderb 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/noderb_extension/extconf.rb +4 -2
- data/ext/noderb_extension/libuv/AUTHORS +2 -0
- data/ext/noderb_extension/libuv/Makefile +1 -1
- data/ext/noderb_extension/libuv/common.gypi +51 -51
- data/ext/noderb_extension/libuv/config-mingw.mk +3 -9
- data/ext/noderb_extension/libuv/config-unix.mk +10 -1
- data/ext/noderb_extension/libuv/include/uv-private/uv-unix.h +3 -2
- data/ext/noderb_extension/libuv/include/uv-private/uv-win.h +7 -6
- data/ext/noderb_extension/libuv/include/uv.h +47 -13
- data/ext/noderb_extension/libuv/src/ares/config_netbsd/ares_config.h +510 -0
- data/ext/noderb_extension/libuv/src/unix/core.c +20 -65
- data/ext/noderb_extension/libuv/src/unix/darwin.c +1 -0
- data/ext/noderb_extension/libuv/src/unix/eio/config_netbsd.h +81 -0
- data/ext/noderb_extension/libuv/src/unix/error.c +9 -1
- data/ext/noderb_extension/libuv/src/unix/ev/config_netbsd.h +120 -0
- data/ext/noderb_extension/libuv/src/unix/fs.c +151 -21
- data/ext/noderb_extension/libuv/src/unix/internal.h +30 -0
- data/ext/noderb_extension/libuv/src/unix/netbsd.c +68 -0
- data/ext/noderb_extension/libuv/src/unix/pipe.c +20 -30
- data/ext/noderb_extension/libuv/src/unix/process.c +13 -0
- data/ext/noderb_extension/libuv/src/unix/stream.c +105 -63
- data/ext/noderb_extension/libuv/src/unix/tcp.c +75 -21
- data/ext/noderb_extension/libuv/src/unix/tty.c +69 -0
- data/ext/noderb_extension/libuv/src/unix/udp.c +31 -0
- data/ext/noderb_extension/libuv/src/uv-common.c +2 -0
- data/ext/noderb_extension/libuv/src/uv-common.h +0 -6
- data/ext/noderb_extension/libuv/src/win/cares.c +7 -7
- data/ext/noderb_extension/libuv/src/win/core.c +25 -17
- data/ext/noderb_extension/libuv/src/win/error.c +7 -0
- data/ext/noderb_extension/libuv/src/win/fs.c +587 -92
- data/ext/noderb_extension/libuv/src/win/getaddrinfo.c +3 -1
- data/ext/noderb_extension/libuv/src/win/handle.c +0 -17
- data/ext/noderb_extension/libuv/src/win/internal.h +15 -5
- data/ext/noderb_extension/libuv/src/win/loop-watcher.c +1 -1
- data/ext/noderb_extension/libuv/src/win/pipe.c +6 -0
- data/ext/noderb_extension/libuv/src/win/process.c +90 -43
- data/ext/noderb_extension/libuv/src/win/tcp.c +37 -4
- data/ext/noderb_extension/libuv/src/win/threads.c +81 -0
- data/ext/noderb_extension/libuv/src/win/timer.c +15 -15
- data/ext/noderb_extension/libuv/src/win/tty.c +37 -0
- data/ext/noderb_extension/libuv/src/win/udp.c +8 -2
- data/ext/noderb_extension/libuv/src/win/winapi.c +12 -0
- data/ext/noderb_extension/libuv/src/win/winapi.h +1146 -1015
- data/ext/noderb_extension/libuv/test/benchmark-ares.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-getaddrinfo.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-ping-pongs.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-pound.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-pump.c +4 -6
- data/ext/noderb_extension/libuv/test/benchmark-spawn.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-udp-packet-storm.c +0 -1
- data/ext/noderb_extension/libuv/test/dns-server.c +2 -2
- data/ext/noderb_extension/libuv/test/echo-server.c +4 -5
- data/ext/noderb_extension/libuv/test/run-tests.c +0 -2
- data/ext/noderb_extension/libuv/test/test-async.c +0 -2
- data/ext/noderb_extension/libuv/test/test-callback-stack.c +0 -2
- data/ext/noderb_extension/libuv/test/test-connection-fail.c +3 -5
- data/ext/noderb_extension/libuv/test/test-delayed-accept.c +2 -3
- data/ext/noderb_extension/libuv/test/test-fs.c +578 -42
- data/ext/noderb_extension/libuv/test/test-get-currentexe.c +12 -2
- data/ext/noderb_extension/libuv/test/test-getaddrinfo.c +10 -5
- data/ext/noderb_extension/libuv/test/test-gethostbyname.c +0 -2
- data/ext/noderb_extension/libuv/test/test-getsockname.c +92 -72
- data/ext/noderb_extension/libuv/test/test-idle.c +0 -3
- data/ext/noderb_extension/libuv/test/test-list.h +13 -0
- data/ext/noderb_extension/libuv/test/test-loop-handles.c +0 -3
- data/ext/noderb_extension/libuv/test/test-ping-pong.c +13 -19
- data/ext/noderb_extension/libuv/test/test-pipe-bind-error.c +0 -12
- data/ext/noderb_extension/libuv/test/test-ref.c +0 -7
- data/ext/noderb_extension/libuv/test/test-shutdown-eof.c +3 -3
- data/ext/noderb_extension/libuv/test/test-spawn.c +2 -11
- data/ext/noderb_extension/libuv/test/test-tcp-bind-error.c +0 -19
- data/ext/noderb_extension/libuv/test/test-tcp-bind6-error.c +0 -15
- data/ext/noderb_extension/libuv/test/test-tcp-close.c +129 -0
- data/ext/noderb_extension/libuv/test/test-tcp-writealot.c +0 -3
- data/ext/noderb_extension/libuv/test/test-threadpool.c +0 -2
- data/ext/noderb_extension/libuv/test/test-timer-again.c +0 -3
- data/ext/noderb_extension/libuv/test/test-timer.c +0 -2
- data/ext/noderb_extension/libuv/test/test-udp-dgram-too-big.c +0 -2
- data/ext/noderb_extension/libuv/test/test-udp-ipv6.c +0 -2
- data/ext/noderb_extension/libuv/test/test-udp-send-and-recv.c +0 -2
- data/ext/noderb_extension/libuv/uv.gyp +18 -2
- data/ext/noderb_extension/noderb_fs.c +1 -2
- data/lib/noderb/version.rb +1 -1
- metadata +10 -2
|
@@ -27,28 +27,8 @@
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
|
|
30
|
-
|
|
30
|
+
uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
|
|
31
31
|
loop->counters.tcp_init++;
|
|
32
|
-
|
|
33
|
-
tcp->alloc_cb = NULL;
|
|
34
|
-
tcp->connect_req = NULL;
|
|
35
|
-
tcp->accepted_fd = -1;
|
|
36
|
-
tcp->fd = -1;
|
|
37
|
-
tcp->delayed_error = 0;
|
|
38
|
-
ngx_queue_init(&tcp->write_queue);
|
|
39
|
-
ngx_queue_init(&tcp->write_completed_queue);
|
|
40
|
-
tcp->write_queue_size = 0;
|
|
41
|
-
|
|
42
|
-
ev_init(&tcp->read_watcher, uv__stream_io);
|
|
43
|
-
tcp->read_watcher.data = tcp;
|
|
44
|
-
|
|
45
|
-
ev_init(&tcp->write_watcher, uv__stream_io);
|
|
46
|
-
tcp->write_watcher.data = tcp;
|
|
47
|
-
|
|
48
|
-
assert(ngx_queue_empty(&tcp->write_queue));
|
|
49
|
-
assert(ngx_queue_empty(&tcp->write_completed_queue));
|
|
50
|
-
assert(tcp->write_queue_size == 0);
|
|
51
|
-
|
|
52
32
|
return 0;
|
|
53
33
|
}
|
|
54
34
|
|
|
@@ -122,6 +102,80 @@ int uv_tcp_bind6(uv_tcp_t* tcp, struct sockaddr_in6 addr) {
|
|
|
122
102
|
}
|
|
123
103
|
|
|
124
104
|
|
|
105
|
+
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
|
|
106
|
+
int* namelen) {
|
|
107
|
+
socklen_t socklen;
|
|
108
|
+
int saved_errno;
|
|
109
|
+
int rv = 0;
|
|
110
|
+
|
|
111
|
+
/* Don't clobber errno. */
|
|
112
|
+
saved_errno = errno;
|
|
113
|
+
|
|
114
|
+
if (handle->delayed_error) {
|
|
115
|
+
uv_err_new(handle->loop, handle->delayed_error);
|
|
116
|
+
rv = -1;
|
|
117
|
+
goto out;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (handle->fd < 0) {
|
|
121
|
+
uv_err_new(handle->loop, EINVAL);
|
|
122
|
+
rv = -1;
|
|
123
|
+
goto out;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
|
127
|
+
socklen = (socklen_t)*namelen;
|
|
128
|
+
|
|
129
|
+
if (getsockname(handle->fd, name, &socklen) == -1) {
|
|
130
|
+
uv_err_new(handle->loop, errno);
|
|
131
|
+
rv = -1;
|
|
132
|
+
} else {
|
|
133
|
+
*namelen = (int)socklen;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
out:
|
|
137
|
+
errno = saved_errno;
|
|
138
|
+
return rv;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
|
|
143
|
+
int* namelen) {
|
|
144
|
+
socklen_t socklen;
|
|
145
|
+
int saved_errno;
|
|
146
|
+
int rv = 0;
|
|
147
|
+
|
|
148
|
+
/* Don't clobber errno. */
|
|
149
|
+
saved_errno = errno;
|
|
150
|
+
|
|
151
|
+
if (handle->delayed_error) {
|
|
152
|
+
uv_err_new(handle->loop, handle->delayed_error);
|
|
153
|
+
rv = -1;
|
|
154
|
+
goto out;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (handle->fd < 0) {
|
|
158
|
+
uv_err_new(handle->loop, EINVAL);
|
|
159
|
+
rv = -1;
|
|
160
|
+
goto out;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
|
164
|
+
socklen = (socklen_t)*namelen;
|
|
165
|
+
|
|
166
|
+
if (getpeername(handle->fd, name, &socklen) == -1) {
|
|
167
|
+
uv_err_new(handle->loop, errno);
|
|
168
|
+
rv = -1;
|
|
169
|
+
} else {
|
|
170
|
+
*namelen = (int)socklen;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
out:
|
|
174
|
+
errno = saved_errno;
|
|
175
|
+
return rv;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
125
179
|
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
|
|
126
180
|
int r;
|
|
127
181
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
* of this software and associated documentation files (the "Software"), to
|
|
5
|
+
* deal in the Software without restriction, including without limitation the
|
|
6
|
+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
7
|
+
* sell copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
* furnished to do so, subject to the following conditions:
|
|
9
|
+
*
|
|
10
|
+
* The above copyright notice and this permission notice shall be included in
|
|
11
|
+
* all copies or substantial portions of the Software.
|
|
12
|
+
*
|
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
18
|
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
19
|
+
* IN THE SOFTWARE.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
#include "uv.h"
|
|
23
|
+
#include "internal.h"
|
|
24
|
+
|
|
25
|
+
#include <assert.h>
|
|
26
|
+
#include <termios.h>
|
|
27
|
+
#include <errno.h>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd) {
|
|
31
|
+
uv__nonblock(fd, 1);
|
|
32
|
+
uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);
|
|
33
|
+
uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE | UV_WRITABLE);
|
|
34
|
+
loop->counters.tty_init++;
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
int uv_tty_set_mode(uv_tty_t* tty, int mode) {
|
|
40
|
+
int fd = tty->fd;
|
|
41
|
+
struct termios orig_termios; /* in order to restore at exit */
|
|
42
|
+
struct termios raw;
|
|
43
|
+
|
|
44
|
+
if (tcgetattr(fd, &orig_termios) == -1) goto fatal;
|
|
45
|
+
|
|
46
|
+
raw = orig_termios; /* modify the original mode */
|
|
47
|
+
/* input modes: no break, no CR to NL, no parity check, no strip char,
|
|
48
|
+
* no start/stop output control. */
|
|
49
|
+
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
|
|
50
|
+
/* output modes */
|
|
51
|
+
raw.c_oflag |= (ONLCR);
|
|
52
|
+
/* control modes - set 8 bit chars */
|
|
53
|
+
raw.c_cflag |= (CS8);
|
|
54
|
+
/* local modes - echoing off, canonical off, no extended functions,
|
|
55
|
+
* no signal chars (^Z,^C) */
|
|
56
|
+
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
|
57
|
+
/* control chars - set return condition: min number of bytes and timer.
|
|
58
|
+
* We want read to return every single byte, without timeout. */
|
|
59
|
+
raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
|
|
60
|
+
|
|
61
|
+
/* put terminal in raw mode after flushing */
|
|
62
|
+
if (tcsetattr(fd, TCSAFLUSH, &raw) < 0) goto fatal;
|
|
63
|
+
return 0;
|
|
64
|
+
|
|
65
|
+
fatal:
|
|
66
|
+
uv_err_new(tty->loop, ENOTTY);
|
|
67
|
+
return -1;
|
|
68
|
+
}
|
|
69
|
+
|
|
@@ -460,6 +460,37 @@ int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags) {
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
|
|
463
|
+
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
|
|
464
|
+
int* namelen) {
|
|
465
|
+
socklen_t socklen;
|
|
466
|
+
int saved_errno;
|
|
467
|
+
int rv = 0;
|
|
468
|
+
|
|
469
|
+
/* Don't clobber errno. */
|
|
470
|
+
saved_errno = errno;
|
|
471
|
+
|
|
472
|
+
if (handle->fd < 0) {
|
|
473
|
+
uv_err_new(handle->loop, EINVAL);
|
|
474
|
+
rv = -1;
|
|
475
|
+
goto out;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
|
479
|
+
socklen = (socklen_t)*namelen;
|
|
480
|
+
|
|
481
|
+
if (getsockname(handle->fd, name, &socklen) == -1) {
|
|
482
|
+
uv_err_new(handle->loop, errno);
|
|
483
|
+
rv = -1;
|
|
484
|
+
} else {
|
|
485
|
+
*namelen = (int)socklen;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
out:
|
|
489
|
+
errno = saved_errno;
|
|
490
|
+
return rv;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
|
|
463
494
|
int uv_udp_send(uv_udp_send_t* req,
|
|
464
495
|
uv_udp_t* handle,
|
|
465
496
|
uv_buf_t bufs[],
|
|
@@ -81,11 +81,13 @@ const char* uv_err_name(uv_err_t err) {
|
|
|
81
81
|
case UV_ENOTCONN: return "ENOTCONN";
|
|
82
82
|
case UV_ENOTSOCK: return "ENOTSOCK";
|
|
83
83
|
case UV_ENOTSUP: return "ENOTSUP";
|
|
84
|
+
case UV_ENOENT: return "ENOENT";
|
|
84
85
|
case UV_EPIPE: return "EPIPE";
|
|
85
86
|
case UV_EPROTO: return "EPROTO";
|
|
86
87
|
case UV_EPROTONOSUPPORT: return "EPROTONOSUPPORT";
|
|
87
88
|
case UV_EPROTOTYPE: return "EPROTOTYPE";
|
|
88
89
|
case UV_ETIMEDOUT: return "ETIMEDOUT";
|
|
90
|
+
case UV_EEXIST: return "EEXIST";
|
|
89
91
|
default:
|
|
90
92
|
assert(0);
|
|
91
93
|
return NULL;
|
|
@@ -31,12 +31,6 @@
|
|
|
31
31
|
|
|
32
32
|
#define COUNTOF(a) (sizeof(a) / sizeof(a[0]))
|
|
33
33
|
|
|
34
|
-
/* Used for the uv_fs_ functions */
|
|
35
|
-
#define SET_REQ_RESULT(req, result) \
|
|
36
|
-
req->result = result; \
|
|
37
|
-
if (result == -1) { \
|
|
38
|
-
req->errorno = errno; \
|
|
39
|
-
}
|
|
40
34
|
|
|
41
35
|
struct uv_ares_task_s {
|
|
42
36
|
UV_HANDLE_FIELDS
|
|
@@ -95,8 +95,8 @@ static void CALLBACK uv_ares_socksignal_tp(void* parameter,
|
|
|
95
95
|
/* periodically call ares to check for timeouts */
|
|
96
96
|
static void uv_ares_poll(uv_timer_t* handle, int status) {
|
|
97
97
|
uv_loop_t* loop = handle->loop;
|
|
98
|
-
if (loop->
|
|
99
|
-
ares_process_fd(loop->
|
|
98
|
+
if (loop->ares_chan != NULL && loop->ares_active_sockets > 0) {
|
|
99
|
+
ares_process_fd(loop->ares_chan, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -214,7 +214,7 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read,
|
|
|
214
214
|
/* called via uv_poll when ares completion port signaled */
|
|
215
215
|
void uv_process_ares_event_req(uv_loop_t* loop, uv_ares_action_t* handle,
|
|
216
216
|
uv_req_t* req) {
|
|
217
|
-
ares_process_fd(loop->
|
|
217
|
+
ares_process_fd(loop->ares_chan,
|
|
218
218
|
handle->read ? handle->sock : INVALID_SOCKET,
|
|
219
219
|
handle->write ? handle->sock : INVALID_SOCKET);
|
|
220
220
|
|
|
@@ -258,7 +258,7 @@ int uv_ares_init_options(uv_loop_t* loop,
|
|
|
258
258
|
int rc;
|
|
259
259
|
|
|
260
260
|
/* only allow single init at a time */
|
|
261
|
-
if (loop->
|
|
261
|
+
if (loop->ares_chan != NULL) {
|
|
262
262
|
return UV_EALREADY;
|
|
263
263
|
}
|
|
264
264
|
|
|
@@ -272,7 +272,7 @@ int uv_ares_init_options(uv_loop_t* loop,
|
|
|
272
272
|
|
|
273
273
|
/* if success, save channel */
|
|
274
274
|
if (rc == ARES_SUCCESS) {
|
|
275
|
-
loop->
|
|
275
|
+
loop->ares_chan = *channelptr;
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
return rc;
|
|
@@ -282,8 +282,8 @@ int uv_ares_init_options(uv_loop_t* loop,
|
|
|
282
282
|
/* release memory */
|
|
283
283
|
void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) {
|
|
284
284
|
/* only allow destroy if did init */
|
|
285
|
-
if (loop->
|
|
285
|
+
if (loop->ares_chan != NULL) {
|
|
286
286
|
ares_destroy(channel);
|
|
287
|
-
loop->
|
|
287
|
+
loop->ares_chan = NULL;
|
|
288
288
|
}
|
|
289
289
|
}
|
|
@@ -33,7 +33,22 @@
|
|
|
33
33
|
|
|
34
34
|
/* The only event loop we support right now */
|
|
35
35
|
static uv_loop_t uv_default_loop_;
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
/* uv_once intialization guards */
|
|
38
|
+
static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
|
|
39
|
+
static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
static void uv_init(void) {
|
|
43
|
+
/* Initialize winsock */
|
|
44
|
+
uv_winsock_init();
|
|
45
|
+
|
|
46
|
+
/* Fetch winapi function pointers */
|
|
47
|
+
uv_winapi_init();
|
|
48
|
+
|
|
49
|
+
/* Initialize FS */
|
|
50
|
+
uv_fs_init();
|
|
51
|
+
}
|
|
37
52
|
|
|
38
53
|
|
|
39
54
|
static void uv_loop_init(uv_loop_t* loop) {
|
|
@@ -62,31 +77,24 @@ static void uv_loop_init(uv_loop_t* loop) {
|
|
|
62
77
|
loop->next_idle_handle = NULL;
|
|
63
78
|
|
|
64
79
|
loop->ares_active_sockets = 0;
|
|
65
|
-
loop->
|
|
80
|
+
loop->ares_chan = NULL;
|
|
66
81
|
|
|
67
82
|
loop->last_error = uv_ok_;
|
|
68
83
|
}
|
|
69
84
|
|
|
70
85
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
uv_default_loop_initialized_ = 1;
|
|
75
|
-
}
|
|
86
|
+
static void uv_default_loop_init(void) {
|
|
87
|
+
/* Intialize libuv itself first */
|
|
88
|
+
uv_once(&uv_init_guard_, uv_init);
|
|
76
89
|
|
|
77
|
-
|
|
90
|
+
/* Initialize the main loop */
|
|
91
|
+
uv_loop_init(&uv_default_loop_);
|
|
78
92
|
}
|
|
79
93
|
|
|
80
94
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
/* Fetch winapi function pointers */
|
|
86
|
-
uv_winapi_init();
|
|
87
|
-
|
|
88
|
-
/* Initialize FS */
|
|
89
|
-
uv_fs_init();
|
|
95
|
+
uv_loop_t* uv_default_loop() {
|
|
96
|
+
uv_once(&uv_default_loop_init_guard_, uv_default_loop_init);
|
|
97
|
+
return &uv_default_loop_;
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
|
|
@@ -96,6 +96,8 @@ char* uv_strerror(uv_err_t err) {
|
|
|
96
96
|
uv_err_code uv_translate_sys_error(int sys_errno) {
|
|
97
97
|
switch (sys_errno) {
|
|
98
98
|
case ERROR_SUCCESS: return UV_OK;
|
|
99
|
+
case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
|
|
100
|
+
case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
|
|
99
101
|
case ERROR_NOACCESS: return UV_EACCESS;
|
|
100
102
|
case WSAEACCES: return UV_EACCESS;
|
|
101
103
|
case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
|
|
@@ -104,6 +106,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
|
|
|
104
106
|
case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT;
|
|
105
107
|
case WSAEWOULDBLOCK: return UV_EAGAIN;
|
|
106
108
|
case WSAEALREADY: return UV_EALREADY;
|
|
109
|
+
case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED;
|
|
110
|
+
case WSAECONNABORTED: return UV_ECONNABORTED;
|
|
107
111
|
case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED;
|
|
108
112
|
case WSAECONNREFUSED: return UV_ECONNREFUSED;
|
|
109
113
|
case WSAEFAULT: return UV_EFAULT;
|
|
@@ -117,6 +121,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
|
|
|
117
121
|
case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
|
|
118
122
|
case WSAENETUNREACH: return UV_ENETUNREACH;
|
|
119
123
|
case ERROR_OUTOFMEMORY: return UV_ENOMEM;
|
|
124
|
+
case ERROR_NOT_CONNECTED: return UV_ENOTCONN;
|
|
125
|
+
case WSAENOTCONN: return UV_ENOTCONN;
|
|
120
126
|
case ERROR_NOT_SUPPORTED: return UV_ENOTSUP;
|
|
121
127
|
case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
|
|
122
128
|
case ERROR_INVALID_FLAGS: return UV_EBADF;
|
|
@@ -125,6 +131,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
|
|
|
125
131
|
case ERROR_BROKEN_PIPE: return UV_EOF;
|
|
126
132
|
case ERROR_PIPE_BUSY: return UV_EBUSY;
|
|
127
133
|
case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT;
|
|
134
|
+
case ERROR_ALREADY_EXISTS: return UV_EEXIST;
|
|
128
135
|
default: return UV_UNKNOWN;
|
|
129
136
|
}
|
|
130
137
|
}
|
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
#include <assert.h>
|
|
23
23
|
#include <malloc.h>
|
|
24
24
|
#include <direct.h>
|
|
25
|
+
#include <errno.h>
|
|
25
26
|
#include <fcntl.h>
|
|
26
27
|
#include <io.h>
|
|
28
|
+
#include <limits.h>
|
|
27
29
|
#include <sys/stat.h>
|
|
28
30
|
#include <sys/utime.h>
|
|
29
31
|
#include <stdio.h>
|
|
@@ -36,6 +38,7 @@
|
|
|
36
38
|
#define UV_FS_FREE_ARG1 0x0004
|
|
37
39
|
#define UV_FS_FREE_PTR 0x0008
|
|
38
40
|
#define UV_FS_CLEANEDUP 0x0010
|
|
41
|
+
#define UV_FS_LAST_ERROR_SET 0x0020
|
|
39
42
|
|
|
40
43
|
#define STRDUP_ARG(req, i) \
|
|
41
44
|
req->arg##i = (void*)strdup((const char*)req->arg##i); \
|
|
@@ -70,13 +73,34 @@
|
|
|
70
73
|
uv_ref((loop));
|
|
71
74
|
|
|
72
75
|
|
|
76
|
+
#define SET_UV_LAST_ERROR_FROM_REQ(req) \
|
|
77
|
+
if (req->flags & UV_FS_LAST_ERROR_SET) { \
|
|
78
|
+
uv_set_sys_error(req->loop, req->last_error); \
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#define SET_REQ_LAST_ERROR(req, error) \
|
|
82
|
+
req->last_error = error; \
|
|
83
|
+
req->flags |= UV_FS_LAST_ERROR_SET;
|
|
84
|
+
|
|
85
|
+
#define SET_REQ_RESULT(req, result_value) \
|
|
86
|
+
req->result = (result_value); \
|
|
87
|
+
if (req->result == -1) { \
|
|
88
|
+
req->errorno = uv_translate_sys_error(_doserrno); \
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#define SET_REQ_RESULT_WIN32_ERROR(req, sys_errno) \
|
|
92
|
+
req->result = -1; \
|
|
93
|
+
req->errorno = uv_translate_sys_error(sys_errno); \
|
|
94
|
+
SET_REQ_LAST_ERROR(req, sys_errno);
|
|
95
|
+
|
|
96
|
+
|
|
73
97
|
void uv_fs_init() {
|
|
74
98
|
_fmode = _O_BINARY;
|
|
75
99
|
}
|
|
76
100
|
|
|
77
101
|
|
|
78
102
|
static void uv_fs_req_init_async(uv_loop_t* loop, uv_fs_t* req,
|
|
79
|
-
uv_fs_type fs_type, uv_fs_cb cb) {
|
|
103
|
+
uv_fs_type fs_type, const char* path, uv_fs_cb cb) {
|
|
80
104
|
uv_req_init(loop, (uv_req_t*) req);
|
|
81
105
|
req->type = UV_FS;
|
|
82
106
|
req->loop = loop;
|
|
@@ -85,7 +109,9 @@ static void uv_fs_req_init_async(uv_loop_t* loop, uv_fs_t* req,
|
|
|
85
109
|
req->cb = cb;
|
|
86
110
|
req->result = 0;
|
|
87
111
|
req->ptr = NULL;
|
|
112
|
+
req->path = path ? strdup(path) : NULL;
|
|
88
113
|
req->errorno = 0;
|
|
114
|
+
req->last_error = 0;
|
|
89
115
|
memset(&req->overlapped, 0, sizeof(req->overlapped));
|
|
90
116
|
}
|
|
91
117
|
|
|
@@ -99,16 +125,118 @@ static void uv_fs_req_init_sync(uv_loop_t* loop, uv_fs_t* req,
|
|
|
99
125
|
req->fs_type = fs_type;
|
|
100
126
|
req->result = 0;
|
|
101
127
|
req->ptr = NULL;
|
|
128
|
+
req->path = NULL;
|
|
102
129
|
req->errorno = 0;
|
|
103
130
|
}
|
|
104
131
|
|
|
105
132
|
|
|
106
133
|
void fs__open(uv_fs_t* req, const char* path, int flags, int mode) {
|
|
107
|
-
|
|
134
|
+
DWORD access;
|
|
135
|
+
DWORD share;
|
|
136
|
+
DWORD disposition;
|
|
137
|
+
DWORD attributes;
|
|
138
|
+
HANDLE file;
|
|
139
|
+
int result, current_umask;
|
|
140
|
+
|
|
141
|
+
/* Obtain the active umask. umask() never fails and returns the previous */
|
|
142
|
+
/* umask. */
|
|
143
|
+
current_umask = umask(0);
|
|
144
|
+
umask(current_umask);
|
|
145
|
+
|
|
146
|
+
/* convert flags and mode to CreateFile parameters */
|
|
147
|
+
switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
|
|
148
|
+
case _O_RDONLY:
|
|
149
|
+
access = GENERIC_READ;
|
|
150
|
+
break;
|
|
151
|
+
case _O_WRONLY:
|
|
152
|
+
access = GENERIC_WRITE;
|
|
153
|
+
break;
|
|
154
|
+
case _O_RDWR:
|
|
155
|
+
access = GENERIC_READ | GENERIC_WRITE;
|
|
156
|
+
break;
|
|
157
|
+
default:
|
|
158
|
+
result = -1;
|
|
159
|
+
goto end;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
* Here is where we deviate significantly from what CRT's _open()
|
|
164
|
+
* does. We indiscriminately use all the sharing modes, to match
|
|
165
|
+
* UNIX semantics. In particular, this ensures that the file can
|
|
166
|
+
* be deleted even whilst it's open, fixing issue #1449.
|
|
167
|
+
*/
|
|
168
|
+
share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
|
169
|
+
|
|
170
|
+
switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
|
|
171
|
+
case 0:
|
|
172
|
+
case _O_EXCL:
|
|
173
|
+
disposition = OPEN_EXISTING;
|
|
174
|
+
break;
|
|
175
|
+
case _O_CREAT:
|
|
176
|
+
disposition = OPEN_ALWAYS;
|
|
177
|
+
break;
|
|
178
|
+
case _O_CREAT | _O_EXCL:
|
|
179
|
+
case _O_CREAT | _O_TRUNC | _O_EXCL:
|
|
180
|
+
disposition = CREATE_NEW;
|
|
181
|
+
break;
|
|
182
|
+
case _O_TRUNC:
|
|
183
|
+
case _O_TRUNC | _O_EXCL:
|
|
184
|
+
disposition = TRUNCATE_EXISTING;
|
|
185
|
+
break;
|
|
186
|
+
case _O_CREAT | _O_TRUNC:
|
|
187
|
+
disposition = CREATE_ALWAYS;
|
|
188
|
+
break;
|
|
189
|
+
default:
|
|
190
|
+
result = -1;
|
|
191
|
+
goto end;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
attributes = FILE_ATTRIBUTE_NORMAL;
|
|
195
|
+
if (flags & _O_CREAT) {
|
|
196
|
+
if (!((mode & ~current_umask) & _S_IWRITE)) {
|
|
197
|
+
attributes |= FILE_ATTRIBUTE_READONLY;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (flags & _O_TEMPORARY ) {
|
|
202
|
+
attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY;
|
|
203
|
+
access |= DELETE;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (flags & _O_SHORT_LIVED) {
|
|
207
|
+
attributes |= FILE_ATTRIBUTE_TEMPORARY;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
switch (flags & (_O_SEQUENTIAL | _O_RANDOM)) {
|
|
211
|
+
case 0:
|
|
212
|
+
break;
|
|
213
|
+
case _O_SEQUENTIAL:
|
|
214
|
+
attributes |= FILE_FLAG_SEQUENTIAL_SCAN;
|
|
215
|
+
break;
|
|
216
|
+
case _O_RANDOM:
|
|
217
|
+
attributes |= FILE_FLAG_RANDOM_ACCESS;
|
|
218
|
+
break;
|
|
219
|
+
default:
|
|
220
|
+
result = -1;
|
|
221
|
+
goto end;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
file = CreateFileA(path,
|
|
225
|
+
access,
|
|
226
|
+
share,
|
|
227
|
+
NULL,
|
|
228
|
+
disposition,
|
|
229
|
+
attributes,
|
|
230
|
+
NULL);
|
|
231
|
+
if (file == INVALID_HANDLE_VALUE) {
|
|
232
|
+
SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
result = _open_osfhandle((intptr_t)file, flags);
|
|
236
|
+
end:
|
|
108
237
|
SET_REQ_RESULT(req, result);
|
|
109
238
|
}
|
|
110
239
|
|
|
111
|
-
|
|
112
240
|
void fs__close(uv_fs_t* req, uv_file file) {
|
|
113
241
|
int result = _close(file);
|
|
114
242
|
SET_REQ_RESULT(req, result);
|
|
@@ -117,33 +245,77 @@ void fs__close(uv_fs_t* req, uv_file file) {
|
|
|
117
245
|
|
|
118
246
|
void fs__read(uv_fs_t* req, uv_file file, void *buf, size_t length,
|
|
119
247
|
off_t offset) {
|
|
120
|
-
|
|
248
|
+
HANDLE handle;
|
|
249
|
+
OVERLAPPED overlapped, *overlapped_ptr;
|
|
250
|
+
LARGE_INTEGER offset_;
|
|
251
|
+
DWORD bytes;
|
|
252
|
+
|
|
253
|
+
handle = (HANDLE) _get_osfhandle(file);
|
|
254
|
+
if (handle == INVALID_HANDLE_VALUE) {
|
|
255
|
+
SET_REQ_RESULT(req, -1);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
121
258
|
|
|
122
|
-
if (
|
|
123
|
-
|
|
259
|
+
if (length > INT_MAX) {
|
|
260
|
+
SET_REQ_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
|
|
261
|
+
return;
|
|
124
262
|
}
|
|
125
263
|
|
|
126
|
-
if (
|
|
127
|
-
|
|
264
|
+
if (offset != -1) {
|
|
265
|
+
memset(&overlapped, 0, sizeof overlapped);
|
|
266
|
+
|
|
267
|
+
offset_.QuadPart = offset;
|
|
268
|
+
overlapped.Offset = offset_.LowPart;
|
|
269
|
+
overlapped.OffsetHigh = offset_.HighPart;
|
|
270
|
+
|
|
271
|
+
overlapped_ptr = &overlapped;
|
|
272
|
+
} else {
|
|
273
|
+
overlapped_ptr = NULL;
|
|
128
274
|
}
|
|
129
275
|
|
|
130
|
-
|
|
276
|
+
if (ReadFile(handle, buf, length, &bytes, overlapped_ptr)) {
|
|
277
|
+
SET_REQ_RESULT(req, bytes);
|
|
278
|
+
} else {
|
|
279
|
+
SET_REQ_ERROR(req, GetLastError());
|
|
280
|
+
}
|
|
131
281
|
}
|
|
132
282
|
|
|
133
283
|
|
|
134
284
|
void fs__write(uv_fs_t* req, uv_file file, void *buf, size_t length,
|
|
135
285
|
off_t offset) {
|
|
136
|
-
|
|
286
|
+
HANDLE handle;
|
|
287
|
+
OVERLAPPED overlapped, *overlapped_ptr;
|
|
288
|
+
LARGE_INTEGER offset_;
|
|
289
|
+
DWORD bytes;
|
|
290
|
+
|
|
291
|
+
handle = (HANDLE) _get_osfhandle(file);
|
|
292
|
+
if (handle == INVALID_HANDLE_VALUE) {
|
|
293
|
+
SET_REQ_RESULT(req, -1);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
137
296
|
|
|
138
|
-
if (
|
|
139
|
-
|
|
297
|
+
if (length > INT_MAX) {
|
|
298
|
+
SET_REQ_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
|
|
299
|
+
return;
|
|
140
300
|
}
|
|
141
301
|
|
|
142
|
-
if (
|
|
143
|
-
|
|
302
|
+
if (offset != -1) {
|
|
303
|
+
memset(&overlapped, 0, sizeof overlapped);
|
|
304
|
+
|
|
305
|
+
offset_.QuadPart = offset;
|
|
306
|
+
overlapped.Offset = offset_.LowPart;
|
|
307
|
+
overlapped.OffsetHigh = offset_.HighPart;
|
|
308
|
+
|
|
309
|
+
overlapped_ptr = &overlapped;
|
|
310
|
+
} else {
|
|
311
|
+
overlapped_ptr = NULL;
|
|
144
312
|
}
|
|
145
313
|
|
|
146
|
-
|
|
314
|
+
if (WriteFile(handle, buf, length, &bytes, overlapped_ptr)) {
|
|
315
|
+
SET_REQ_RESULT(req, bytes);
|
|
316
|
+
} else {
|
|
317
|
+
SET_REQ_ERROR(req, GetLastError());
|
|
318
|
+
}
|
|
147
319
|
}
|
|
148
320
|
|
|
149
321
|
|
|
@@ -186,8 +358,8 @@ void fs__readdir(uv_fs_t* req, const char* path, int flags) {
|
|
|
186
358
|
free(path2);
|
|
187
359
|
|
|
188
360
|
if(dir == INVALID_HANDLE_VALUE) {
|
|
189
|
-
|
|
190
|
-
|
|
361
|
+
SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
|
|
362
|
+
return;
|
|
191
363
|
}
|
|
192
364
|
|
|
193
365
|
buf = (char*)malloc(buf_size);
|
|
@@ -226,7 +398,6 @@ void fs__readdir(uv_fs_t* req, const char* path, int flags) {
|
|
|
226
398
|
req->ptr = buf;
|
|
227
399
|
req->flags |= UV_FS_FREE_PTR;
|
|
228
400
|
|
|
229
|
-
done:
|
|
230
401
|
SET_REQ_RESULT(req, result);
|
|
231
402
|
}
|
|
232
403
|
|
|
@@ -234,7 +405,7 @@ done:
|
|
|
234
405
|
void fs__stat(uv_fs_t* req, const char* path) {
|
|
235
406
|
int result;
|
|
236
407
|
|
|
237
|
-
result =
|
|
408
|
+
result = _stati64(path, &req->stat);
|
|
238
409
|
if (result == -1) {
|
|
239
410
|
req->ptr = NULL;
|
|
240
411
|
} else {
|
|
@@ -248,7 +419,7 @@ void fs__stat(uv_fs_t* req, const char* path) {
|
|
|
248
419
|
void fs__fstat(uv_fs_t* req, uv_file file) {
|
|
249
420
|
int result;
|
|
250
421
|
|
|
251
|
-
result =
|
|
422
|
+
result = _fstati64(file, &req->stat);
|
|
252
423
|
if (result == -1) {
|
|
253
424
|
req->ptr = NULL;
|
|
254
425
|
} else {
|
|
@@ -267,7 +438,11 @@ void fs__rename(uv_fs_t* req, const char* path, const char* new_path) {
|
|
|
267
438
|
|
|
268
439
|
void fs__fsync(uv_fs_t* req, uv_file file) {
|
|
269
440
|
int result = FlushFileBuffers((HANDLE)_get_osfhandle(file)) ? 0 : -1;
|
|
270
|
-
|
|
441
|
+
if (result == -1) {
|
|
442
|
+
SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
|
|
443
|
+
} else {
|
|
444
|
+
SET_REQ_RESULT(req, result);
|
|
445
|
+
}
|
|
271
446
|
}
|
|
272
447
|
|
|
273
448
|
|
|
@@ -323,6 +498,50 @@ void fs__chmod(uv_fs_t* req, const char* path, int mode) {
|
|
|
323
498
|
}
|
|
324
499
|
|
|
325
500
|
|
|
501
|
+
void fs__fchmod(uv_fs_t* req, uv_file file, int mode) {
|
|
502
|
+
int result;
|
|
503
|
+
HANDLE handle;
|
|
504
|
+
NTSTATUS nt_status;
|
|
505
|
+
IO_STATUS_BLOCK io_status;
|
|
506
|
+
FILE_BASIC_INFORMATION file_info;
|
|
507
|
+
|
|
508
|
+
handle = (HANDLE)_get_osfhandle(file);
|
|
509
|
+
|
|
510
|
+
nt_status = pNtQueryInformationFile(handle,
|
|
511
|
+
&io_status,
|
|
512
|
+
&file_info,
|
|
513
|
+
sizeof file_info,
|
|
514
|
+
FileBasicInformation);
|
|
515
|
+
|
|
516
|
+
if (nt_status != STATUS_SUCCESS) {
|
|
517
|
+
result = -1;
|
|
518
|
+
goto done;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
if (mode & _S_IWRITE) {
|
|
522
|
+
file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
|
|
523
|
+
} else {
|
|
524
|
+
file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
nt_status = pNtSetInformationFile(handle,
|
|
528
|
+
&io_status,
|
|
529
|
+
&file_info,
|
|
530
|
+
sizeof file_info,
|
|
531
|
+
FileBasicInformation);
|
|
532
|
+
|
|
533
|
+
if (nt_status != STATUS_SUCCESS) {
|
|
534
|
+
result = -1;
|
|
535
|
+
goto done;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
result = 0;
|
|
539
|
+
|
|
540
|
+
done:
|
|
541
|
+
SET_REQ_RESULT(req, result);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
|
|
326
545
|
void fs__utime(uv_fs_t* req, const char* path, double atime, double mtime) {
|
|
327
546
|
int result;
|
|
328
547
|
struct _utimbuf b = {(time_t)atime, (time_t)mtime};
|
|
@@ -339,6 +558,144 @@ void fs__futime(uv_fs_t* req, uv_file file, double atime, double mtime) {
|
|
|
339
558
|
}
|
|
340
559
|
|
|
341
560
|
|
|
561
|
+
void fs__link(uv_fs_t* req, const char* path, const char* new_path) {
|
|
562
|
+
int result = CreateHardLinkA(new_path, path, NULL) ? 0 : -1;
|
|
563
|
+
if (result == -1) {
|
|
564
|
+
SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
|
|
565
|
+
} else {
|
|
566
|
+
SET_REQ_RESULT(req, result);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
void fs__symlink(uv_fs_t* req, const char* path, const char* new_path,
|
|
572
|
+
int flags) {
|
|
573
|
+
int result;
|
|
574
|
+
if (pCreateSymbolicLinkA) {
|
|
575
|
+
result = pCreateSymbolicLinkA(new_path,
|
|
576
|
+
path,
|
|
577
|
+
flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1;
|
|
578
|
+
if (result == -1) {
|
|
579
|
+
SET_REQ_LAST_ERROR(req, GetLastError());
|
|
580
|
+
}
|
|
581
|
+
} else {
|
|
582
|
+
result = -1;
|
|
583
|
+
errno = ENOSYS;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
SET_REQ_RESULT(req, result);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
void fs__readlink(uv_fs_t* req, const char* path) {
|
|
591
|
+
int result = -1;
|
|
592
|
+
BOOL rv;
|
|
593
|
+
HANDLE symlink;
|
|
594
|
+
void* buffer = NULL;
|
|
595
|
+
DWORD bytes_returned;
|
|
596
|
+
REPARSE_DATA_BUFFER* reparse_data;
|
|
597
|
+
int utf8size;
|
|
598
|
+
wchar_t* substitute_name;
|
|
599
|
+
int substitute_name_length;
|
|
600
|
+
|
|
601
|
+
symlink = CreateFileA(path,
|
|
602
|
+
0,
|
|
603
|
+
0,
|
|
604
|
+
NULL,
|
|
605
|
+
OPEN_EXISTING,
|
|
606
|
+
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
|
|
607
|
+
NULL);
|
|
608
|
+
|
|
609
|
+
if (INVALID_HANDLE_VALUE == symlink) {
|
|
610
|
+
result = -1;
|
|
611
|
+
SET_REQ_LAST_ERROR(req, GetLastError());
|
|
612
|
+
goto done;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
buffer = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
|
|
616
|
+
if (!buffer) {
|
|
617
|
+
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
rv = DeviceIoControl(symlink,
|
|
621
|
+
FSCTL_GET_REPARSE_POINT,
|
|
622
|
+
NULL,
|
|
623
|
+
0,
|
|
624
|
+
buffer,
|
|
625
|
+
MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
|
|
626
|
+
&bytes_returned,
|
|
627
|
+
NULL);
|
|
628
|
+
|
|
629
|
+
if (!rv) {
|
|
630
|
+
result = -1;
|
|
631
|
+
SET_REQ_LAST_ERROR(req, GetLastError());
|
|
632
|
+
goto done;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
reparse_data = buffer;
|
|
636
|
+
if (reparse_data->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
|
|
637
|
+
result = -1;
|
|
638
|
+
/* something is seriously wrong */
|
|
639
|
+
SET_REQ_LAST_ERROR(req, GetLastError());
|
|
640
|
+
goto done;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
substitute_name = reparse_data->SymbolicLinkReparseBuffer.PathBuffer + (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t));
|
|
644
|
+
substitute_name_length = reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
|
|
645
|
+
|
|
646
|
+
/* Strip off the leading \??\ from the substitute name buffer.*/
|
|
647
|
+
if (memcmp(substitute_name, L"\\??\\", 8) == 0) {
|
|
648
|
+
substitute_name += 4;
|
|
649
|
+
substitute_name_length -= 4;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
utf8size = uv_utf16_to_utf8(substitute_name,
|
|
653
|
+
substitute_name_length,
|
|
654
|
+
NULL,
|
|
655
|
+
0);
|
|
656
|
+
if (!utf8size) {
|
|
657
|
+
result = -1;
|
|
658
|
+
SET_REQ_LAST_ERROR(req, GetLastError());
|
|
659
|
+
goto done;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
req->ptr = malloc(utf8size + 1);
|
|
663
|
+
if (!req->ptr) {
|
|
664
|
+
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
utf8size = uv_utf16_to_utf8(substitute_name,
|
|
668
|
+
substitute_name_length,
|
|
669
|
+
req->ptr,
|
|
670
|
+
utf8size);
|
|
671
|
+
if (!utf8size) {
|
|
672
|
+
result = -1;
|
|
673
|
+
SET_REQ_LAST_ERROR(req, GetLastError());
|
|
674
|
+
goto done;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
req->flags |= UV_FS_FREE_PTR;
|
|
678
|
+
((char*)req->ptr)[utf8size] = '\0';
|
|
679
|
+
result = 0;
|
|
680
|
+
|
|
681
|
+
done:
|
|
682
|
+
if (buffer) {
|
|
683
|
+
free(buffer);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
if (symlink != INVALID_HANDLE_VALUE) {
|
|
687
|
+
CloseHandle(symlink);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
SET_REQ_RESULT(req, result);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
void fs__nop(uv_fs_t* req) {
|
|
695
|
+
req->result = 0;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
|
|
342
699
|
static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
|
|
343
700
|
uv_fs_t* req = (uv_fs_t*) parameter;
|
|
344
701
|
uv_loop_t* loop = req->loop;
|
|
@@ -348,7 +705,7 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
|
|
|
348
705
|
|
|
349
706
|
switch (req->fs_type) {
|
|
350
707
|
case UV_FS_OPEN:
|
|
351
|
-
fs__open(req,
|
|
708
|
+
fs__open(req, req->path, (int)req->arg0, (int)req->arg1);
|
|
352
709
|
break;
|
|
353
710
|
case UV_FS_CLOSE:
|
|
354
711
|
fs__close(req, (uv_file)req->arg0);
|
|
@@ -368,25 +725,26 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
|
|
|
368
725
|
(off_t) req->arg3);
|
|
369
726
|
break;
|
|
370
727
|
case UV_FS_UNLINK:
|
|
371
|
-
fs__unlink(req,
|
|
728
|
+
fs__unlink(req, req->path);
|
|
372
729
|
break;
|
|
373
730
|
case UV_FS_MKDIR:
|
|
374
|
-
fs__mkdir(req,
|
|
731
|
+
fs__mkdir(req, req->path, (int)req->arg0);
|
|
375
732
|
break;
|
|
376
733
|
case UV_FS_RMDIR:
|
|
377
|
-
fs__rmdir(req,
|
|
734
|
+
fs__rmdir(req, req->path);
|
|
378
735
|
break;
|
|
379
736
|
case UV_FS_READDIR:
|
|
380
|
-
fs__readdir(req,
|
|
737
|
+
fs__readdir(req, req->path, (int)req->arg0);
|
|
381
738
|
break;
|
|
382
739
|
case UV_FS_STAT:
|
|
383
|
-
|
|
740
|
+
case UV_FS_LSTAT:
|
|
741
|
+
fs__stat(req, req->path);
|
|
384
742
|
break;
|
|
385
743
|
case UV_FS_FSTAT:
|
|
386
744
|
fs__fstat(req, (uv_file)req->arg0);
|
|
387
745
|
break;
|
|
388
746
|
case UV_FS_RENAME:
|
|
389
|
-
fs__rename(req,
|
|
747
|
+
fs__rename(req, req->path, (const char*)req->arg0);
|
|
390
748
|
break;
|
|
391
749
|
case UV_FS_FSYNC:
|
|
392
750
|
case UV_FS_FDATASYNC:
|
|
@@ -403,14 +761,30 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
|
|
|
403
761
|
(size_t) req->arg3);
|
|
404
762
|
break;
|
|
405
763
|
case UV_FS_CHMOD:
|
|
406
|
-
fs__chmod(req,
|
|
764
|
+
fs__chmod(req, req->path, (int)req->arg0);
|
|
765
|
+
break;
|
|
766
|
+
case UV_FS_FCHMOD:
|
|
767
|
+
fs__fchmod(req, (uv_file)req->arg0, (int)req->arg1);
|
|
407
768
|
break;
|
|
408
769
|
case UV_FS_UTIME:
|
|
409
|
-
fs__utime(req,
|
|
770
|
+
fs__utime(req, req->path, req->arg4, req->arg5);
|
|
410
771
|
break;
|
|
411
772
|
case UV_FS_FUTIME:
|
|
412
773
|
fs__futime(req, (uv_file)req->arg0, req->arg4, req->arg5);
|
|
413
774
|
break;
|
|
775
|
+
case UV_FS_LINK:
|
|
776
|
+
fs__link(req, req->path, (const char*)req->arg0);
|
|
777
|
+
break;
|
|
778
|
+
case UV_FS_SYMLINK:
|
|
779
|
+
fs__symlink(req, req->path, (const char*)req->arg0, (int)req->arg1);
|
|
780
|
+
break;
|
|
781
|
+
case UV_FS_READLINK:
|
|
782
|
+
fs__readlink(req, req->path);
|
|
783
|
+
break;
|
|
784
|
+
case UV_FS_CHOWN:
|
|
785
|
+
case UV_FS_FCHOWN:
|
|
786
|
+
fs__nop(req);
|
|
787
|
+
break;
|
|
414
788
|
default:
|
|
415
789
|
assert(!"bad uv_fs_type");
|
|
416
790
|
}
|
|
@@ -424,13 +798,14 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
|
|
|
424
798
|
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
|
425
799
|
int mode, uv_fs_cb cb) {
|
|
426
800
|
if (cb) {
|
|
427
|
-
uv_fs_req_init_async(loop, req, UV_FS_OPEN, cb);
|
|
428
|
-
|
|
429
|
-
STRDUP_ARG(req, 0);
|
|
801
|
+
uv_fs_req_init_async(loop, req, UV_FS_OPEN, path, cb);
|
|
802
|
+
WRAP_REQ_ARGS2(req, flags, mode);
|
|
430
803
|
QUEUE_FS_TP_JOB(loop, req);
|
|
431
804
|
} else {
|
|
432
805
|
uv_fs_req_init_sync(loop, req, UV_FS_OPEN);
|
|
433
806
|
fs__open(req, path, flags, mode);
|
|
807
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
808
|
+
return req->result;
|
|
434
809
|
}
|
|
435
810
|
|
|
436
811
|
return 0;
|
|
@@ -439,12 +814,14 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
|
|
439
814
|
|
|
440
815
|
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
441
816
|
if (cb) {
|
|
442
|
-
uv_fs_req_init_async(loop, req, UV_FS_CLOSE, cb);
|
|
817
|
+
uv_fs_req_init_async(loop, req, UV_FS_CLOSE, NULL, cb);
|
|
443
818
|
WRAP_REQ_ARGS1(req, file);
|
|
444
819
|
QUEUE_FS_TP_JOB(loop, req);
|
|
445
820
|
} else {
|
|
446
821
|
uv_fs_req_init_sync(loop, req, UV_FS_CLOSE);
|
|
447
822
|
fs__close(req, file);
|
|
823
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
824
|
+
return req->result;
|
|
448
825
|
}
|
|
449
826
|
|
|
450
827
|
return 0;
|
|
@@ -454,12 +831,14 @@ int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
|
454
831
|
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
|
|
455
832
|
size_t length, off_t offset, uv_fs_cb cb) {
|
|
456
833
|
if (cb) {
|
|
457
|
-
uv_fs_req_init_async(loop, req, UV_FS_READ, cb);
|
|
834
|
+
uv_fs_req_init_async(loop, req, UV_FS_READ, NULL, cb);
|
|
458
835
|
WRAP_REQ_ARGS4(req, file, buf, length, offset);
|
|
459
836
|
QUEUE_FS_TP_JOB(loop, req);
|
|
460
837
|
} else {
|
|
461
838
|
uv_fs_req_init_sync(loop, req, UV_FS_READ);
|
|
462
839
|
fs__read(req, file, buf, length, offset);
|
|
840
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
841
|
+
return req->result;
|
|
463
842
|
}
|
|
464
843
|
|
|
465
844
|
return 0;
|
|
@@ -469,12 +848,14 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
|
|
|
469
848
|
int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
|
|
470
849
|
size_t length, off_t offset, uv_fs_cb cb) {
|
|
471
850
|
if (cb) {
|
|
472
|
-
uv_fs_req_init_async(loop, req, UV_FS_WRITE, cb);
|
|
851
|
+
uv_fs_req_init_async(loop, req, UV_FS_WRITE, NULL, cb);
|
|
473
852
|
WRAP_REQ_ARGS4(req, file, buf, length, offset);
|
|
474
853
|
QUEUE_FS_TP_JOB(loop, req);
|
|
475
854
|
} else {
|
|
476
855
|
uv_fs_req_init_sync(loop, req, UV_FS_WRITE);
|
|
477
856
|
fs__write(req, file, buf, length, offset);
|
|
857
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
858
|
+
return req->result;
|
|
478
859
|
}
|
|
479
860
|
|
|
480
861
|
return 0;
|
|
@@ -484,13 +865,13 @@ int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
|
|
|
484
865
|
int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
|
485
866
|
uv_fs_cb cb) {
|
|
486
867
|
if (cb) {
|
|
487
|
-
uv_fs_req_init_async(loop, req, UV_FS_UNLINK, cb);
|
|
488
|
-
WRAP_REQ_ARGS1(req, path);
|
|
489
|
-
STRDUP_ARG(req, 0);
|
|
868
|
+
uv_fs_req_init_async(loop, req, UV_FS_UNLINK, path, cb);
|
|
490
869
|
QUEUE_FS_TP_JOB(loop, req);
|
|
491
870
|
} else {
|
|
492
871
|
uv_fs_req_init_sync(loop, req, UV_FS_UNLINK);
|
|
493
872
|
fs__unlink(req, path);
|
|
873
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
874
|
+
return req->result;
|
|
494
875
|
}
|
|
495
876
|
|
|
496
877
|
return 0;
|
|
@@ -500,13 +881,14 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
|
|
500
881
|
int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
|
|
501
882
|
uv_fs_cb cb) {
|
|
502
883
|
if (cb) {
|
|
503
|
-
uv_fs_req_init_async(loop, req, UV_FS_MKDIR, cb);
|
|
504
|
-
|
|
505
|
-
STRDUP_ARG(req, 0);
|
|
884
|
+
uv_fs_req_init_async(loop, req, UV_FS_MKDIR, path, cb);
|
|
885
|
+
WRAP_REQ_ARGS1(req, mode);
|
|
506
886
|
QUEUE_FS_TP_JOB(loop, req);
|
|
507
887
|
} else {
|
|
508
888
|
uv_fs_req_init_sync(loop, req, UV_FS_MKDIR);
|
|
509
889
|
fs__mkdir(req, path, mode);
|
|
890
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
891
|
+
return req->result;
|
|
510
892
|
}
|
|
511
893
|
|
|
512
894
|
return 0;
|
|
@@ -515,13 +897,13 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
|
|
|
515
897
|
|
|
516
898
|
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
517
899
|
if (cb) {
|
|
518
|
-
uv_fs_req_init_async(loop, req, UV_FS_RMDIR, cb);
|
|
519
|
-
WRAP_REQ_ARGS1(req, path);
|
|
520
|
-
STRDUP_ARG(req, 0);
|
|
900
|
+
uv_fs_req_init_async(loop, req, UV_FS_RMDIR, path, cb);
|
|
521
901
|
QUEUE_FS_TP_JOB(loop, req);
|
|
522
902
|
} else {
|
|
523
903
|
uv_fs_req_init_sync(loop, req, UV_FS_RMDIR);
|
|
524
904
|
fs__rmdir(req, path);
|
|
905
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
906
|
+
return req->result;
|
|
525
907
|
}
|
|
526
908
|
|
|
527
909
|
return 0;
|
|
@@ -531,65 +913,103 @@ int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
|
531
913
|
int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
|
532
914
|
uv_fs_cb cb) {
|
|
533
915
|
if (cb) {
|
|
534
|
-
uv_fs_req_init_async(loop, req, UV_FS_READDIR, cb);
|
|
535
|
-
|
|
536
|
-
STRDUP_ARG(req, 0);
|
|
916
|
+
uv_fs_req_init_async(loop, req, UV_FS_READDIR, path, cb);
|
|
917
|
+
WRAP_REQ_ARGS1(req, flags);
|
|
537
918
|
QUEUE_FS_TP_JOB(loop, req);
|
|
538
919
|
} else {
|
|
539
920
|
uv_fs_req_init_sync(loop, req, UV_FS_READDIR);
|
|
540
921
|
fs__readdir(req, path, flags);
|
|
922
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
923
|
+
return req->result;
|
|
541
924
|
}
|
|
542
925
|
|
|
543
926
|
return 0;
|
|
544
927
|
}
|
|
545
928
|
|
|
546
929
|
|
|
547
|
-
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
548
|
-
assert(0 && "implement me");
|
|
549
|
-
return -1;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
// uv_fs_readlink, uv_fs_fchmod, uv_fs_chown, uv_fs_fchown
|
|
554
930
|
int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
|
555
931
|
const char* new_path, uv_fs_cb cb) {
|
|
556
|
-
|
|
557
|
-
|
|
932
|
+
if (cb) {
|
|
933
|
+
uv_fs_req_init_async(loop, req, UV_FS_LINK, path, cb);
|
|
934
|
+
WRAP_REQ_ARGS1(req, new_path);
|
|
935
|
+
STRDUP_ARG(req, 0);
|
|
936
|
+
QUEUE_FS_TP_JOB(loop, req);
|
|
937
|
+
} else {
|
|
938
|
+
uv_fs_req_init_sync(loop, req, UV_FS_LINK);
|
|
939
|
+
fs__link(req, path, new_path);
|
|
940
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
941
|
+
return req->result;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
return 0;
|
|
558
945
|
}
|
|
559
946
|
|
|
560
947
|
|
|
561
948
|
int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
|
562
|
-
const char* new_path, uv_fs_cb cb) {
|
|
563
|
-
|
|
564
|
-
|
|
949
|
+
const char* new_path, int flags, uv_fs_cb cb) {
|
|
950
|
+
if (cb) {
|
|
951
|
+
uv_fs_req_init_async(loop, req, UV_FS_SYMLINK, path, cb);
|
|
952
|
+
WRAP_REQ_ARGS2(req, new_path, flags);
|
|
953
|
+
STRDUP_ARG(req, 0);
|
|
954
|
+
QUEUE_FS_TP_JOB(loop, req);
|
|
955
|
+
} else {
|
|
956
|
+
uv_fs_req_init_sync(loop, req, UV_FS_SYMLINK);
|
|
957
|
+
fs__symlink(req, path, new_path, flags);
|
|
958
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
959
|
+
return req->result;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
return 0;
|
|
565
963
|
}
|
|
566
964
|
|
|
567
965
|
|
|
568
966
|
int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
|
569
967
|
uv_fs_cb cb) {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
968
|
+
if (cb) {
|
|
969
|
+
uv_fs_req_init_async(loop, req, UV_FS_READLINK, path, cb);
|
|
970
|
+
QUEUE_FS_TP_JOB(loop, req);
|
|
971
|
+
} else {
|
|
972
|
+
uv_fs_req_init_sync(loop, req, UV_FS_READLINK);
|
|
973
|
+
fs__readlink(req, path);
|
|
974
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
975
|
+
return req->result;
|
|
976
|
+
}
|
|
574
977
|
|
|
575
|
-
|
|
576
|
-
uv_fs_cb cb) {
|
|
577
|
-
assert(0 && "implement me");
|
|
578
|
-
return -1;
|
|
978
|
+
return 0;
|
|
579
979
|
}
|
|
580
980
|
|
|
581
981
|
|
|
582
982
|
int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
|
|
583
983
|
int gid, uv_fs_cb cb) {
|
|
584
|
-
|
|
585
|
-
|
|
984
|
+
if (cb) {
|
|
985
|
+
uv_fs_req_init_async(loop, req, UV_FS_CHOWN, path, cb);
|
|
986
|
+
WRAP_REQ_ARGS2(req, uid, gid);
|
|
987
|
+
QUEUE_FS_TP_JOB(loop, req);
|
|
988
|
+
} else {
|
|
989
|
+
uv_fs_req_init_sync(loop, req, UV_FS_CHOWN);
|
|
990
|
+
fs__nop(req);
|
|
991
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
992
|
+
return req->result;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
return 0;
|
|
586
996
|
}
|
|
587
997
|
|
|
588
998
|
|
|
589
999
|
int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid,
|
|
590
1000
|
int gid, uv_fs_cb cb) {
|
|
591
|
-
|
|
592
|
-
|
|
1001
|
+
if (cb) {
|
|
1002
|
+
uv_fs_req_init_async(loop, req, UV_FS_FCHOWN, NULL, cb);
|
|
1003
|
+
WRAP_REQ_ARGS3(req, file, uid, gid);
|
|
1004
|
+
QUEUE_FS_TP_JOB(loop, req);
|
|
1005
|
+
} else {
|
|
1006
|
+
uv_fs_req_init_sync(loop, req, UV_FS_FCHOWN);
|
|
1007
|
+
fs__nop(req);
|
|
1008
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1009
|
+
return req->result;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
return 0;
|
|
593
1013
|
}
|
|
594
1014
|
|
|
595
1015
|
|
|
@@ -608,13 +1028,11 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
|
608
1028
|
}
|
|
609
1029
|
|
|
610
1030
|
if (cb) {
|
|
611
|
-
uv_fs_req_init_async(loop, req, UV_FS_STAT, cb);
|
|
1031
|
+
uv_fs_req_init_async(loop, req, UV_FS_STAT, NULL, cb);
|
|
612
1032
|
if (path2) {
|
|
613
|
-
|
|
614
|
-
req->flags |= UV_FS_FREE_ARG0;
|
|
1033
|
+
req->path = path2;
|
|
615
1034
|
} else {
|
|
616
|
-
|
|
617
|
-
STRDUP_ARG(req, 0);
|
|
1035
|
+
req->path = strdup(path);
|
|
618
1036
|
}
|
|
619
1037
|
|
|
620
1038
|
QUEUE_FS_TP_JOB(loop, req);
|
|
@@ -624,6 +1042,46 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
|
624
1042
|
if (path2) {
|
|
625
1043
|
free(path2);
|
|
626
1044
|
}
|
|
1045
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1046
|
+
return req->result;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
return 0;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
/* TODO: add support for links. */
|
|
1054
|
+
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
1055
|
+
int len = strlen(path);
|
|
1056
|
+
char* path2 = NULL;
|
|
1057
|
+
int has_backslash = (path[len - 1] == '\\' || path[len - 1] == '/');
|
|
1058
|
+
|
|
1059
|
+
if (path[len - 1] == '\\' || path[len - 1] == '/') {
|
|
1060
|
+
path2 = strdup(path);
|
|
1061
|
+
if (!path2) {
|
|
1062
|
+
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
path2[len - 1] = '\0';
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
if (cb) {
|
|
1069
|
+
uv_fs_req_init_async(loop, req, UV_FS_LSTAT, NULL, cb);
|
|
1070
|
+
if (path2) {
|
|
1071
|
+
req->path = path2;
|
|
1072
|
+
} else {
|
|
1073
|
+
req->path = strdup(path);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
QUEUE_FS_TP_JOB(loop, req);
|
|
1077
|
+
} else {
|
|
1078
|
+
uv_fs_req_init_sync(loop, req, UV_FS_LSTAT);
|
|
1079
|
+
fs__stat(req, path2 ? path2 : path);
|
|
1080
|
+
if (path2) {
|
|
1081
|
+
free(path2);
|
|
1082
|
+
}
|
|
1083
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1084
|
+
return req->result;
|
|
627
1085
|
}
|
|
628
1086
|
|
|
629
1087
|
return 0;
|
|
@@ -632,12 +1090,14 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
|
632
1090
|
|
|
633
1091
|
int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
634
1092
|
if (cb) {
|
|
635
|
-
uv_fs_req_init_async(loop, req, UV_FS_FSTAT, cb);
|
|
1093
|
+
uv_fs_req_init_async(loop, req, UV_FS_FSTAT, NULL, cb);
|
|
636
1094
|
WRAP_REQ_ARGS1(req, file);
|
|
637
1095
|
QUEUE_FS_TP_JOB(loop, req);
|
|
638
1096
|
} else {
|
|
639
1097
|
uv_fs_req_init_sync(loop, req, UV_FS_FSTAT);
|
|
640
1098
|
fs__fstat(req, file);
|
|
1099
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1100
|
+
return req->result;
|
|
641
1101
|
}
|
|
642
1102
|
|
|
643
1103
|
return 0;
|
|
@@ -647,14 +1107,15 @@ int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
|
647
1107
|
int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
|
648
1108
|
const char* new_path, uv_fs_cb cb) {
|
|
649
1109
|
if (cb) {
|
|
650
|
-
uv_fs_req_init_async(loop, req, UV_FS_RENAME, cb);
|
|
651
|
-
|
|
1110
|
+
uv_fs_req_init_async(loop, req, UV_FS_RENAME, path, cb);
|
|
1111
|
+
WRAP_REQ_ARGS1(req, new_path);
|
|
652
1112
|
STRDUP_ARG(req, 0);
|
|
653
|
-
STRDUP_ARG(req, 1);
|
|
654
1113
|
QUEUE_FS_TP_JOB(loop, req);
|
|
655
1114
|
} else {
|
|
656
1115
|
uv_fs_req_init_sync(loop, req, UV_FS_RENAME);
|
|
657
1116
|
fs__rename(req, path, new_path);
|
|
1117
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1118
|
+
return req->result;
|
|
658
1119
|
}
|
|
659
1120
|
|
|
660
1121
|
return 0;
|
|
@@ -663,12 +1124,14 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
|
|
663
1124
|
|
|
664
1125
|
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
665
1126
|
if (cb) {
|
|
666
|
-
uv_fs_req_init_async(loop, req, UV_FS_FDATASYNC, cb);
|
|
1127
|
+
uv_fs_req_init_async(loop, req, UV_FS_FDATASYNC, NULL, cb);
|
|
667
1128
|
WRAP_REQ_ARGS1(req, file);
|
|
668
1129
|
QUEUE_FS_TP_JOB(loop, req);
|
|
669
1130
|
} else {
|
|
670
1131
|
uv_fs_req_init_sync(loop, req, UV_FS_FDATASYNC);
|
|
671
1132
|
fs__fsync(req, file);
|
|
1133
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1134
|
+
return req->result;
|
|
672
1135
|
}
|
|
673
1136
|
|
|
674
1137
|
return 0;
|
|
@@ -677,12 +1140,14 @@ int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
|
677
1140
|
|
|
678
1141
|
int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
679
1142
|
if (cb) {
|
|
680
|
-
uv_fs_req_init_async(loop, req, UV_FS_FSYNC, cb);
|
|
1143
|
+
uv_fs_req_init_async(loop, req, UV_FS_FSYNC, NULL, cb);
|
|
681
1144
|
WRAP_REQ_ARGS1(req, file);
|
|
682
1145
|
QUEUE_FS_TP_JOB(loop, req);
|
|
683
1146
|
} else {
|
|
684
1147
|
uv_fs_req_init_sync(loop, req, UV_FS_FSYNC);
|
|
685
1148
|
fs__fsync(req, file);
|
|
1149
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1150
|
+
return req->result;
|
|
686
1151
|
}
|
|
687
1152
|
|
|
688
1153
|
return 0;
|
|
@@ -692,12 +1157,14 @@ int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
|
692
1157
|
int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
|
|
693
1158
|
off_t offset, uv_fs_cb cb) {
|
|
694
1159
|
if (cb) {
|
|
695
|
-
uv_fs_req_init_async(loop, req, UV_FS_FTRUNCATE, cb);
|
|
1160
|
+
uv_fs_req_init_async(loop, req, UV_FS_FTRUNCATE, NULL, cb);
|
|
696
1161
|
WRAP_REQ_ARGS2(req, file, offset);
|
|
697
1162
|
QUEUE_FS_TP_JOB(loop, req);
|
|
698
1163
|
} else {
|
|
699
1164
|
uv_fs_req_init_sync(loop, req, UV_FS_FTRUNCATE);
|
|
700
1165
|
fs__ftruncate(req, file, offset);
|
|
1166
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1167
|
+
return req->result;
|
|
701
1168
|
}
|
|
702
1169
|
|
|
703
1170
|
return 0;
|
|
@@ -707,12 +1174,14 @@ int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
|
|
|
707
1174
|
int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
|
|
708
1175
|
uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb) {
|
|
709
1176
|
if (cb) {
|
|
710
|
-
uv_fs_req_init_async(loop, req, UV_FS_SENDFILE, cb);
|
|
1177
|
+
uv_fs_req_init_async(loop, req, UV_FS_SENDFILE, NULL, cb);
|
|
711
1178
|
WRAP_REQ_ARGS4(req, out_fd, in_fd, in_offset, length);
|
|
712
1179
|
QUEUE_FS_TP_JOB(loop, req);
|
|
713
1180
|
} else {
|
|
714
1181
|
uv_fs_req_init_sync(loop, req, UV_FS_SENDFILE);
|
|
715
1182
|
fs__sendfile(req, out_fd, in_fd, in_offset, length);
|
|
1183
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1184
|
+
return req->result;
|
|
716
1185
|
}
|
|
717
1186
|
|
|
718
1187
|
return 0;
|
|
@@ -722,13 +1191,31 @@ int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
|
|
|
722
1191
|
int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
|
|
723
1192
|
uv_fs_cb cb) {
|
|
724
1193
|
if (cb) {
|
|
725
|
-
uv_fs_req_init_async(loop, req, UV_FS_CHMOD, cb);
|
|
726
|
-
|
|
727
|
-
STRDUP_ARG(req, 0);
|
|
1194
|
+
uv_fs_req_init_async(loop, req, UV_FS_CHMOD, path, cb);
|
|
1195
|
+
WRAP_REQ_ARGS1(req, mode);
|
|
728
1196
|
QUEUE_FS_TP_JOB(loop, req);
|
|
729
1197
|
} else {
|
|
730
1198
|
uv_fs_req_init_sync(loop, req, UV_FS_CHMOD);
|
|
731
1199
|
fs__chmod(req, path, mode);
|
|
1200
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1201
|
+
return req->result;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
return 0;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
|
|
1209
|
+
uv_fs_cb cb) {
|
|
1210
|
+
if (cb) {
|
|
1211
|
+
uv_fs_req_init_async(loop, req, UV_FS_FCHMOD, NULL, cb);
|
|
1212
|
+
WRAP_REQ_ARGS2(req, file, mode);
|
|
1213
|
+
QUEUE_FS_TP_JOB(loop, req);
|
|
1214
|
+
} else {
|
|
1215
|
+
uv_fs_req_init_sync(loop, req, UV_FS_FCHMOD);
|
|
1216
|
+
fs__fchmod(req, file, mode);
|
|
1217
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1218
|
+
return req->result;
|
|
732
1219
|
}
|
|
733
1220
|
|
|
734
1221
|
return 0;
|
|
@@ -738,15 +1225,15 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
|
|
|
738
1225
|
int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
|
|
739
1226
|
double mtime, uv_fs_cb cb) {
|
|
740
1227
|
if (cb) {
|
|
741
|
-
uv_fs_req_init_async(loop, req, UV_FS_UTIME, cb);
|
|
742
|
-
WRAP_REQ_ARGS1(req, path);
|
|
743
|
-
STRDUP_ARG(req, 0);
|
|
1228
|
+
uv_fs_req_init_async(loop, req, UV_FS_UTIME, path, cb);
|
|
744
1229
|
req->arg4 = (ssize_t)atime;
|
|
745
1230
|
req->arg5 = (ssize_t)mtime;
|
|
746
1231
|
QUEUE_FS_TP_JOB(loop, req);
|
|
747
1232
|
} else {
|
|
748
1233
|
uv_fs_req_init_sync(loop, req, UV_FS_UTIME);
|
|
749
1234
|
fs__utime(req, path, atime, mtime);
|
|
1235
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1236
|
+
return req->result;
|
|
750
1237
|
}
|
|
751
1238
|
|
|
752
1239
|
return 0;
|
|
@@ -756,7 +1243,7 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
|
|
|
756
1243
|
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
|
|
757
1244
|
double mtime, uv_fs_cb cb) {
|
|
758
1245
|
if (cb) {
|
|
759
|
-
uv_fs_req_init_async(loop, req, UV_FS_FUTIME, cb);
|
|
1246
|
+
uv_fs_req_init_async(loop, req, UV_FS_FUTIME, NULL, cb);
|
|
760
1247
|
WRAP_REQ_ARGS1(req, file);
|
|
761
1248
|
req->arg4 = (ssize_t)atime;
|
|
762
1249
|
req->arg5 = (ssize_t)mtime;
|
|
@@ -764,6 +1251,8 @@ int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
|
|
|
764
1251
|
} else {
|
|
765
1252
|
uv_fs_req_init_sync(loop, req, UV_FS_FUTIME);
|
|
766
1253
|
fs__futime(req, file, atime, mtime);
|
|
1254
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
1255
|
+
return req->result;
|
|
767
1256
|
}
|
|
768
1257
|
|
|
769
1258
|
return 0;
|
|
@@ -772,6 +1261,7 @@ int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
|
|
|
772
1261
|
|
|
773
1262
|
void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req) {
|
|
774
1263
|
assert(req->cb);
|
|
1264
|
+
SET_UV_LAST_ERROR_FROM_REQ(req);
|
|
775
1265
|
req->cb(req);
|
|
776
1266
|
}
|
|
777
1267
|
|
|
@@ -799,6 +1289,11 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
|
|
|
799
1289
|
|
|
800
1290
|
req->ptr = NULL;
|
|
801
1291
|
|
|
1292
|
+
if (req->path) {
|
|
1293
|
+
free(req->path);
|
|
1294
|
+
req->path = NULL;
|
|
1295
|
+
}
|
|
1296
|
+
|
|
802
1297
|
if (req->flags & UV_FS_ASYNC_QUEUED) {
|
|
803
1298
|
uv_unref(loop);
|
|
804
1299
|
}
|