noderb 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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