rbuv 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +0 -1
  6. data/README.md +6 -1
  7. data/Rakefile +42 -0
  8. data/deps/libuv/.gitignore +34 -0
  9. data/deps/libuv/.mailmap +16 -0
  10. data/deps/libuv/AUTHORS +81 -0
  11. data/deps/libuv/ChangeLog +45 -0
  12. data/deps/libuv/LICENSE +41 -0
  13. data/deps/libuv/Makefile +53 -0
  14. data/deps/libuv/README.md +118 -0
  15. data/deps/libuv/build.mk +164 -0
  16. data/deps/libuv/checksparse.sh +230 -0
  17. data/deps/libuv/common.gypi +197 -0
  18. data/deps/libuv/config-mingw.mk +48 -0
  19. data/deps/libuv/config-unix.mk +167 -0
  20. data/deps/libuv/gyp_uv +98 -0
  21. data/deps/libuv/include/uv-private/ngx-queue.h +129 -0
  22. data/deps/libuv/include/uv-private/stdint-msvc2008.h +247 -0
  23. data/deps/libuv/include/uv-private/tree.h +768 -0
  24. data/deps/libuv/include/uv-private/uv-bsd.h +34 -0
  25. data/deps/libuv/include/uv-private/uv-darwin.h +61 -0
  26. data/deps/libuv/include/uv-private/uv-linux.h +34 -0
  27. data/deps/libuv/include/uv-private/uv-sunos.h +44 -0
  28. data/deps/libuv/include/uv-private/uv-unix.h +332 -0
  29. data/deps/libuv/include/uv-private/uv-win.h +585 -0
  30. data/deps/libuv/include/uv.h +1987 -0
  31. data/deps/libuv/src/fs-poll.c +248 -0
  32. data/deps/libuv/src/inet.c +298 -0
  33. data/deps/libuv/src/unix/aix.c +393 -0
  34. data/deps/libuv/src/unix/async.c +281 -0
  35. data/deps/libuv/src/unix/core.c +714 -0
  36. data/deps/libuv/src/unix/cygwin.c +93 -0
  37. data/deps/libuv/src/unix/darwin-proctitle.m +78 -0
  38. data/deps/libuv/src/unix/darwin.c +431 -0
  39. data/deps/libuv/src/unix/dl.c +83 -0
  40. data/deps/libuv/src/unix/error.c +109 -0
  41. data/deps/libuv/src/unix/freebsd.c +343 -0
  42. data/deps/libuv/src/unix/fs.c +869 -0
  43. data/deps/libuv/src/unix/fsevents.c +299 -0
  44. data/deps/libuv/src/unix/getaddrinfo.c +159 -0
  45. data/deps/libuv/src/unix/internal.h +259 -0
  46. data/deps/libuv/src/unix/kqueue.c +347 -0
  47. data/deps/libuv/src/unix/linux-core.c +724 -0
  48. data/deps/libuv/src/unix/linux-inotify.c +236 -0
  49. data/deps/libuv/src/unix/linux-syscalls.c +388 -0
  50. data/deps/libuv/src/unix/linux-syscalls.h +150 -0
  51. data/deps/libuv/src/unix/loop-watcher.c +64 -0
  52. data/deps/libuv/src/unix/loop.c +114 -0
  53. data/deps/libuv/src/unix/netbsd.c +353 -0
  54. data/deps/libuv/src/unix/openbsd.c +304 -0
  55. data/deps/libuv/src/unix/pipe.c +261 -0
  56. data/deps/libuv/src/unix/poll.c +108 -0
  57. data/deps/libuv/src/unix/process.c +501 -0
  58. data/deps/libuv/src/unix/proctitle.c +103 -0
  59. data/deps/libuv/src/unix/signal.c +455 -0
  60. data/deps/libuv/src/unix/stream.c +1380 -0
  61. data/deps/libuv/src/unix/sunos.c +647 -0
  62. data/deps/libuv/src/unix/tcp.c +357 -0
  63. data/deps/libuv/src/unix/thread.c +431 -0
  64. data/deps/libuv/src/unix/threadpool.c +286 -0
  65. data/deps/libuv/src/unix/timer.c +153 -0
  66. data/deps/libuv/src/unix/tty.c +179 -0
  67. data/deps/libuv/src/unix/udp.c +715 -0
  68. data/deps/libuv/src/uv-common.c +431 -0
  69. data/deps/libuv/src/uv-common.h +204 -0
  70. data/deps/libuv/src/version.c +60 -0
  71. data/deps/libuv/src/win/async.c +99 -0
  72. data/deps/libuv/src/win/atomicops-inl.h +56 -0
  73. data/deps/libuv/src/win/core.c +310 -0
  74. data/deps/libuv/src/win/dl.c +86 -0
  75. data/deps/libuv/src/win/error.c +164 -0
  76. data/deps/libuv/src/win/fs-event.c +506 -0
  77. data/deps/libuv/src/win/fs.c +1951 -0
  78. data/deps/libuv/src/win/getaddrinfo.c +365 -0
  79. data/deps/libuv/src/win/handle-inl.h +164 -0
  80. data/deps/libuv/src/win/handle.c +153 -0
  81. data/deps/libuv/src/win/internal.h +346 -0
  82. data/deps/libuv/src/win/loop-watcher.c +124 -0
  83. data/deps/libuv/src/win/pipe.c +1656 -0
  84. data/deps/libuv/src/win/poll.c +615 -0
  85. data/deps/libuv/src/win/process-stdio.c +503 -0
  86. data/deps/libuv/src/win/process.c +1048 -0
  87. data/deps/libuv/src/win/req-inl.h +224 -0
  88. data/deps/libuv/src/win/req.c +25 -0
  89. data/deps/libuv/src/win/signal.c +354 -0
  90. data/deps/libuv/src/win/stream-inl.h +67 -0
  91. data/deps/libuv/src/win/stream.c +198 -0
  92. data/deps/libuv/src/win/tcp.c +1422 -0
  93. data/deps/libuv/src/win/thread.c +666 -0
  94. data/deps/libuv/src/win/threadpool.c +82 -0
  95. data/deps/libuv/src/win/timer.c +230 -0
  96. data/deps/libuv/src/win/tty.c +1857 -0
  97. data/deps/libuv/src/win/udp.c +744 -0
  98. data/deps/libuv/src/win/util.c +946 -0
  99. data/deps/libuv/src/win/winapi.c +152 -0
  100. data/deps/libuv/src/win/winapi.h +4476 -0
  101. data/deps/libuv/src/win/winsock.c +560 -0
  102. data/deps/libuv/src/win/winsock.h +171 -0
  103. data/deps/libuv/test/benchmark-async-pummel.c +119 -0
  104. data/deps/libuv/test/benchmark-async.c +139 -0
  105. data/deps/libuv/test/benchmark-fs-stat.c +136 -0
  106. data/deps/libuv/test/benchmark-getaddrinfo.c +91 -0
  107. data/deps/libuv/test/benchmark-list.h +163 -0
  108. data/deps/libuv/test/benchmark-loop-count.c +90 -0
  109. data/deps/libuv/test/benchmark-million-async.c +112 -0
  110. data/deps/libuv/test/benchmark-million-timers.c +77 -0
  111. data/deps/libuv/test/benchmark-multi-accept.c +432 -0
  112. data/deps/libuv/test/benchmark-ping-pongs.c +212 -0
  113. data/deps/libuv/test/benchmark-pound.c +325 -0
  114. data/deps/libuv/test/benchmark-pump.c +459 -0
  115. data/deps/libuv/test/benchmark-sizes.c +45 -0
  116. data/deps/libuv/test/benchmark-spawn.c +163 -0
  117. data/deps/libuv/test/benchmark-tcp-write-batch.c +141 -0
  118. data/deps/libuv/test/benchmark-thread.c +64 -0
  119. data/deps/libuv/test/benchmark-udp-pummel.c +238 -0
  120. data/deps/libuv/test/blackhole-server.c +118 -0
  121. data/deps/libuv/test/dns-server.c +329 -0
  122. data/deps/libuv/test/echo-server.c +384 -0
  123. data/deps/libuv/test/fixtures/empty_file +0 -0
  124. data/deps/libuv/test/fixtures/load_error.node +1 -0
  125. data/deps/libuv/test/run-benchmarks.c +64 -0
  126. data/deps/libuv/test/run-tests.c +159 -0
  127. data/deps/libuv/test/runner-unix.c +328 -0
  128. data/deps/libuv/test/runner-unix.h +36 -0
  129. data/deps/libuv/test/runner-win.c +318 -0
  130. data/deps/libuv/test/runner-win.h +43 -0
  131. data/deps/libuv/test/runner.c +394 -0
  132. data/deps/libuv/test/runner.h +165 -0
  133. data/deps/libuv/test/task.h +122 -0
  134. data/deps/libuv/test/test-active.c +83 -0
  135. data/deps/libuv/test/test-async.c +136 -0
  136. data/deps/libuv/test/test-barrier.c +98 -0
  137. data/deps/libuv/test/test-callback-order.c +77 -0
  138. data/deps/libuv/test/test-callback-stack.c +204 -0
  139. data/deps/libuv/test/test-condvar.c +173 -0
  140. data/deps/libuv/test/test-connection-fail.c +150 -0
  141. data/deps/libuv/test/test-cwd-and-chdir.c +64 -0
  142. data/deps/libuv/test/test-delayed-accept.c +189 -0
  143. data/deps/libuv/test/test-dlerror.c +58 -0
  144. data/deps/libuv/test/test-embed.c +136 -0
  145. data/deps/libuv/test/test-error.c +59 -0
  146. data/deps/libuv/test/test-fail-always.c +29 -0
  147. data/deps/libuv/test/test-fs-event.c +504 -0
  148. data/deps/libuv/test/test-fs-poll.c +148 -0
  149. data/deps/libuv/test/test-fs.c +1899 -0
  150. data/deps/libuv/test/test-get-currentexe.c +63 -0
  151. data/deps/libuv/test/test-get-loadavg.c +36 -0
  152. data/deps/libuv/test/test-get-memory.c +38 -0
  153. data/deps/libuv/test/test-getaddrinfo.c +120 -0
  154. data/deps/libuv/test/test-getsockname.c +344 -0
  155. data/deps/libuv/test/test-hrtime.c +54 -0
  156. data/deps/libuv/test/test-idle.c +82 -0
  157. data/deps/libuv/test/test-ipc-send-recv.c +218 -0
  158. data/deps/libuv/test/test-ipc.c +625 -0
  159. data/deps/libuv/test/test-list.h +492 -0
  160. data/deps/libuv/test/test-loop-handles.c +337 -0
  161. data/deps/libuv/test/test-loop-stop.c +73 -0
  162. data/deps/libuv/test/test-multiple-listen.c +103 -0
  163. data/deps/libuv/test/test-mutexes.c +63 -0
  164. data/deps/libuv/test/test-pass-always.c +28 -0
  165. data/deps/libuv/test/test-ping-pong.c +250 -0
  166. data/deps/libuv/test/test-pipe-bind-error.c +144 -0
  167. data/deps/libuv/test/test-pipe-connect-error.c +98 -0
  168. data/deps/libuv/test/test-platform-output.c +87 -0
  169. data/deps/libuv/test/test-poll-close.c +73 -0
  170. data/deps/libuv/test/test-poll.c +575 -0
  171. data/deps/libuv/test/test-process-title.c +49 -0
  172. data/deps/libuv/test/test-ref.c +415 -0
  173. data/deps/libuv/test/test-run-nowait.c +46 -0
  174. data/deps/libuv/test/test-run-once.c +49 -0
  175. data/deps/libuv/test/test-semaphore.c +111 -0
  176. data/deps/libuv/test/test-shutdown-close.c +105 -0
  177. data/deps/libuv/test/test-shutdown-eof.c +184 -0
  178. data/deps/libuv/test/test-signal-multiple-loops.c +270 -0
  179. data/deps/libuv/test/test-signal.c +152 -0
  180. data/deps/libuv/test/test-spawn.c +938 -0
  181. data/deps/libuv/test/test-stdio-over-pipes.c +250 -0
  182. data/deps/libuv/test/test-tcp-bind-error.c +198 -0
  183. data/deps/libuv/test/test-tcp-bind6-error.c +159 -0
  184. data/deps/libuv/test/test-tcp-close-while-connecting.c +81 -0
  185. data/deps/libuv/test/test-tcp-close.c +130 -0
  186. data/deps/libuv/test/test-tcp-connect-error-after-write.c +96 -0
  187. data/deps/libuv/test/test-tcp-connect-error.c +71 -0
  188. data/deps/libuv/test/test-tcp-connect-timeout.c +86 -0
  189. data/deps/libuv/test/test-tcp-connect6-error.c +69 -0
  190. data/deps/libuv/test/test-tcp-flags.c +52 -0
  191. data/deps/libuv/test/test-tcp-open.c +175 -0
  192. data/deps/libuv/test/test-tcp-read-stop.c +73 -0
  193. data/deps/libuv/test/test-tcp-shutdown-after-write.c +132 -0
  194. data/deps/libuv/test/test-tcp-unexpected-read.c +114 -0
  195. data/deps/libuv/test/test-tcp-write-to-half-open-connection.c +136 -0
  196. data/deps/libuv/test/test-tcp-writealot.c +171 -0
  197. data/deps/libuv/test/test-thread.c +183 -0
  198. data/deps/libuv/test/test-threadpool-cancel.c +311 -0
  199. data/deps/libuv/test/test-threadpool.c +77 -0
  200. data/deps/libuv/test/test-timer-again.c +142 -0
  201. data/deps/libuv/test/test-timer.c +266 -0
  202. data/deps/libuv/test/test-tty.c +111 -0
  203. data/deps/libuv/test/test-udp-dgram-too-big.c +87 -0
  204. data/deps/libuv/test/test-udp-ipv6.c +158 -0
  205. data/deps/libuv/test/test-udp-multicast-join.c +140 -0
  206. data/deps/libuv/test/test-udp-multicast-ttl.c +87 -0
  207. data/deps/libuv/test/test-udp-open.c +154 -0
  208. data/deps/libuv/test/test-udp-options.c +87 -0
  209. data/deps/libuv/test/test-udp-send-and-recv.c +210 -0
  210. data/deps/libuv/test/test-util.c +97 -0
  211. data/deps/libuv/test/test-walk-handles.c +78 -0
  212. data/deps/libuv/uv.gyp +431 -0
  213. data/deps/libuv/vcbuild.bat +128 -0
  214. data/ext/rbuv/debug.h +27 -0
  215. data/ext/rbuv/error.c +7 -0
  216. data/ext/rbuv/error.h +10 -0
  217. data/ext/rbuv/extconf.rb +35 -0
  218. data/ext/rbuv/handle.c +40 -0
  219. data/ext/rbuv/handle.h +14 -0
  220. data/ext/rbuv/libuv.mk +12 -0
  221. data/ext/rbuv/loop.c +50 -0
  222. data/ext/rbuv/loop.h +13 -0
  223. data/ext/rbuv/rbuv.c +15 -0
  224. data/ext/rbuv/rbuv.h +27 -0
  225. data/ext/rbuv/timer.c +133 -0
  226. data/ext/rbuv/timer.h +13 -0
  227. data/lib/rbuv/timer.rb +7 -0
  228. data/lib/rbuv/version.rb +1 -1
  229. data/lib/rbuv.rb +24 -2
  230. data/rbuv.gemspec +5 -1
  231. data/spec/spec_helper.rb +22 -0
  232. data/spec/timer_spec.rb +144 -0
  233. metadata +278 -9
