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.
Files changed (84) hide show
  1. data/ext/noderb_extension/extconf.rb +4 -2
  2. data/ext/noderb_extension/libuv/AUTHORS +2 -0
  3. data/ext/noderb_extension/libuv/Makefile +1 -1
  4. data/ext/noderb_extension/libuv/common.gypi +51 -51
  5. data/ext/noderb_extension/libuv/config-mingw.mk +3 -9
  6. data/ext/noderb_extension/libuv/config-unix.mk +10 -1
  7. data/ext/noderb_extension/libuv/include/uv-private/uv-unix.h +3 -2
  8. data/ext/noderb_extension/libuv/include/uv-private/uv-win.h +7 -6
  9. data/ext/noderb_extension/libuv/include/uv.h +47 -13
  10. data/ext/noderb_extension/libuv/src/ares/config_netbsd/ares_config.h +510 -0
  11. data/ext/noderb_extension/libuv/src/unix/core.c +20 -65
  12. data/ext/noderb_extension/libuv/src/unix/darwin.c +1 -0
  13. data/ext/noderb_extension/libuv/src/unix/eio/config_netbsd.h +81 -0
  14. data/ext/noderb_extension/libuv/src/unix/error.c +9 -1
  15. data/ext/noderb_extension/libuv/src/unix/ev/config_netbsd.h +120 -0
  16. data/ext/noderb_extension/libuv/src/unix/fs.c +151 -21
  17. data/ext/noderb_extension/libuv/src/unix/internal.h +30 -0
  18. data/ext/noderb_extension/libuv/src/unix/netbsd.c +68 -0
  19. data/ext/noderb_extension/libuv/src/unix/pipe.c +20 -30
  20. data/ext/noderb_extension/libuv/src/unix/process.c +13 -0
  21. data/ext/noderb_extension/libuv/src/unix/stream.c +105 -63
  22. data/ext/noderb_extension/libuv/src/unix/tcp.c +75 -21
  23. data/ext/noderb_extension/libuv/src/unix/tty.c +69 -0
  24. data/ext/noderb_extension/libuv/src/unix/udp.c +31 -0
  25. data/ext/noderb_extension/libuv/src/uv-common.c +2 -0
  26. data/ext/noderb_extension/libuv/src/uv-common.h +0 -6
  27. data/ext/noderb_extension/libuv/src/win/cares.c +7 -7
  28. data/ext/noderb_extension/libuv/src/win/core.c +25 -17
  29. data/ext/noderb_extension/libuv/src/win/error.c +7 -0
  30. data/ext/noderb_extension/libuv/src/win/fs.c +587 -92
  31. data/ext/noderb_extension/libuv/src/win/getaddrinfo.c +3 -1
  32. data/ext/noderb_extension/libuv/src/win/handle.c +0 -17
  33. data/ext/noderb_extension/libuv/src/win/internal.h +15 -5
  34. data/ext/noderb_extension/libuv/src/win/loop-watcher.c +1 -1
  35. data/ext/noderb_extension/libuv/src/win/pipe.c +6 -0
  36. data/ext/noderb_extension/libuv/src/win/process.c +90 -43
  37. data/ext/noderb_extension/libuv/src/win/tcp.c +37 -4
  38. data/ext/noderb_extension/libuv/src/win/threads.c +81 -0
  39. data/ext/noderb_extension/libuv/src/win/timer.c +15 -15
  40. data/ext/noderb_extension/libuv/src/win/tty.c +37 -0
  41. data/ext/noderb_extension/libuv/src/win/udp.c +8 -2
  42. data/ext/noderb_extension/libuv/src/win/winapi.c +12 -0
  43. data/ext/noderb_extension/libuv/src/win/winapi.h +1146 -1015
  44. data/ext/noderb_extension/libuv/test/benchmark-ares.c +0 -1
  45. data/ext/noderb_extension/libuv/test/benchmark-getaddrinfo.c +0 -1
  46. data/ext/noderb_extension/libuv/test/benchmark-ping-pongs.c +0 -1
  47. data/ext/noderb_extension/libuv/test/benchmark-pound.c +0 -1
  48. data/ext/noderb_extension/libuv/test/benchmark-pump.c +4 -6
  49. data/ext/noderb_extension/libuv/test/benchmark-spawn.c +0 -1
  50. data/ext/noderb_extension/libuv/test/benchmark-udp-packet-storm.c +0 -1
  51. data/ext/noderb_extension/libuv/test/dns-server.c +2 -2
  52. data/ext/noderb_extension/libuv/test/echo-server.c +4 -5
  53. data/ext/noderb_extension/libuv/test/run-tests.c +0 -2
  54. data/ext/noderb_extension/libuv/test/test-async.c +0 -2
  55. data/ext/noderb_extension/libuv/test/test-callback-stack.c +0 -2
  56. data/ext/noderb_extension/libuv/test/test-connection-fail.c +3 -5
  57. data/ext/noderb_extension/libuv/test/test-delayed-accept.c +2 -3
  58. data/ext/noderb_extension/libuv/test/test-fs.c +578 -42
  59. data/ext/noderb_extension/libuv/test/test-get-currentexe.c +12 -2
  60. data/ext/noderb_extension/libuv/test/test-getaddrinfo.c +10 -5
  61. data/ext/noderb_extension/libuv/test/test-gethostbyname.c +0 -2
  62. data/ext/noderb_extension/libuv/test/test-getsockname.c +92 -72
  63. data/ext/noderb_extension/libuv/test/test-idle.c +0 -3
  64. data/ext/noderb_extension/libuv/test/test-list.h +13 -0
  65. data/ext/noderb_extension/libuv/test/test-loop-handles.c +0 -3
  66. data/ext/noderb_extension/libuv/test/test-ping-pong.c +13 -19
  67. data/ext/noderb_extension/libuv/test/test-pipe-bind-error.c +0 -12
  68. data/ext/noderb_extension/libuv/test/test-ref.c +0 -7
  69. data/ext/noderb_extension/libuv/test/test-shutdown-eof.c +3 -3
  70. data/ext/noderb_extension/libuv/test/test-spawn.c +2 -11
  71. data/ext/noderb_extension/libuv/test/test-tcp-bind-error.c +0 -19
  72. data/ext/noderb_extension/libuv/test/test-tcp-bind6-error.c +0 -15
  73. data/ext/noderb_extension/libuv/test/test-tcp-close.c +129 -0
  74. data/ext/noderb_extension/libuv/test/test-tcp-writealot.c +0 -3
  75. data/ext/noderb_extension/libuv/test/test-threadpool.c +0 -2
  76. data/ext/noderb_extension/libuv/test/test-timer-again.c +0 -3
  77. data/ext/noderb_extension/libuv/test/test-timer.c +0 -2
  78. data/ext/noderb_extension/libuv/test/test-udp-dgram-too-big.c +0 -2
  79. data/ext/noderb_extension/libuv/test/test-udp-ipv6.c +0 -2
  80. data/ext/noderb_extension/libuv/test/test-udp-send-and-recv.c +0 -2
  81. data/ext/noderb_extension/libuv/uv.gyp +18 -2
  82. data/ext/noderb_extension/noderb_fs.c +1 -2
  83. data/lib/noderb/version.rb +1 -1
  84. metadata +10 -2
@@ -18,10 +18,6 @@
18
18
  * IN THE SOFTWARE.
19
19
  */
20
20
 
21
- #ifndef _GNU_SOURCE
22
- #define _GNU_SOURCE /* O_CLOEXEC, accept4(), etc. */
23
- #endif
24
-
25
21
  #include "uv.h"
26
22
  #include "unix/internal.h"
27
23
 
@@ -42,26 +38,6 @@
42
38
  #include <limits.h> /* PATH_MAX */
43
39
  #include <sys/uio.h> /* writev */
44
40
 
45
- #if defined(__linux__)
46
-
47
- #include <linux/version.h>
48
- #include <features.h>
49
-
50
- #undef HAVE_PIPE2
51
- #undef HAVE_ACCEPT4
52
-
53
- /* pipe2() requires linux >= 2.6.27 and glibc >= 2.9 */
54
- #if LINUX_VERSION_CODE >= 0x2061B && __GLIBC_PREREQ(2, 9)
55
- #define HAVE_PIPE2
56
- #endif
57
-
58
- /* accept4() requires linux >= 2.6.28 and glib >= 2.10 */
59
- #if LINUX_VERSION_CODE >= 0x2061C && __GLIBC_PREREQ(2, 10)
60
- #define HAVE_ACCEPT4
61
- #endif
62
-
63
- #endif /* __linux__ */
64
-
65
41
  #ifdef __sun
66
42
  # include <sys/types.h>
67
43
  # include <sys/wait.h>
@@ -89,17 +65,6 @@ static void uv__finish_close(uv_handle_t* handle);
89
65
  #endif
90
66
 
91
67
 
92
- void uv_init() {
93
- default_loop_ptr = &default_loop_struct;
94
- #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
95
- default_loop_struct.ev = ev_default_loop(EVBACKEND_KQUEUE);
96
- #else
97
- default_loop_struct.ev = ev_default_loop(EVFLAG_AUTO);
98
- #endif
99
- ev_set_userdata(default_loop_struct.ev, default_loop_ptr);
100
- }
101
-
102
-
103
68
  void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
104
69
  uv_udp_t* udp;
105
70
  uv_async_t* async;