@@ -0,0 +1,164 @@
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 <assert.h>
23
+ #include <errno.h>
24
+ #include <malloc.h>
25
+ #include <stdio.h>
26
+ #include <string.h>
27
+
28
+ #include "uv.h"
29
+ #include "internal.h"
30
+
31
+
32
+ /*
33
+ * Display an error message and abort the event loop.
34
+ */
35
+ void uv_fatal_error(const int errorno, const char* syscall) {
36
+ char* buf = NULL;
37
+ const char* errmsg;
38
+
39
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
40
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
41
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL);
42
+
43
+ if (buf) {
44
+ errmsg = buf;
45
+ } else {
46
+ errmsg = "Unknown error";
47
+ }
48
+
49
+ /* FormatMessage messages include a newline character already, */
50
+ /* so don't add another. */
51
+ if (syscall) {
52
+ fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg);
53
+ } else {
54
+ fprintf(stderr, "(%d) %s", errorno, errmsg);
55
+ }
56
+
57
+ if (buf) {
58
+ LocalFree(buf);
59
+ }
60
+
61
+ *((char*)NULL) = 0xff; /* Force debug break */
62
+ abort();
63
+ }
64
+
65
+
66
+ uv_err_code uv_translate_sys_error(int sys_errno) {
67
+ switch (sys_errno) {
68
+ case ERROR_SUCCESS: return UV_OK;
69
+ case ERROR_NOACCESS: return UV_EACCES;
70
+ case WSAEACCES: return UV_EACCES;
71
+ case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
72
+ case WSAEADDRINUSE: return UV_EADDRINUSE;
73
+ case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
74
+ case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT;
75
+ case WSAEWOULDBLOCK: return UV_EAGAIN;
76
+ case WSAEALREADY: return UV_EALREADY;
77
+ case ERROR_INVALID_FLAGS: return UV_EBADF;
78
+ case ERROR_INVALID_HANDLE: return UV_EBADF;
79
+ case ERROR_LOCK_VIOLATION: return UV_EBUSY;
80
+ case ERROR_PIPE_BUSY: return UV_EBUSY;
81
+ case ERROR_SHARING_VIOLATION: return UV_EBUSY;
82
+ case ERROR_OPERATION_ABORTED: return UV_ECANCELED;
83
+ case WSAEINTR: return UV_ECANCELED;
84
+ case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
85
+ case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED;
86
+ case WSAECONNABORTED: return UV_ECONNABORTED;
87
+ case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED;
88
+ case WSAECONNREFUSED: return UV_ECONNREFUSED;
89
+ case ERROR_NETNAME_DELETED: return UV_ECONNRESET;
90
+ case WSAECONNRESET: return UV_ECONNRESET;
91
+ case ERROR_ALREADY_EXISTS: return UV_EEXIST;
92
+ case ERROR_FILE_EXISTS: return UV_EEXIST;
93
+ case ERROR_BUFFER_OVERFLOW: return UV_EFAULT;
94
+ case WSAEFAULT: return UV_EFAULT;
95
+ case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH;
96
+ case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
97
+ case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
98
+ case ERROR_INVALID_DATA: return UV_EINVAL;
99
+ case ERROR_INVALID_PARAMETER: return UV_EINVAL;
100
+ case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
101
+ case WSAEINVAL: return UV_EINVAL;
102
+ case WSAEPFNOSUPPORT: return UV_EINVAL;
103
+ case WSAESOCKTNOSUPPORT: return UV_EINVAL;
104
+ case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
105
+ case ERROR_BUS_RESET: return UV_EIO;
106
+ case ERROR_CRC: return UV_EIO;
107
+ case ERROR_DEVICE_DOOR_OPEN: return UV_EIO;
108
+ case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO;
109
+ case ERROR_DISK_CORRUPT: return UV_EIO;
110
+ case ERROR_EOM_OVERFLOW: return UV_EIO;
111
+ case ERROR_FILEMARK_DETECTED: return UV_EIO;
112
+ case ERROR_GEN_FAILURE: return UV_EIO;
113
+ case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO;
114
+ case ERROR_IO_DEVICE: return UV_EIO;
115
+ case ERROR_NO_DATA_DETECTED: return UV_EIO;
116
+ case ERROR_NO_SIGNAL_SENT: return UV_EIO;
117
+ case ERROR_OPEN_FAILED: return UV_EIO;
118
+ case ERROR_SETMARK_DETECTED: return UV_EIO;
119
+ case ERROR_SIGNAL_REFUSED: return UV_EIO;
120
+ case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP;
121
+ case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE;
122
+ case WSAEMFILE: return UV_EMFILE;
123
+ case WSAEMSGSIZE: return UV_EMSGSIZE;
124
+ case ERROR_FILENAME_EXCED_RANGE: return UV_ENAMETOOLONG;
125
+ case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
126
+ case WSAENETUNREACH: return UV_ENETUNREACH;
127
+ case WSAENOBUFS: return UV_ENOBUFS;
128
+ case ERROR_DIRECTORY: return UV_ENOENT;
129
+ case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
130
+ case ERROR_INVALID_NAME: return UV_ENOENT;
131
+ case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT;
132
+ case ERROR_MOD_NOT_FOUND: return UV_ENOENT;
133
+ case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
134
+ case WSAHOST_NOT_FOUND: return UV_ENOENT;
135
+ case WSANO_DATA: return UV_ENOENT;
136
+ case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM;
137
+ case ERROR_OUTOFMEMORY: return UV_ENOMEM;
138
+ case ERROR_CANNOT_MAKE: return UV_ENOSPC;
139
+ case ERROR_DISK_FULL: return UV_ENOSPC;
140
+ case ERROR_EA_TABLE_FULL: return UV_ENOSPC;
141
+ case ERROR_END_OF_MEDIA: return UV_ENOSPC;
142
+ case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC;
143
+ case ERROR_NOT_CONNECTED: return UV_ENOTCONN;
144
+ case WSAENOTCONN: return UV_ENOTCONN;
145
+ case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY;
146
+ case WSAENOTSOCK: return UV_ENOTSOCK;
147
+ case ERROR_NOT_SUPPORTED: return UV_ENOTSUP;
148
+ case ERROR_BROKEN_PIPE: return UV_EOF;
149
+ case ERROR_ACCESS_DENIED: return UV_EPERM;
150
+ case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM;
151
+ case ERROR_BAD_PIPE: return UV_EPIPE;
152
+ case ERROR_NO_DATA: return UV_EPIPE;
153
+ case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE;
154
+ case WSAESHUTDOWN: return UV_EPIPE;
155
+ case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT;
156
+ case ERROR_WRITE_PROTECT: return UV_EROFS;
157
+ case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT;
158
+ case WSAETIMEDOUT: return UV_ETIMEDOUT;
159
+ case ERROR_NOT_SAME_DEVICE: return UV_EXDEV;
160
+ case ERROR_INVALID_FUNCTION: return UV_EISDIR;
161
+ default: return UV_UNKNOWN;
162
+ }
163
+ }
164
+
@@ -0,0 +1,506 @@
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 <assert.h>
23
+ #include <malloc.h>
24
+ #include <errno.h>
25
+ #include <stdio.h>
26
+ #include <string.h>
27
+
28
+ #include "uv.h"
29
+ #include "internal.h"
30
+ #include "handle-inl.h"
31
+ #include "req-inl.h"
32
+
33
+
34
+ const unsigned int uv_directory_watcher_buffer_size = 4096;
35
+
36
+
37
+ static void uv_fs_event_init_handle(uv_loop_t* loop, uv_fs_event_t* handle,
38
+ const char* filename, uv_fs_event_cb cb) {
39
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_FS_EVENT);
40
+ handle->cb = cb;
41
+ handle->dir_handle = INVALID_HANDLE_VALUE;
42
+ handle->buffer = NULL;
43
+ handle->req_pending = 0;
44
+ handle->filew = NULL;
45
+ handle->short_filew = NULL;
46
+ handle->dirw = NULL;
47
+
48
+ uv_req_init(loop, (uv_req_t*)&handle->req);
49
+ handle->req.type = UV_FS_EVENT_REQ;
50
+ handle->req.data = (void*)handle;
51
+
52
+ handle->filename = strdup(filename);
53
+ if (!handle->filename) {
54
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
55
+ }
56
+
57
+ uv__handle_start(handle);
58
+ }
59
+
60
+
61
+ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
62
+ uv_fs_event_t* handle) {
63
+ assert(handle->dir_handle != INVALID_HANDLE_VALUE);
64
+ assert(!handle->req_pending);
65
+
66
+ memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped));
67
+ if (!ReadDirectoryChangesW(handle->dir_handle,
68
+ handle->buffer,
69
+ uv_directory_watcher_buffer_size,
70
+ FALSE,
71
+ FILE_NOTIFY_CHANGE_FILE_NAME |
72
+ FILE_NOTIFY_CHANGE_DIR_NAME |
73
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |
74
+ FILE_NOTIFY_CHANGE_SIZE |
75
+ FILE_NOTIFY_CHANGE_LAST_WRITE |
76
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |
77
+ FILE_NOTIFY_CHANGE_CREATION |
78
+ FILE_NOTIFY_CHANGE_SECURITY,
79
+ NULL,
80
+ &handle->req.overlapped,
81
+ NULL)) {
82
+ /* Make this req pending reporting an error. */
83
+ SET_REQ_ERROR(&handle->req, GetLastError());
84
+ uv_insert_pending_req(loop, (uv_req_t*)&handle->req);
85
+ }
86
+
87
+ handle->req_pending = 1;
88
+ }
89
+
90
+
91
+ static int uv_split_path(const WCHAR* filename, WCHAR** dir,
92
+ WCHAR** file) {
93
+ int len = wcslen(filename);
94
+ int i = len;
95
+ while (i > 0 && filename[--i] != '\\' && filename[i] != '/');
96
+
97
+ if (i == 0) {
98
+ if (dir) {
99
+ *dir = (WCHAR*)malloc((MAX_PATH + 1) * sizeof(WCHAR));
100
+ if (!*dir) {
101
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
102
+ }
103
+
104
+ if (!GetCurrentDirectoryW(MAX_PATH, *dir)) {
105
+ free(*dir);
106
+ *dir = NULL;
107
+ return -1;
108
+ }
109
+ }
110
+
111
+ *file = wcsdup(filename);
112
+ } else {
113
+ if (dir) {
114
+ *dir = (WCHAR*)malloc((i + 1) * sizeof(WCHAR));
115
+ if (!*dir) {
116
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
117
+ }
118
+ wcsncpy(*dir, filename, i);
119
+ (*dir)[i] = L'\0';
120
+ }
121
+
122
+ *file = (WCHAR*)malloc((len - i) * sizeof(WCHAR));
123
+ if (!*file) {
124
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
125
+ }
126
+ wcsncpy(*file, filename + i + 1, len - i - 1);
127
+ (*file)[len - i - 1] = L'\0';
128
+ }
129
+
130
+ return 0;
131
+ }
132
+
133
+
134
+ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
135
+ const char* filename, uv_fs_event_cb cb, int flags) {
136
+ int name_size, is_path_dir;
137
+ DWORD attr, last_error;
138
+ WCHAR* dir = NULL, *dir_to_watch, *filenamew = NULL;
139
+ WCHAR short_path[MAX_PATH];
140
+
141
+ uv_fs_event_init_handle(loop, handle, filename, cb);
142
+
143
+ /* Convert name to UTF16. */
144
+ name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(WCHAR);
145
+ filenamew = (WCHAR*)malloc(name_size);
146
+ if (!filenamew) {
147
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
148
+ }
149
+
150
+ if (!uv_utf8_to_utf16(filename, filenamew,
151
+ name_size / sizeof(WCHAR))) {
152
+ uv__set_sys_error(loop, GetLastError());
153
+ return -1;
154
+ }
155
+
156
+ /* Determine whether filename is a file or a directory. */
157
+ attr = GetFileAttributesW(filenamew);
158
+ if (attr == INVALID_FILE_ATTRIBUTES) {
159
+ last_error = GetLastError();
160
+ goto error;
161
+ }
162
+
163
+ is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
164
+
165
+ if (is_path_dir) {
166
+ /* filename is a directory, so that's the directory that we will watch. */
167
+ handle->dirw = filenamew;
168
+ dir_to_watch = filenamew;
169
+ } else {
170
+ /*
171
+ * filename is a file. So we split filename into dir & file parts, and
172
+ * watch the dir directory.
173
+ */
174
+
175
+ /* Convert to short path. */
176
+ if (!GetShortPathNameW(filenamew, short_path, ARRAY_SIZE(short_path))) {
177
+ last_error = GetLastError();
178
+ goto error;
179
+ }
180
+
181
+ if (uv_split_path(filenamew, &dir, &handle->filew) != 0) {
182
+ last_error = GetLastError();
183
+ goto error;
184
+ }
185
+
186
+ if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) {
187
+ last_error = GetLastError();
188
+ goto error;
189
+ }
190
+
191
+ dir_to_watch = dir;
192
+ free(filenamew);
193
+ filenamew = NULL;
194
+ }
195
+
196
+ handle->dir_handle = CreateFileW(dir_to_watch,
197
+ FILE_LIST_DIRECTORY,
198
+ FILE_SHARE_READ | FILE_SHARE_DELETE |
199
+ FILE_SHARE_WRITE,
200
+ NULL,
201
+ OPEN_EXISTING,
202
+ FILE_FLAG_BACKUP_SEMANTICS |
203
+ FILE_FLAG_OVERLAPPED,
204
+ NULL);
205
+
206
+ if (dir) {
207
+ free(dir);
208
+ dir = NULL;
209
+ }
210
+
211
+ if (handle->dir_handle == INVALID_HANDLE_VALUE) {
212
+ last_error = GetLastError();
213
+ goto error;
214
+ }
215
+
216
+ if (CreateIoCompletionPort(handle->dir_handle,
217
+ loop->iocp,
218
+ (ULONG_PTR)handle,
219
+ 0) == NULL) {
220
+ last_error = GetLastError();
221
+ goto error;
222
+ }
223
+
224
+ handle->buffer = (char*)_aligned_malloc(uv_directory_watcher_buffer_size,
225
+ sizeof(DWORD));
226
+ if (!handle->buffer) {
227
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
228
+ }
229
+
230
+ memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped));
231
+
232
+ if (!ReadDirectoryChangesW(handle->dir_handle,
233
+ handle->buffer,
234
+ uv_directory_watcher_buffer_size,
235
+ FALSE,
236
+ FILE_NOTIFY_CHANGE_FILE_NAME |
237
+ FILE_NOTIFY_CHANGE_DIR_NAME |
238
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |
239
+ FILE_NOTIFY_CHANGE_SIZE |
240
+ FILE_NOTIFY_CHANGE_LAST_WRITE |
241
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |
242
+ FILE_NOTIFY_CHANGE_CREATION |
243
+ FILE_NOTIFY_CHANGE_SECURITY,
244
+ NULL,
245
+ &handle->req.overlapped,
246
+ NULL)) {
247
+ last_error = GetLastError();
248
+ goto error;
249
+ }
250
+
251
+ handle->req_pending = 1;
252
+ return 0;
253
+
254
+ error:
255
+ if (handle->filename) {
256
+ free(handle->filename);
257
+ handle->filename = NULL;
258
+ }
259
+
260
+ if (handle->filew) {
261
+ free(handle->filew);
262
+ handle->filew = NULL;
263
+ }
264
+
265
+ if (handle->short_filew) {
266
+ free(handle->short_filew);
267
+ handle->short_filew = NULL;
268
+ }
269
+
270
+ free(filenamew);
271
+
272
+ if (handle->dir_handle != INVALID_HANDLE_VALUE) {
273
+ CloseHandle(handle->dir_handle);
274
+ handle->dir_handle = INVALID_HANDLE_VALUE;
275
+ }
276
+
277
+ if (handle->buffer) {
278
+ _aligned_free(handle->buffer);
279
+ handle->buffer = NULL;
280
+ }
281
+
282
+ uv__set_sys_error(loop, last_error);
283
+ return -1;
284
+ }
285
+
286
+
287
+ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
288
+ uv_fs_event_t* handle) {
289
+ FILE_NOTIFY_INFORMATION* file_info;
290
+ int sizew, size, result;
291
+ char* filename = NULL;
292
+ WCHAR* filenamew, *long_filenamew = NULL;
293
+ DWORD offset = 0;
294
+
295
+ assert(req->type == UV_FS_EVENT_REQ);
296
+ assert(handle->req_pending);
297
+ handle->req_pending = 0;
298
+
299
+ /* If we're closing, don't report any callbacks, and just push the handle */
300
+ /* onto the endgame queue. */
301
+ if (handle->flags & UV__HANDLE_CLOSING) {
302
+ uv_want_endgame(loop, (uv_handle_t*) handle);
303
+ return;
304
+ };
305
+
306
+ file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);
307
+
308
+ if (REQ_SUCCESS(req)) {
309
+ if (req->overlapped.InternalHigh > 0) {
310
+ do {
311
+ file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
312
+ assert(!filename);
313
+ assert(!long_filenamew);
314
+
315
+ /*
316
+ * Fire the event only if we were asked to watch a directory,
317
+ * or if the filename filter matches.
318
+ */
319
+ if (handle->dirw ||
320
+ _wcsnicmp(handle->filew, file_info->FileName,
321
+ file_info->FileNameLength / sizeof(WCHAR)) == 0 ||
322
+ _wcsnicmp(handle->short_filew, file_info->FileName,
323
+ file_info->FileNameLength / sizeof(WCHAR)) == 0) {
324
+
325
+ if (handle->dirw) {
326
+ /*
327
+ * We attempt to convert the file name to its long form for
328
+ * events that still point to valid files on disk.
329
+ * For removed and renamed events, we do not provide the file name.
330
+ */
331
+ if (file_info->Action != FILE_ACTION_REMOVED &&
332
+ file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
333
+ /* Construct a full path to the file. */
334
+ size = wcslen(handle->dirw) +
335
+ file_info->FileNameLength / sizeof(WCHAR) + 2;
336
+
337
+ filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
338
+ if (!filenamew) {
339
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
340
+ }
341
+
342
+ _snwprintf(filenamew, size, L"%s\\%s", handle->dirw,
343
+ file_info->FileName);
344
+
345
+ filenamew[size - 1] = L'\0';
346
+
347
+ /* Convert to long name. */
348
+ size = GetLongPathNameW(filenamew, NULL, 0);
349
+
350
+ if (size) {
351
+ long_filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
352
+ if (!long_filenamew) {
353
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
354
+ }
355
+
356
+ size = GetLongPathNameW(filenamew, long_filenamew, size);
357
+ if (size) {
358
+ long_filenamew[size] = '\0';
359
+ } else {
360
+ free(long_filenamew);
361
+ long_filenamew = NULL;
362
+ }
363
+ }
364
+
365
+ free(filenamew);
366
+
367
+ if (long_filenamew) {
368
+ /* Get the file name out of the long path. */
369
+ result = uv_split_path(long_filenamew, NULL, &filenamew);
370
+ free(long_filenamew);
371
+
372
+ if (result == 0) {
373
+ long_filenamew = filenamew;
374
+ sizew = -1;
375
+ } else {
376
+ long_filenamew = NULL;
377
+ }
378
+ }
379
+
380
+ /*
381
+ * If we couldn't get the long name - just use the name
382
+ * provided by ReadDirectoryChangesW.
383
+ */
384
+ if (!long_filenamew) {
385
+ filenamew = file_info->FileName;
386
+ sizew = file_info->FileNameLength / sizeof(WCHAR);
387
+ }
388
+ } else {
389
+ /* Removed or renamed callbacks don't provide filename. */
390
+ filenamew = NULL;
391
+ }
392
+ } else {
393
+ /* We already have the long name of the file, so just use it. */
394
+ filenamew = handle->filew;
395
+ sizew = -1;
396
+ }
397
+
398
+ if (filenamew) {
399
+ /* Convert the filename to utf8. */
400
+ size = uv_utf16_to_utf8(filenamew,
401
+ sizew,
402
+ NULL,
403
+ 0);
404
+ if (size) {
405
+ filename = (char*)malloc(size + 1);
406
+ if (!filename) {
407
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
408
+ }
409
+
410
+ size = uv_utf16_to_utf8(filenamew,
411
+ sizew,
412
+ filename,
413
+ size);
414
+ if (size) {
415
+ filename[size] = '\0';
416
+ } else {
417
+ free(filename);
418
+ filename = NULL;
419
+ }
420
+ }
421
+ }
422
+
423
+ switch (file_info->Action) {
424
+ case FILE_ACTION_ADDED:
425
+ case FILE_ACTION_REMOVED:
426
+ case FILE_ACTION_RENAMED_OLD_NAME:
427
+ case FILE_ACTION_RENAMED_NEW_NAME:
428
+ handle->cb(handle, filename, UV_RENAME, 0);
429
+ break;
430
+
431
+ case FILE_ACTION_MODIFIED:
432
+ handle->cb(handle, filename, UV_CHANGE, 0);
433
+ break;
434
+ }
435
+
436
+ free(filename);
437
+ filename = NULL;
438
+ free(long_filenamew);
439
+ long_filenamew = NULL;
440
+ }
441
+
442
+ offset = file_info->NextEntryOffset;
443
+ } while (offset && !(handle->flags & UV__HANDLE_CLOSING));
444
+ } else {
445
+ handle->cb(handle, NULL, UV_CHANGE, 0);
446
+ }
447
+ } else {
448
+ uv__set_sys_error(loop, GET_REQ_ERROR(req));
449
+ handle->cb(handle, NULL, 0, -1);
450
+ }
451
+
452
+ if (!(handle->flags & UV__HANDLE_CLOSING)) {
453
+ uv_fs_event_queue_readdirchanges(loop, handle);
454
+ } else {
455
+ uv_want_endgame(loop, (uv_handle_t*)handle);
456
+ }
457
+ }
458
+
459
+
460
+ void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) {
461
+ if (handle->dir_handle != INVALID_HANDLE_VALUE) {
462
+ CloseHandle(handle->dir_handle);
463
+ handle->dir_handle = INVALID_HANDLE_VALUE;
464
+ }
465
+
466
+ if (!handle->req_pending) {
467
+ uv_want_endgame(loop, (uv_handle_t*)handle);
468
+ }
469
+
470
+ uv__handle_closing(handle);
471
+ }
472
+
473
+
474
+ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) {
475
+ if (handle->flags & UV__HANDLE_CLOSING &&
476
+ !handle->req_pending) {
477
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
478
+
479
+ if (handle->buffer) {
480
+ _aligned_free(handle->buffer);
481
+ handle->buffer = NULL;
482
+ }
483
+
484
+ if (handle->filew) {
485
+ free(handle->filew);
486
+ handle->filew = NULL;
487
+ }
488
+
489
+ if (handle->short_filew) {
490
+ free(handle->short_filew);
491
+ handle->short_filew = NULL;
492
+ }
493
+
494
+ if (handle->filename) {
495
+ free(handle->filename);
496
+ handle->filename = NULL;
497
+ }
498
+
499
+ if (handle->dirw) {
500
+ free(handle->dirw);
501
+ handle->dirw = NULL;
502
+ }
503
+
504
+ uv__handle_close(handle);
505
+ }
506
+ }