@@ -200,6 +165,15 @@ void uv_loop_delete(uv_loop_t* loop) {
200
165
 
201
166
 
202
167
  uv_loop_t* uv_default_loop() {
168
+ if (!default_loop_ptr) {
169
+ default_loop_ptr = &default_loop_struct;
170
+ #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
171
+ default_loop_struct.ev = ev_default_loop(EVBACKEND_KQUEUE);
172
+ #else
173
+ default_loop_struct.ev = ev_default_loop(EVFLAG_AUTO);
174
+ #endif
175
+ ev_set_userdata(default_loop_struct.ev, default_loop_ptr);
176
+ }
203
177
  assert(default_loop_ptr->ev == EV_DEFAULT_UC);
204
178
  return default_loop_ptr;
205
179
  }
@@ -259,6 +233,8 @@ void uv__finish_close(uv_handle_t* handle) {
259
233
  case UV_TCP:
260
234
  assert(!ev_is_active(&((uv_stream_t*)handle)->read_watcher));
261
235
  assert(!ev_is_active(&((uv_stream_t*)handle)->write_watcher));
236
+ assert(((uv_stream_t*)handle)->fd == -1);
237
+ uv__stream_destroy((uv_stream_t*)handle);
262
238
  break;
263
239
 
264
240
  case UV_UDP:
@@ -300,27 +276,6 @@ void uv__next(EV_P_ ev_idle* watcher, int revents) {
300
276
  }
301
277
 
302
278
 
303
- int uv_getsockname(uv_handle_t* handle, struct sockaddr* name, int* namelen) {
304
- socklen_t socklen;
305
- int saved_errno;
306
-
307
- /* Don't clobber errno. */
308
- saved_errno = errno;
309
-
310
- /* sizeof(socklen_t) != sizeof(int) on some systems. */
311
- socklen = (socklen_t)*namelen;
312
-
313
- if (getsockname(handle->fd, name, &socklen) == -1) {
314
- uv_err_new(handle->loop, errno);
315
- } else {
316
- *namelen = (int)socklen;
317
- }
318
-
319
- errno = saved_errno;
320
- return 0;
321
- }
322
-
323
-
324
279
  void uv_ref(uv_loop_t* loop) {
325
280
  ev_ref(loop->ev);
326
281
  }
@@ -344,7 +299,6 @@ int64_t uv_now(uv_loop_t* loop) {
344
299
  void uv__req_init(uv_req_t* req) {
345
300
  /* loop->counters.req_init++; */
346
301
  req->type = UV_UNKNOWN_REQ;
347
- req->data = NULL;
348
302
  }
349
303
 
350
304
 
@@ -653,7 +607,7 @@ static void getaddrinfo_thread_proc(eio_req *req) {
653
607
 
654
608
 
655
609
  /* stub implementation of uv_getaddrinfo */
656
- int uv_getaddrinfo(uv_loop_t* loop,
610
+ int uv_getaddrinfo(uv_loop_t* loop,
657
611
  uv_getaddrinfo_t* handle,
658
612
  uv_getaddrinfo_cb cb,
659
613
  const char* hostname,
@@ -668,7 +622,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
668
622
  return -1;
669
623
  }
670
624
 
671
- memset(handle, 0, sizeof(uv_getaddrinfo_t));
625
+ uv__req_init((uv_req_t*)handle);
626
+ handle->type = UV_GETADDRINFO;
627
+ handle->loop = loop;
628
+ handle->cb = cb;
672
629
 
673
630
  /* TODO don't alloc so much. */
674
631
 
@@ -679,10 +636,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
679
636
 
680
637
  /* TODO security! check lengths, check return values. */
681
638
 
682
- handle->loop = loop;
683
- handle->cb = cb;
684
639
  handle->hostname = hostname ? strdup(hostname) : NULL;
685
640
  handle->service = service ? strdup(service) : NULL;
641
+ handle->res = NULL;
642
+ handle->retcode = 0;
686
643
 
687
644
  /* TODO check handle->hostname == NULL */
688
645
  /* TODO check handle->service == NULL */
@@ -810,10 +767,8 @@ size_t uv__strlcpy(char* dst, const char* src, size_t size) {
810
767
  }
811
768
 
812
769
  org = src;
813
- while (size > 1) {
814
- if ((*dst++ = *src++) == '\0') {
815
- return org - src;
816
- }
770
+ while (--size && *src) {
771
+ *dst++ = *src++;
817
772
  }
818
773
  *dst = '\0';
819
774
 
@@ -24,6 +24,7 @@
24
24
  #include <CoreServices/CoreServices.h>
25
25
  #include <mach/mach.h>
26
26
  #include <mach/mach_time.h>
27
+ #include <mach-o/dyld.h> /* _NSGetExecutablePath */
27
28
 
28
29
 
29
30
  uint64_t uv_hrtime() {
@@ -0,0 +1,81 @@
1
+ /* config.h. Generated from config.h.in by configure. */
2
+ /* config.h.in. Generated from configure.ac by autoheader. */
3
+
4
+ /* Define to 1 if you have the <dlfcn.h> header file. */
5
+ #define HAVE_DLFCN_H 1
6
+
7
+ /* fdatasync(2) is available */
8
+ /* #undef HAVE_FDATASYNC */
9
+
10
+ /* utimes(2) is available */
11
+ #define HAVE_UTIMES 1
12
+
13
+ /* futimes(2) is available */
14
+ #define HAVE_FUTIMES 1
15
+
16
+ /* Define to 1 if you have the <inttypes.h> header file. */
17
+ #define HAVE_INTTYPES_H 1
18
+
19
+ /* Define to 1 if you have the <memory.h> header file. */
20
+ #define HAVE_MEMORY_H 1
21
+
22
+ /* pread(2) and pwrite(2) are available */
23
+ #define HAVE_PREADWRITE 1
24
+
25
+ /* readahead(2) is available (linux) */
26
+ /* #undef HAVE_READAHEAD */
27
+
28
+ /* sendfile(2) is available and supported */
29
+ #define HAVE_SENDFILE 0
30
+
31
+ /* Define to 1 if you have the <stdint.h> header file. */
32
+ #define HAVE_STDINT_H 1
33
+
34
+ /* Define to 1 if you have the <stdlib.h> header file. */
35
+ #define HAVE_STDLIB_H 1
36
+
37
+ /* Define to 1 if you have the <strings.h> header file. */
38
+ #define HAVE_STRINGS_H 1
39
+
40
+ /* Define to 1 if you have the <string.h> header file. */
41
+ #define HAVE_STRING_H 1
42
+
43
+ /* sync_file_range(2) is available */
44
+ /* #undef HAVE_SYNC_FILE_RANGE */
45
+
46
+ /* Define to 1 if you have the <sys/stat.h> header file. */
47
+ #define HAVE_SYS_STAT_H 1
48
+
49
+ /* Define to 1 if you have the <sys/types.h> header file. */
50
+ #define HAVE_SYS_TYPES_H 1
51
+
52
+ /* Define to 1 if you have the <unistd.h> header file. */
53
+ #define HAVE_UNISTD_H 1
54
+
55
+ /* Define to the sub-directory in which libtool stores uninstalled libraries.
56
+ */
57
+ #define LT_OBJDIR ".libs/"
58
+
59
+ /* Name of package */
60
+ #define PACKAGE "libeio"
61
+
62
+ /* Define to the address where bug reports for this package should be sent. */
63
+ #define PACKAGE_BUGREPORT ""
64
+
65
+ /* Define to the full name of this package. */
66
+ #define PACKAGE_NAME ""
67
+
68
+ /* Define to the full name and version of this package. */
69
+ #define PACKAGE_STRING ""
70
+
71
+ /* Define to the one symbol short name of this package. */
72
+ #define PACKAGE_TARNAME ""
73
+
74
+ /* Define to the version of this package. */
75
+ #define PACKAGE_VERSION ""
76
+
77
+ /* Define to 1 if you have the ANSI C header files. */
78
+ #define STDC_HEADERS 1
79
+
80
+ /* Version number of package */
81
+ #define VERSION "1.0"
@@ -30,6 +30,8 @@
30
30
  #include <errno.h>
31
31
  #include <stdio.h>
32
32
  #include <stdlib.h>
33
+ #include <string.h>
34
+ #include <assert.h>
33
35
 
34
36
 
35
37
  /* TODO Expose callback to user to handle fatal error like V8 does. */
@@ -64,9 +66,10 @@ char* uv_strerror(uv_err_t err) {
64
66
  }
65
67
 
66
68
 
67
- static uv_err_code uv_translate_sys_error(int sys_errno) {
69
+ uv_err_code uv_translate_sys_error(int sys_errno) {
68
70
  switch (sys_errno) {
69
71
  case 0: return UV_OK;
72
+ case ENOENT: return UV_ENOENT;
70
73
  case EACCES: return UV_EACCESS;
71
74
  case EBADF: return UV_EBADF;
72
75
  case EPIPE: return UV_EPIPE;
@@ -79,8 +82,13 @@ static uv_err_code uv_translate_sys_error(int sys_errno) {
79
82
  case ECONNREFUSED: return UV_ECONNREFUSED;
80
83
  case EADDRINUSE: return UV_EADDRINUSE;
81
84
  case EADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
85
+ case ENOTCONN: return UV_ENOTCONN;
86
+ case EEXIST: return UV_EEXIST;
82
87
  default: return UV_UNKNOWN;
83
88
  }
89
+
90
+ assert(0 && "unreachable");
91
+ return -1;
84
92
  }
85
93
 
86
94
 
@@ -0,0 +1,120 @@
1
+ /* config.h. Generated from config.h.in by configure. */
2
+ /* config.h.in. Generated from configure.ac by autoheader. */
3
+
4
+ /* Define to 1 if you have the `clock_gettime' function. */
5
+ /* #undef HAVE_CLOCK_GETTIME */
6
+
7
+ /* "use syscall interface for clock_gettime" */
8
+ /* #undef HAVE_CLOCK_SYSCALL */
9
+
10
+ /* Define to 1 if you have the <dlfcn.h> header file. */
11
+ #define HAVE_DLFCN_H 1
12
+
13
+ /* Define to 1 if you have the `epoll_ctl' function. */
14
+ /* #undef HAVE_EPOLL_CTL */
15
+
16
+ /* Define to 1 if you have the `eventfd' function. */
17
+ /* #undef HAVE_EVENTFD */
18
+
19
+ /* Define to 1 if you have the `inotify_init' function. */
20
+ /* #undef HAVE_INOTIFY_INIT */
21
+
22
+ /* Define to 1 if you have the <inttypes.h> header file. */
23
+ #define HAVE_INTTYPES_H 1
24
+
25
+ /* Define to 1 if you have the `kqueue' function. */
26
+ #define HAVE_KQUEUE 1
27
+
28
+ /* Define to 1 if you have the `m' library (-lm). */
29
+ #define HAVE_LIBM 1
30
+
31
+ /* Define to 1 if you have the `rt' library (-lrt). */
32
+ /* #undef HAVE_LIBRT */
33
+
34
+ /* Define to 1 if you have the <memory.h> header file. */
35
+ #define HAVE_MEMORY_H 1
36
+
37
+ /* Define to 1 if you have the `nanosleep' function. */
38
+ /* #undef HAVE_NANOSLEEP */
39
+
40
+ /* Define to 1 if you have the `poll' function. */
41
+ #define HAVE_POLL 1
42
+
43
+ /* Define to 1 if you have the <poll.h> header file. */
44
+ #define HAVE_POLL_H 1
45
+
46
+ /* Define to 1 if you have the `port_create' function. */
47
+ /* #undef HAVE_PORT_CREATE */
48
+
49
+ /* Define to 1 if you have the <port.h> header file. */
50
+ /* #undef HAVE_PORT_H */
51
+
52
+ /* Define to 1 if you have the `select' function. */
53
+ #define HAVE_SELECT 1
54
+
55
+ /* Define to 1 if you have the <stdint.h> header file. */
56
+ #define HAVE_STDINT_H 1
57
+
58
+ /* Define to 1 if you have the <stdlib.h> header file. */
59
+ #define HAVE_STDLIB_H 1
60
+
61
+ /* Define to 1 if you have the <strings.h> header file. */
62
+ #define HAVE_STRINGS_H 1
63
+
64
+ /* Define to 1 if you have the <string.h> header file. */
65
+ #define HAVE_STRING_H 1
66
+
67
+ /* Define to 1 if you have the <sys/epoll.h> header file. */
68
+ /* #undef HAVE_SYS_EPOLL_H */
69
+
70
+ /* Define to 1 if you have the <sys/eventfd.h> header file. */
71
+ /* #undef HAVE_SYS_EVENTFD_H */
72
+
73
+ /* Define to 1 if you have the <sys/event.h> header file. */
74
+ #define HAVE_SYS_EVENT_H 1
75
+
76
+ /* Define to 1 if you have the <sys/inotify.h> header file. */
77
+ /* #undef HAVE_SYS_INOTIFY_H */
78
+
79
+ /* Define to 1 if you have the <sys/queue.h> header file. */
80
+ #define HAVE_SYS_QUEUE_H 1
81
+
82
+ /* Define to 1 if you have the <sys/select.h> header file. */
83
+ #define HAVE_SYS_SELECT_H 1
84
+
85
+ /* Define to 1 if you have the <sys/stat.h> header file. */
86
+ #define HAVE_SYS_STAT_H 1
87
+
88
+ /* Define to 1 if you have the <sys/types.h> header file. */
89
+ #define HAVE_SYS_TYPES_H 1
90
+
91
+ /* Define to 1 if you have the <unistd.h> header file. */
92
+ #define HAVE_UNISTD_H 1
93
+
94
+ /* Define to the sub-directory in which libtool stores uninstalled libraries.
95
+ */
96
+ #define LT_OBJDIR ".libs/"
97
+
98
+ /* Name of package */
99
+ #define PACKAGE "libev"
100
+
101
+ /* Define to the address where bug reports for this package should be sent. */
102
+ #define PACKAGE_BUGREPORT ""
103
+
104
+ /* Define to the full name of this package. */
105
+ #define PACKAGE_NAME ""
106
+
107
+ /* Define to the full name and version of this package. */
108
+ #define PACKAGE_STRING ""
109
+
110
+ /* Define to the one symbol short name of this package. */
111
+ #define PACKAGE_TARNAME ""
112
+
113
+ /* Define to the version of this package. */
114
+ #define PACKAGE_VERSION ""
115
+
116
+ /* Define to 1 if you have the ANSI C header files. */
117
+ #define STDC_HEADERS 1
118
+
119
+ /* Version number of package */
120
+ #define VERSION "3.9"
@@ -32,6 +32,7 @@
32
32
  #include <fcntl.h>
33
33
  #include <unistd.h>
34
34
  #include <utime.h>
35
+ #include <sys/time.h>
35
36
 
36
37
 
37
38
  #define ARGS1(a) (a)
@@ -40,28 +41,28 @@
40
41
  #define ARGS4(a,b,c,d) (a), (b), (c), (d)
41
42
 
42
43
  #define WRAP_EIO(type, eiofunc, func, args) \
43
- uv_fs_req_init(loop, req, type, cb); \
44
+ uv_fs_req_init(loop, req, type, path, cb); \
44
45
  if (cb) { \
45
46
  /* async */ \
46
- uv_ref(loop); \
47
47
  req->eio = eiofunc(args, EIO_PRI_DEFAULT, uv__fs_after, req); \
48
48
  if (!req->eio) { \
49
49
  uv_err_new(loop, ENOMEM); \
50
50
  return -1; \
51
51
  } \
52
+ uv_ref(loop); \
52
53
  } else { \
53
54
  /* sync */ \
54
55
  req->result = func(args); \
55
56
  if (req->result) { \
56
57
  uv_err_new(loop, errno); \
57
- return -1; \
58
58
  } \
59
+ return req->result; \
59
60
  } \
60
61
  return 0;
61
62
 
62
63
 
63
64
  static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type,
64
- uv_fs_cb cb) {
65
+ const char* path, uv_fs_cb cb) {
65
66
  /* Make sure the thread pool is initialized. */
66
67
  uv_eio_init(loop);
67
68
 
@@ -72,15 +73,20 @@ static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type,
72
73
  req->cb = cb;
73
74
  req->result = 0;
74
75
  req->ptr = NULL;
76
+ req->path = path ? strdup(path) : NULL;
75
77
  req->errorno = 0;
76
78
  req->eio = NULL;
77
79
  }
78
80
 
79
81
 
80
82
  void uv_fs_req_cleanup(uv_fs_t* req) {
83
+ free(req->path);
84
+ req->path = NULL;
85
+
81
86
  switch (req->fs_type) {
82
87
  case UV_FS_READDIR:
83
- assert(req->ptr);
88
+ assert((req->result == -1 && req->ptr == NULL)
89
+ || (req->result >= 0 && req->ptr != NULL));
84
90
  free(req->ptr);
85
91
  req->ptr = NULL;
86
92
  break;
@@ -106,13 +112,16 @@ static int uv__fs_after(eio_req* eio) {
106
112
  assert(req->cb);
107
113
 
108
114
  req->result = req->eio->result;
109
- req->errorno = req->eio->errorno;
115
+ req->errorno = uv_translate_sys_error(req->eio->errorno);
110
116
 
111
117
  switch (req->fs_type) {
112
118
  case UV_FS_READDIR:
119
+ if (req->eio->result == -1)
120
+ break; /* opendir() or readdir() operation failed. */
121
+
113
122
  /*
114
123
  * XXX This is pretty bad.
115
- * We alloc and copy the large null termiated string list from libeio.
124
+ * We alloc and copy the large null terminated string list from libeio.
116
125
  * This is done because libeio is going to free eio->ptr2 after this
117
126
  * callback. We must keep it until uv_fs_req_cleanup. If we get rid of
118
127
  * libeio this can be avoided.
@@ -130,12 +139,31 @@ static int uv__fs_after(eio_req* eio) {
130
139
  req->ptr = malloc(buflen);
131
140
  memcpy(req->ptr, req->eio->ptr2, buflen);
132
141
  break;
142
+
133
143
  case UV_FS_STAT:
134
144
  case UV_FS_LSTAT:
135
145
  case UV_FS_FSTAT:
136
146
  req->ptr = req->eio->ptr2;
137
147
  break;
138
148
 
149
+ case UV_FS_READLINK:
150
+ if (req->result == -1) {
151
+ req->ptr = NULL;
152
+ } else {
153
+ assert(req->result > 0);
154
+
155
+ if ((name = realloc(req->eio->ptr2, req->result + 1)) == NULL) {
156
+ /* Not enough memory. Reuse buffer, chop off last byte. */
157
+ name = req->eio->ptr2;
158
+ req->result--;
159
+ }
160
+
161
+ name[req->result] = '\0';
162
+ req->ptr = name;
163
+ req->result = 0;
164
+ }
165
+ break;
166
+
139
167
  default:
140
168
  break;
141
169
  }
@@ -149,13 +177,14 @@ static int uv__fs_after(eio_req* eio) {
149
177
 
150
178
 
151
179
  int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
180
+ char* path = NULL;
152
181
  WRAP_EIO(UV_FS_CLOSE, eio_close, close, ARGS1(file));
153
182
  }
154
183
 
155
184
 
156
185
  int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
157
186
  int mode, uv_fs_cb cb) {
158
- uv_fs_req_init(loop, req, UV_FS_OPEN, cb);
187
+ uv_fs_req_init(loop, req, UV_FS_OPEN, path, cb);
159
188
 
160
189
  if (cb) {
161
190
  /* async */
@@ -175,6 +204,8 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
175
204
  }
176
205
 
177
206
  uv__cloexec(req->result, 1);
207
+
208
+ return req->result;
178
209
  }
179
210
 
180
211
  return 0;
@@ -183,7 +214,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
183
214
 
184
215
  int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
185
216
  size_t length, off_t offset, uv_fs_cb cb) {
186
- uv_fs_req_init(loop, req, UV_FS_READ, cb);
217
+ uv_fs_req_init(loop, req, UV_FS_READ, NULL, cb);
187
218
 
188
219
  if (cb) {
189
220
  /* async */
@@ -206,6 +237,8 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
206
237
  uv_err_new(loop, errno);
207
238
  return -1;
208
239
  }
240
+
241
+ return req->result;
209
242
  }
210
243
 
211
244
  return 0;
@@ -219,7 +252,7 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
219
252
 
220
253
  int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
221
254
  size_t length, off_t offset, uv_fs_cb cb) {
222
- uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
255
+ uv_fs_req_init(loop, req, UV_FS_WRITE, NULL, cb);
223
256
 
224
257
  if (cb) {
225
258
  /* async */
@@ -241,6 +274,8 @@ int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
241
274
  uv_err_new(loop, errno);
242
275
  return -1;
243
276
  }
277
+
278
+ return req->result;
244
279
  }
245
280
 
246
281
  return 0;
@@ -265,7 +300,7 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
265
300
  size_t size = 0;
266
301
  size_t d_namlen = 0;
267
302
 
268
- uv_fs_req_init(loop, req, UV_FS_READDIR, cb);
303
+ uv_fs_req_init(loop, req, UV_FS_READDIR, path, cb);
269
304
 
270
305
  if (cb) {
271
306
  /* async */
@@ -281,25 +316,40 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
281
316
  DIR* dir = opendir(path);
282
317
  if (!dir) {
283
318
  uv_err_new(loop, errno);
319
+ req->result = -1;
284
320
  return -1;
285
321
  }
286
322
 
323
+ /* req->result stores number of entries */
324
+ req->result = 0;
325
+
287
326
  while ((entry = readdir(dir))) {
288
327
  d_namlen = strlen(entry->d_name);
328
+
329
+ /* Skip . and .. */
330
+ if ((d_namlen == 1 && entry->d_name[0] == '.') ||
331
+ (d_namlen == 2 && entry->d_name[0] == '.' &&
332
+ entry->d_name[1] == '.')) {
333
+ continue;
334
+ }
335
+
289
336
  req->ptr = realloc(req->ptr, size + d_namlen + 1);
290
337
  /* TODO check ENOMEM */
291
- /* TODO skip . and .. */
292
338
  memcpy((char*)req->ptr + size, entry->d_name, d_namlen);
293
339
  size += d_namlen;
294
340
  ((char*)req->ptr)[size] = '\0';
295
341
  size++;
342
+ req->result++;
296
343
  }
297
344
 
298
345
  r = closedir(dir);
299
346
  if (r) {
300
347
  uv_err_new(loop, errno);
348
+ req->result = -1;
301
349
  return -1;
302
350
  }
351
+
352
+ return req->result;
303
353
  }
304
354
 
305
355
  return 0;
@@ -307,10 +357,10 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
307
357
 
308
358
 
309
359
  int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
310
- char* pathdup = path;
360
+ char* pathdup;
311
361
  int pathlen;
312
362
 
313
- uv_fs_req_init(loop, req, UV_FS_STAT, cb);
363
+ uv_fs_req_init(loop, req, UV_FS_STAT, path, cb);
314
364
 
315
365
  /* TODO do this without duplicating the string. */
316
366
  /* TODO security */
@@ -346,6 +396,7 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
346
396
  }
347
397
 
348
398
  req->ptr = &req->statbuf;
399
+ return req->result;
349
400
  }
350
401
 
351
402
  return 0;
@@ -353,7 +404,7 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
353
404
 
354
405
 
355
406
  int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
356
- uv_fs_req_init(loop, req, UV_FS_FSTAT, cb);
407
+ uv_fs_req_init(loop, req, UV_FS_FSTAT, NULL, cb);
357
408
 
358
409
  if (cb) {
359
410
  /* async */
@@ -375,6 +426,7 @@ int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
375
426
  }
376
427
 
377
428
  req->ptr = &req->statbuf;
429
+ return req->result;
378
430
  }
379
431
 
380
432
  return 0;
@@ -388,23 +440,27 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* ne
388
440
 
389
441
 
390
442
  int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
443
+ char* path = NULL;
391
444
  WRAP_EIO(UV_FS_FSYNC, eio_fsync, fsync, ARGS1(file))
392
445
  }
393
446
 
394
447
 
395
448
  int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
449
+ char* path = NULL;
396
450
  WRAP_EIO(UV_FS_FDATASYNC, eio_fdatasync, fdatasync, ARGS1(file))
397
451
  }
398
452
 
399
453
 
400
454
  int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, off_t offset,
401
455
  uv_fs_cb cb) {
456
+ char* path = NULL;
402
457
  WRAP_EIO(UV_FS_FTRUNCATE, eio_ftruncate, ftruncate, ARGS2(file, offset))
403
458
  }
404
459
 
405
460
 
406
461
  int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd,
407
462
  off_t in_offset, size_t length, uv_fs_cb cb) {
463
+ char* path = NULL;
408
464
  WRAP_EIO(UV_FS_SENDFILE, eio_sendfile, eio_sendfile_sync,
409
465
  ARGS4(out_fd, in_fd, in_offset, length))
410
466
  }
@@ -430,18 +486,42 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
430
486
  }
431
487
 
432
488
 
489
+ #if defined(HAVE_FUTIMES)
490
+ static int _futime(const uv_file file, double atime, double mtime) {
491
+ struct timeval tv[2];
492
+
493
+ /* FIXME possible loss of precision in floating-point arithmetic? */
494
+ tv[0].tv_sec = atime;
495
+ tv[0].tv_usec = (unsigned long)(atime * 1000000) % 1000000;
496
+
497
+ tv[1].tv_sec = mtime;
498
+ tv[1].tv_usec = (unsigned long)(mtime * 1000000) % 1000000;
499
+
500
+ return futimes(file, tv);
501
+ }
502
+ #endif
503
+
504
+
433
505
  int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
434
506
  double mtime, uv_fs_cb cb) {
435
- assert(0 && "implement me");
507
+ #if defined(HAVE_FUTIMES)
508
+ const char* path = NULL;
509
+
510
+ uv_fs_req_init(loop, req, UV_FS_FUTIME, path, cb);
511
+
512
+ WRAP_EIO(UV_FS_FUTIME, eio_futime, _futime, ARGS3(file, atime, mtime))
513
+ #else
514
+ uv_err_new(loop, ENOSYS);
436
515
  return -1;
516
+ #endif
437
517
  }
438
518
 
439
519
 
440
520
  int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
441
- char* pathdup = path;
521
+ char* pathdup;
442
522
  int pathlen;
443
523
 
444
- uv_fs_req_init(loop, req, UV_FS_LSTAT, cb);
524
+ uv_fs_req_init(loop, req, UV_FS_LSTAT, path, cb);
445
525
 
446
526
  /* TODO do this without duplicating the string. */
447
527
  /* TODO security */
@@ -477,6 +557,7 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
477
557
  }
478
558
 
479
559
  req->ptr = &req->statbuf;
560
+ return req->result;
480
561
  }
481
562
 
482
563
  return 0;
@@ -490,20 +571,68 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
490
571
 
491
572
 
492
573
  int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
493
- const char* new_path, uv_fs_cb cb) {
574
+ const char* new_path, int flags, uv_fs_cb cb) {
494
575
  WRAP_EIO(UV_FS_SYMLINK, eio_symlink, symlink, ARGS2(path, new_path))
495
576
  }
496
577
 
497
578
 
498
579
  int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
499
580
  uv_fs_cb cb) {
500
- assert(0 && "implement me");
501
- return -1;
581
+ ssize_t size;
582
+ int status;
583
+ char* buf;
584
+
585
+ status = -1;
586
+
587
+ uv_fs_req_init(loop, req, UV_FS_READLINK, path, cb);
588
+
589
+ if (cb) {
590
+ if ((req->eio = eio_readlink(path, EIO_PRI_DEFAULT, uv__fs_after, req))) {
591
+ uv_ref(loop);
592
+ return 0;
593
+ } else {
594
+ uv_err_new(loop, ENOMEM);
595
+ return -1;
596
+ }
597
+ } else {
598
+ /* pathconf(_PC_PATH_MAX) may return -1 to signify that path
599
+ * lengths have no upper limit or aren't suitable for malloc'ing.
600
+ */
601
+ if ((size = pathconf(path, _PC_PATH_MAX)) == -1) {
602
+ #if defined(PATH_MAX)
603
+ size = PATH_MAX;
604
+ #else
605
+ size = 4096;
606
+ #endif
607
+ }
608
+
609
+ if ((buf = malloc(size + 1)) == NULL) {
610
+ uv_err_new(loop, ENOMEM);
611
+ return -1;
612
+ }
613
+
614
+ if ((size = readlink(path, buf, size)) == -1) {
615
+ req->errorno = errno;
616
+ req->result = -1;
617
+ free(buf);
618
+ } else {
619
+ /* Cannot conceivably fail since it shrinks the buffer. */
620
+ buf = realloc(buf, size + 1);
621
+ buf[size] = '\0';
622
+ req->result = 0;
623
+ req->ptr = buf;
624
+ }
625
+
626
+ return req->result;
627
+ }
628
+
629
+ assert(0 && "unreachable");
502
630
  }
503
631
 
504
632
 
505
633
  int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
506
634
  uv_fs_cb cb) {
635
+ char* path = NULL;
507
636
  WRAP_EIO(UV_FS_FCHMOD, eio_fchmod, fchmod, ARGS2(file, mode))
508
637
  }
509
638
 
@@ -516,6 +645,7 @@ int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
516
645
 
517
646
  int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid, int gid,
518
647
  uv_fs_cb cb) {
648
+ char* path = NULL;
519
649
  WRAP_EIO(UV_FS_FCHOWN, eio_fchown, fchown, ARGS3(file, uid, gid))
520
650
  }
521
651