foolio 0.0.3

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 (261) hide show
  1. data/.gitignore +22 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +21 -0
  6. data/examples/timer.rb +20 -0
  7. data/ext/foolio/extconf.rb +34 -0
  8. data/ext/foolio/foolio_ext.c +921 -0
  9. data/ext/foolio/gen.rb +50 -0
  10. data/ext/foolio/make_table.rb +12 -0
  11. data/ext/foolio/templ +243 -0
  12. data/ext/libuv/.gitignore +33 -0
  13. data/ext/libuv/.mailmap +13 -0
  14. data/ext/libuv/.travis.yml +9 -0
  15. data/ext/libuv/AUTHORS +61 -0
  16. data/ext/libuv/LICENSE +44 -0
  17. data/ext/libuv/Makefile +71 -0
  18. data/ext/libuv/README.md +90 -0
  19. data/ext/libuv/common.gypi +178 -0
  20. data/ext/libuv/gyp_uv +73 -0
  21. data/ext/libuv/include/uv-private/eio.h +403 -0
  22. data/ext/libuv/include/uv-private/ev.h +838 -0
  23. data/ext/libuv/include/uv-private/ngx-queue.h +108 -0
  24. data/ext/libuv/include/uv-private/tree.h +768 -0
  25. data/ext/libuv/include/uv-private/uv-unix.h +324 -0
  26. data/ext/libuv/include/uv-private/uv-win.h +517 -0
  27. data/ext/libuv/include/uv.h +1838 -0
  28. data/ext/libuv/src/fs-poll.c +235 -0
  29. data/ext/libuv/src/inet.c +293 -0
  30. data/ext/libuv/src/unix/async.c +148 -0
  31. data/ext/libuv/src/unix/core.c +696 -0
  32. data/ext/libuv/src/unix/cygwin.c +83 -0
  33. data/ext/libuv/src/unix/darwin.c +342 -0
  34. data/ext/libuv/src/unix/dl.c +83 -0
  35. data/ext/libuv/src/unix/eio/Changes +63 -0
  36. data/ext/libuv/src/unix/eio/LICENSE +36 -0
  37. data/ext/libuv/src/unix/eio/Makefile.am +15 -0
  38. data/ext/libuv/src/unix/eio/aclocal.m4 +8957 -0
  39. data/ext/libuv/src/unix/eio/autogen.sh +3 -0
  40. data/ext/libuv/src/unix/eio/config.h.in +86 -0
  41. data/ext/libuv/src/unix/eio/config_cygwin.h +80 -0
  42. data/ext/libuv/src/unix/eio/config_darwin.h +141 -0
  43. data/ext/libuv/src/unix/eio/config_freebsd.h +81 -0
  44. data/ext/libuv/src/unix/eio/config_linux.h +94 -0
  45. data/ext/libuv/src/unix/eio/config_netbsd.h +81 -0
  46. data/ext/libuv/src/unix/eio/config_openbsd.h +137 -0
  47. data/ext/libuv/src/unix/eio/config_sunos.h +84 -0
  48. data/ext/libuv/src/unix/eio/configure.ac +22 -0
  49. data/ext/libuv/src/unix/eio/demo.c +194 -0
  50. data/ext/libuv/src/unix/eio/ecb.h +370 -0
  51. data/ext/libuv/src/unix/eio/eio.3 +3428 -0
  52. data/ext/libuv/src/unix/eio/eio.c +2593 -0
  53. data/ext/libuv/src/unix/eio/eio.pod +969 -0
  54. data/ext/libuv/src/unix/eio/libeio.m4 +195 -0
  55. data/ext/libuv/src/unix/eio/xthread.h +164 -0
  56. data/ext/libuv/src/unix/error.c +105 -0
  57. data/ext/libuv/src/unix/ev/Changes +388 -0
  58. data/ext/libuv/src/unix/ev/LICENSE +36 -0
  59. data/ext/libuv/src/unix/ev/Makefile.am +18 -0
  60. data/ext/libuv/src/unix/ev/Makefile.in +771 -0
  61. data/ext/libuv/src/unix/ev/README +58 -0
  62. data/ext/libuv/src/unix/ev/aclocal.m4 +8957 -0
  63. data/ext/libuv/src/unix/ev/autogen.sh +6 -0
  64. data/ext/libuv/src/unix/ev/config.guess +1526 -0
  65. data/ext/libuv/src/unix/ev/config.h.in +125 -0
  66. data/ext/libuv/src/unix/ev/config.sub +1658 -0
  67. data/ext/libuv/src/unix/ev/config_cygwin.h +123 -0
  68. data/ext/libuv/src/unix/ev/config_darwin.h +122 -0
  69. data/ext/libuv/src/unix/ev/config_freebsd.h +120 -0
  70. data/ext/libuv/src/unix/ev/config_linux.h +141 -0
  71. data/ext/libuv/src/unix/ev/config_netbsd.h +120 -0
  72. data/ext/libuv/src/unix/ev/config_openbsd.h +126 -0
  73. data/ext/libuv/src/unix/ev/config_sunos.h +122 -0
  74. data/ext/libuv/src/unix/ev/configure +13037 -0
  75. data/ext/libuv/src/unix/ev/configure.ac +18 -0
  76. data/ext/libuv/src/unix/ev/depcomp +630 -0
  77. data/ext/libuv/src/unix/ev/ev++.h +816 -0
  78. data/ext/libuv/src/unix/ev/ev.3 +5311 -0
  79. data/ext/libuv/src/unix/ev/ev.c +3925 -0
  80. data/ext/libuv/src/unix/ev/ev.pod +5243 -0
  81. data/ext/libuv/src/unix/ev/ev_epoll.c +266 -0
  82. data/ext/libuv/src/unix/ev/ev_kqueue.c +235 -0
  83. data/ext/libuv/src/unix/ev/ev_poll.c +148 -0
  84. data/ext/libuv/src/unix/ev/ev_port.c +179 -0
  85. data/ext/libuv/src/unix/ev/ev_select.c +310 -0
  86. data/ext/libuv/src/unix/ev/ev_vars.h +203 -0
  87. data/ext/libuv/src/unix/ev/ev_win32.c +153 -0
  88. data/ext/libuv/src/unix/ev/ev_wrap.h +196 -0
  89. data/ext/libuv/src/unix/ev/event.c +402 -0
  90. data/ext/libuv/src/unix/ev/event.h +170 -0
  91. data/ext/libuv/src/unix/ev/install-sh +294 -0
  92. data/ext/libuv/src/unix/ev/libev.m4 +39 -0
  93. data/ext/libuv/src/unix/ev/ltmain.sh +8413 -0
  94. data/ext/libuv/src/unix/ev/missing +336 -0
  95. data/ext/libuv/src/unix/ev/mkinstalldirs +111 -0
  96. data/ext/libuv/src/unix/freebsd.c +326 -0
  97. data/ext/libuv/src/unix/fs.c +739 -0
  98. data/ext/libuv/src/unix/internal.h +188 -0
  99. data/ext/libuv/src/unix/kqueue.c +120 -0
  100. data/ext/libuv/src/unix/linux/inotify.c +239 -0
  101. data/ext/libuv/src/unix/linux/linux-core.c +557 -0
  102. data/ext/libuv/src/unix/linux/syscalls.c +388 -0
  103. data/ext/libuv/src/unix/linux/syscalls.h +124 -0
  104. data/ext/libuv/src/unix/loop-watcher.c +62 -0
  105. data/ext/libuv/src/unix/loop.c +94 -0
  106. data/ext/libuv/src/unix/netbsd.c +108 -0
  107. data/ext/libuv/src/unix/openbsd.c +295 -0
  108. data/ext/libuv/src/unix/pipe.c +259 -0
  109. data/ext/libuv/src/unix/poll.c +114 -0
  110. data/ext/libuv/src/unix/process.c +495 -0
  111. data/ext/libuv/src/unix/signal.c +269 -0
  112. data/ext/libuv/src/unix/stream.c +990 -0
  113. data/ext/libuv/src/unix/sunos.c +481 -0
  114. data/ext/libuv/src/unix/tcp.c +393 -0
  115. data/ext/libuv/src/unix/thread.c +251 -0
  116. data/ext/libuv/src/unix/timer.c +136 -0
  117. data/ext/libuv/src/unix/tty.c +145 -0
  118. data/ext/libuv/src/unix/udp.c +659 -0
  119. data/ext/libuv/src/unix/uv-eio.c +107 -0
  120. data/ext/libuv/src/unix/uv-eio.h +13 -0
  121. data/ext/libuv/src/uv-common.c +380 -0
  122. data/ext/libuv/src/uv-common.h +170 -0
  123. data/ext/libuv/src/win/async.c +100 -0
  124. data/ext/libuv/src/win/atomicops-inl.h +56 -0
  125. data/ext/libuv/src/win/core.c +278 -0
  126. data/ext/libuv/src/win/dl.c +86 -0
  127. data/ext/libuv/src/win/error.c +155 -0
  128. data/ext/libuv/src/win/fs-event.c +510 -0
  129. data/ext/libuv/src/win/fs.c +1948 -0
  130. data/ext/libuv/src/win/getaddrinfo.c +365 -0
  131. data/ext/libuv/src/win/handle-inl.h +149 -0
  132. data/ext/libuv/src/win/handle.c +154 -0
  133. data/ext/libuv/src/win/internal.h +343 -0
  134. data/ext/libuv/src/win/loop-watcher.c +122 -0
  135. data/ext/libuv/src/win/pipe.c +1672 -0
  136. data/ext/libuv/src/win/poll.c +616 -0
  137. data/ext/libuv/src/win/process-stdio.c +500 -0
  138. data/ext/libuv/src/win/process.c +1013 -0
  139. data/ext/libuv/src/win/req-inl.h +220 -0
  140. data/ext/libuv/src/win/req.c +25 -0
  141. data/ext/libuv/src/win/signal.c +57 -0
  142. data/ext/libuv/src/win/stream-inl.h +67 -0
  143. data/ext/libuv/src/win/stream.c +167 -0
  144. data/ext/libuv/src/win/tcp.c +1394 -0
  145. data/ext/libuv/src/win/thread.c +372 -0
  146. data/ext/libuv/src/win/threadpool.c +74 -0
  147. data/ext/libuv/src/win/timer.c +224 -0
  148. data/ext/libuv/src/win/tty.c +1799 -0
  149. data/ext/libuv/src/win/udp.c +716 -0
  150. data/ext/libuv/src/win/util.c +864 -0
  151. data/ext/libuv/src/win/winapi.c +132 -0
  152. data/ext/libuv/src/win/winapi.h +4452 -0
  153. data/ext/libuv/src/win/winsock.c +557 -0
  154. data/ext/libuv/src/win/winsock.h +171 -0
  155. data/ext/libuv/test/benchmark-async-pummel.c +97 -0
  156. data/ext/libuv/test/benchmark-async.c +137 -0
  157. data/ext/libuv/test/benchmark-fs-stat.c +135 -0
  158. data/ext/libuv/test/benchmark-getaddrinfo.c +94 -0
  159. data/ext/libuv/test/benchmark-list.h +127 -0
  160. data/ext/libuv/test/benchmark-loop-count.c +88 -0
  161. data/ext/libuv/test/benchmark-million-timers.c +65 -0
  162. data/ext/libuv/test/benchmark-ping-pongs.c +213 -0
  163. data/ext/libuv/test/benchmark-pound.c +324 -0
  164. data/ext/libuv/test/benchmark-pump.c +462 -0
  165. data/ext/libuv/test/benchmark-sizes.c +44 -0
  166. data/ext/libuv/test/benchmark-spawn.c +162 -0
  167. data/ext/libuv/test/benchmark-tcp-write-batch.c +140 -0
  168. data/ext/libuv/test/benchmark-thread.c +64 -0
  169. data/ext/libuv/test/benchmark-udp-packet-storm.c +247 -0
  170. data/ext/libuv/test/blackhole-server.c +118 -0
  171. data/ext/libuv/test/dns-server.c +321 -0
  172. data/ext/libuv/test/echo-server.c +378 -0
  173. data/ext/libuv/test/fixtures/empty_file +0 -0
  174. data/ext/libuv/test/fixtures/load_error.node +1 -0
  175. data/ext/libuv/test/run-benchmarks.c +64 -0
  176. data/ext/libuv/test/run-tests.c +138 -0
  177. data/ext/libuv/test/runner-unix.c +295 -0
  178. data/ext/libuv/test/runner-unix.h +36 -0
  179. data/ext/libuv/test/runner-win.c +285 -0
  180. data/ext/libuv/test/runner-win.h +42 -0
  181. data/ext/libuv/test/runner.c +355 -0
  182. data/ext/libuv/test/runner.h +159 -0
  183. data/ext/libuv/test/task.h +112 -0
  184. data/ext/libuv/test/test-async.c +118 -0
  185. data/ext/libuv/test/test-callback-order.c +76 -0
  186. data/ext/libuv/test/test-callback-stack.c +203 -0
  187. data/ext/libuv/test/test-connection-fail.c +148 -0
  188. data/ext/libuv/test/test-cwd-and-chdir.c +64 -0
  189. data/ext/libuv/test/test-delayed-accept.c +188 -0
  190. data/ext/libuv/test/test-dlerror.c +58 -0
  191. data/ext/libuv/test/test-error.c +59 -0
  192. data/ext/libuv/test/test-fail-always.c +29 -0
  193. data/ext/libuv/test/test-fs-event.c +474 -0
  194. data/ext/libuv/test/test-fs-poll.c +146 -0
  195. data/ext/libuv/test/test-fs.c +1843 -0
  196. data/ext/libuv/test/test-get-currentexe.c +63 -0
  197. data/ext/libuv/test/test-get-loadavg.c +36 -0
  198. data/ext/libuv/test/test-get-memory.c +38 -0
  199. data/ext/libuv/test/test-getaddrinfo.c +122 -0
  200. data/ext/libuv/test/test-getsockname.c +342 -0
  201. data/ext/libuv/test/test-hrtime.c +54 -0
  202. data/ext/libuv/test/test-idle.c +81 -0
  203. data/ext/libuv/test/test-ipc-send-recv.c +209 -0
  204. data/ext/libuv/test/test-ipc.c +620 -0
  205. data/ext/libuv/test/test-list.h +427 -0
  206. data/ext/libuv/test/test-loop-handles.c +336 -0
  207. data/ext/libuv/test/test-multiple-listen.c +102 -0
  208. data/ext/libuv/test/test-mutexes.c +63 -0
  209. data/ext/libuv/test/test-pass-always.c +28 -0
  210. data/ext/libuv/test/test-ping-pong.c +253 -0
  211. data/ext/libuv/test/test-pipe-bind-error.c +140 -0
  212. data/ext/libuv/test/test-pipe-connect-error.c +96 -0
  213. data/ext/libuv/test/test-platform-output.c +87 -0
  214. data/ext/libuv/test/test-poll-close.c +72 -0
  215. data/ext/libuv/test/test-poll.c +573 -0
  216. data/ext/libuv/test/test-process-title.c +49 -0
  217. data/ext/libuv/test/test-ref.c +338 -0
  218. data/ext/libuv/test/test-run-once.c +48 -0
  219. data/ext/libuv/test/test-semaphore.c +111 -0
  220. data/ext/libuv/test/test-shutdown-close.c +103 -0
  221. data/ext/libuv/test/test-shutdown-eof.c +183 -0
  222. data/ext/libuv/test/test-signal.c +162 -0
  223. data/ext/libuv/test/test-spawn.c +863 -0
  224. data/ext/libuv/test/test-stdio-over-pipes.c +246 -0
  225. data/ext/libuv/test/test-tcp-bind-error.c +191 -0
  226. data/ext/libuv/test/test-tcp-bind6-error.c +154 -0
  227. data/ext/libuv/test/test-tcp-close-while-connecting.c +80 -0
  228. data/ext/libuv/test/test-tcp-close.c +129 -0
  229. data/ext/libuv/test/test-tcp-connect-error-after-write.c +95 -0
  230. data/ext/libuv/test/test-tcp-connect-error.c +70 -0
  231. data/ext/libuv/test/test-tcp-connect-timeout.c +85 -0
  232. data/ext/libuv/test/test-tcp-connect6-error.c +68 -0
  233. data/ext/libuv/test/test-tcp-flags.c +51 -0
  234. data/ext/libuv/test/test-tcp-shutdown-after-write.c +131 -0
  235. data/ext/libuv/test/test-tcp-unexpected-read.c +113 -0
  236. data/ext/libuv/test/test-tcp-write-error.c +168 -0
  237. data/ext/libuv/test/test-tcp-write-to-half-open-connection.c +135 -0
  238. data/ext/libuv/test/test-tcp-writealot.c +170 -0
  239. data/ext/libuv/test/test-thread.c +183 -0
  240. data/ext/libuv/test/test-threadpool.c +57 -0
  241. data/ext/libuv/test/test-timer-again.c +141 -0
  242. data/ext/libuv/test/test-timer.c +152 -0
  243. data/ext/libuv/test/test-tty.c +110 -0
  244. data/ext/libuv/test/test-udp-dgram-too-big.c +86 -0
  245. data/ext/libuv/test/test-udp-ipv6.c +156 -0
  246. data/ext/libuv/test/test-udp-multicast-join.c +139 -0
  247. data/ext/libuv/test/test-udp-multicast-ttl.c +86 -0
  248. data/ext/libuv/test/test-udp-options.c +86 -0
  249. data/ext/libuv/test/test-udp-send-and-recv.c +208 -0
  250. data/ext/libuv/test/test-util.c +97 -0
  251. data/ext/libuv/test/test-walk-handles.c +77 -0
  252. data/ext/libuv/uv.gyp +375 -0
  253. data/ext/libuv/vcbuild.bat +105 -0
  254. data/foolio.gemspec +18 -0
  255. data/lib/foolio.rb +9 -0
  256. data/lib/foolio/handle.rb +27 -0
  257. data/lib/foolio/listener.rb +26 -0
  258. data/lib/foolio/loop.rb +79 -0
  259. data/lib/foolio/stream.rb +109 -0
  260. data/lib/foolio/version.rb +3 -0
  261. metadata +309 -0
@@ -0,0 +1,146 @@
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to
5
+ * deal in the Software without restriction, including without limitation the
6
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ * sell copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19
+ * IN THE SOFTWARE.
20
+ */
21
+
22
+ #include "uv.h"
23
+ #include "task.h"
24
+
25
+ #include <string.h>
26
+
27
+ #define FIXTURE "testfile"
28
+
29
+ static void timer_cb(uv_timer_t* handle, int status);
30
+ static void close_cb(uv_handle_t* handle);
31
+ static void poll_cb(uv_fs_poll_t* handle,
32
+ int status,
33
+ const uv_statbuf_t* prev,
34
+ const uv_statbuf_t* curr);
35
+
36
+ static uv_fs_poll_t poll_handle;
37
+ static uv_timer_t timer_handle;
38
+ static uv_loop_t* loop;
39
+
40
+ static int poll_cb_called;
41
+ static int timer_cb_called;
42
+ static int close_cb_called;
43
+
44
+
45
+ static void touch_file(const char* path) {
46
+ static int count;
47
+ FILE* fp;
48
+ int i;
49
+
50
+ ASSERT((fp = fopen(FIXTURE, "w+")));
51
+
52
+ /* Need to change the file size because the poller may not pick up
53
+ * sub-second mtime changes.
54
+ */
55
+ i = ++count;
56
+
57
+ while (i--)
58
+ fputc('*', fp);
59
+
60
+ fclose(fp);
61
+ }
62
+
63
+
64
+ static void close_cb(uv_handle_t* handle) {
65
+ close_cb_called++;
66
+ }
67
+
68
+
69
+ static void timer_cb(uv_timer_t* handle, int status) {
70
+ touch_file(FIXTURE);
71
+ timer_cb_called++;
72
+ }
73
+
74
+
75
+ static void poll_cb(uv_fs_poll_t* handle,
76
+ int status,
77
+ const uv_statbuf_t* prev,
78
+ const uv_statbuf_t* curr) {
79
+ const static uv_statbuf_t zero_statbuf;
80
+
81
+ ASSERT(handle == &poll_handle);
82
+ ASSERT(uv_is_active((uv_handle_t*)handle));
83
+ ASSERT(prev != NULL);
84
+ ASSERT(curr != NULL);
85
+
86
+ switch (poll_cb_called++) {
87
+ case 0:
88
+ ASSERT(status == -1);
89
+ ASSERT(uv_last_error(loop).code == UV_ENOENT);
90
+ ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
91
+ ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
92
+ touch_file(FIXTURE);
93
+ break;
94
+
95
+ case 1:
96
+ ASSERT(status == 0);
97
+ ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
98
+ ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
99
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 20, 0));
100
+ break;
101
+
102
+ case 2:
103
+ ASSERT(status == 0);
104
+ ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
105
+ ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
106
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 200, 0));
107
+ break;
108
+
109
+ case 3:
110
+ ASSERT(status == 0);
111
+ ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
112
+ ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
113
+ remove(FIXTURE);
114
+ break;
115
+
116
+ case 4:
117
+ ASSERT(status == -1);
118
+ ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
119
+ ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
120
+ ASSERT(uv_last_error(loop).code == UV_ENOENT);
121
+ uv_close((uv_handle_t*)handle, close_cb);
122
+ break;
123
+
124
+ default:
125
+ ASSERT(0);
126
+ }
127
+ }
128
+
129
+
130
+ TEST_IMPL(fs_poll) {
131
+ loop = uv_default_loop();
132
+
133
+ remove(FIXTURE);
134
+
135
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
136
+ ASSERT(0 == uv_fs_poll_init(loop, &poll_handle));
137
+ ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb, FIXTURE, 100));
138
+ ASSERT(0 == uv_run(loop));
139
+
140
+ ASSERT(poll_cb_called == 5);
141
+ ASSERT(timer_cb_called == 2);
142
+ ASSERT(close_cb_called == 1);
143
+ uv_loop_delete(loop);
144
+
145
+ return 0;
146
+ }
@@ -0,0 +1,1843 @@
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
+ /* FIXME we shouldn't need to branch in this file */
23
+ #define UNIX (defined(__unix__) || defined(__POSIX__) || defined(__APPLE__))
24
+
25
+ #include "uv.h"
26
+ #include "task.h"
27
+
28
+ #include <errno.h>
29
+ #include <string.h> /* memset */
30
+ #include <fcntl.h>
31
+ #include <sys/stat.h>
32
+
33
+
34
+ #if UNIX
35
+ #include <unistd.h> /* unlink, rmdir, etc. */
36
+ #else
37
+ # include <direct.h>
38
+ # include <io.h>
39
+ # define unlink _unlink
40
+ # define rmdir _rmdir
41
+ # define stat _stati64
42
+ # define open _open
43
+ # define write _write
44
+ # define lseek _lseek
45
+ # define close _close
46
+ #endif
47
+
48
+ #define TOO_LONG_NAME_LENGTH 65536
49
+ #define PATHMAX 1024
50
+
51
+ typedef struct {
52
+ const char* path;
53
+ double atime;
54
+ double mtime;
55
+ } utime_check_t;
56
+
57
+
58
+ static int close_cb_count;
59
+ static int create_cb_count;
60
+ static int open_cb_count;
61
+ static int read_cb_count;
62
+ static int write_cb_count;
63
+ static int unlink_cb_count;
64
+ static int mkdir_cb_count;
65
+ static int rmdir_cb_count;
66
+ static int readdir_cb_count;
67
+ static int stat_cb_count;
68
+ static int rename_cb_count;
69
+ static int fsync_cb_count;
70
+ static int fdatasync_cb_count;
71
+ static int ftruncate_cb_count;
72
+ static int sendfile_cb_count;
73
+ static int fstat_cb_count;
74
+ static int chmod_cb_count;
75
+ static int fchmod_cb_count;
76
+ static int chown_cb_count;
77
+ static int fchown_cb_count;
78
+ static int link_cb_count;
79
+ static int symlink_cb_count;
80
+ static int readlink_cb_count;
81
+ static int utime_cb_count;
82
+ static int futime_cb_count;
83
+
84
+ static uv_loop_t* loop;
85
+
86
+ static uv_fs_t open_req1;
87
+ static uv_fs_t open_req2;
88
+ static uv_fs_t read_req;
89
+ static uv_fs_t write_req;
90
+ static uv_fs_t unlink_req;
91
+ static uv_fs_t close_req;
92
+ static uv_fs_t mkdir_req;
93
+ static uv_fs_t rmdir_req;
94
+ static uv_fs_t readdir_req;
95
+ static uv_fs_t stat_req;
96
+ static uv_fs_t rename_req;
97
+ static uv_fs_t fsync_req;
98
+ static uv_fs_t fdatasync_req;
99
+ static uv_fs_t ftruncate_req;
100
+ static uv_fs_t sendfile_req;
101
+ static uv_fs_t utime_req;
102
+ static uv_fs_t futime_req;
103
+
104
+ static char buf[32];
105
+ static char test_buf[] = "test-buffer\n";
106
+
107
+
108
+ void check_permission(const char* filename, int mode) {
109
+ int r;
110
+ uv_fs_t req;
111
+ struct stat* s;
112
+
113
+ r = uv_fs_stat(uv_default_loop(), &req, filename, NULL);
114
+ ASSERT(r == 0);
115
+ ASSERT(req.result == 0);
116
+
117
+ s = req.ptr;
118
+ #ifdef _WIN32
119
+ /*
120
+ * On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit,
121
+ * so only testing for the specified flags.
122
+ */
123
+ ASSERT((s->st_mode & 0777) & mode);
124
+ #else
125
+ ASSERT((s->st_mode & 0777) == mode);
126
+ #endif
127
+
128
+ uv_fs_req_cleanup(&req);
129
+ }
130
+
131
+
132
+ static void link_cb(uv_fs_t* req) {
133
+ ASSERT(req->fs_type == UV_FS_LINK);
134
+ ASSERT(req->result == 0);
135
+ link_cb_count++;
136
+ uv_fs_req_cleanup(req);
137
+ }
138
+
139
+
140
+ static void symlink_cb(uv_fs_t* req) {
141
+ ASSERT(req->fs_type == UV_FS_SYMLINK);
142
+ ASSERT(req->result == 0);
143
+ symlink_cb_count++;
144
+ uv_fs_req_cleanup(req);
145
+ }
146
+
147
+ static void readlink_cb(uv_fs_t* req) {
148
+ ASSERT(req->fs_type == UV_FS_READLINK);
149
+ ASSERT(req->result == 0);
150
+ ASSERT(strcmp(req->ptr, "test_file_symlink2") == 0);
151
+ readlink_cb_count++;
152
+ uv_fs_req_cleanup(req);
153
+ }
154
+
155
+ static void fchmod_cb(uv_fs_t* req) {
156
+ ASSERT(req->fs_type == UV_FS_FCHMOD);
157
+ ASSERT(req->result == 0);
158
+ fchmod_cb_count++;
159
+ uv_fs_req_cleanup(req);
160
+ check_permission("test_file", *(int*)req->data);
161
+ }
162
+
163
+
164
+ static void chmod_cb(uv_fs_t* req) {
165
+ ASSERT(req->fs_type == UV_FS_CHMOD);
166
+ ASSERT(req->result == 0);
167
+ chmod_cb_count++;
168
+ uv_fs_req_cleanup(req);
169
+ check_permission("test_file", *(int*)req->data);
170
+ }
171
+
172
+
173
+ static void fchown_cb(uv_fs_t* req) {
174
+ ASSERT(req->fs_type == UV_FS_FCHOWN);
175
+ ASSERT(req->result == 0);
176
+ fchown_cb_count++;
177
+ uv_fs_req_cleanup(req);
178
+ }
179
+
180
+
181
+ static void chown_cb(uv_fs_t* req) {
182
+ ASSERT(req->fs_type == UV_FS_CHOWN);
183
+ ASSERT(req->result == 0);
184
+ chown_cb_count++;
185
+ uv_fs_req_cleanup(req);
186
+ }
187
+
188
+ static void chown_root_cb(uv_fs_t* req) {
189
+ ASSERT(req->fs_type == UV_FS_CHOWN);
190
+ #ifdef _WIN32
191
+ /* On windows, chown is a no-op and always succeeds. */
192
+ ASSERT(req->result == 0);
193
+ #else
194
+ /* On unix, chown'ing the root directory is not allowed. */
195
+ ASSERT(req->result == -1);
196
+ ASSERT(req->errorno == UV_EPERM);
197
+ #endif
198
+ chown_cb_count++;
199
+ uv_fs_req_cleanup(req);
200
+ }
201
+
202
+ static void unlink_cb(uv_fs_t* req) {
203
+ ASSERT(req == &unlink_req);
204
+ ASSERT(req->fs_type == UV_FS_UNLINK);
205
+ ASSERT(req->result != -1);
206
+ unlink_cb_count++;
207
+ uv_fs_req_cleanup(req);
208
+ }
209
+
210
+ static void fstat_cb(uv_fs_t* req) {
211
+ struct stat* s = req->ptr;
212
+ ASSERT(req->fs_type == UV_FS_FSTAT);
213
+ ASSERT(req->result == 0);
214
+ ASSERT(s->st_size == sizeof(test_buf));
215
+ uv_fs_req_cleanup(req);
216
+ fstat_cb_count++;
217
+ }
218
+
219
+
220
+ static void close_cb(uv_fs_t* req) {
221
+ int r;
222
+ ASSERT(req == &close_req);
223
+ ASSERT(req->fs_type == UV_FS_CLOSE);
224
+ ASSERT(req->result != -1);
225
+ close_cb_count++;
226
+ uv_fs_req_cleanup(req);
227
+ if (close_cb_count == 3) {
228
+ r = uv_fs_unlink(loop, &unlink_req, "test_file2", unlink_cb);
229
+ ASSERT(r == 0);
230
+ }
231
+ }
232
+
233
+
234
+ static void ftruncate_cb(uv_fs_t* req) {
235
+ int r;
236
+ ASSERT(req == &ftruncate_req);
237
+ ASSERT(req->fs_type == UV_FS_FTRUNCATE);
238
+ ASSERT(req->result != -1);
239
+ ftruncate_cb_count++;
240
+ uv_fs_req_cleanup(req);
241
+ r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
242
+ ASSERT(r == 0);
243
+ }
244
+
245
+
246
+ static void read_cb(uv_fs_t* req) {
247
+ int r;
248
+ ASSERT(req == &read_req);
249
+ ASSERT(req->fs_type == UV_FS_READ);
250
+ ASSERT(req->result != -1);
251
+ read_cb_count++;
252
+ uv_fs_req_cleanup(req);
253
+ if (read_cb_count == 1) {
254
+ ASSERT(strcmp(buf, test_buf) == 0);
255
+ r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7,
256
+ ftruncate_cb);
257
+ } else {
258
+ ASSERT(strcmp(buf, "test-bu") == 0);
259
+ r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
260
+ }
261
+ ASSERT(r == 0);
262
+ }
263
+
264
+
265
+ static void open_cb(uv_fs_t* req) {
266
+ int r;
267
+ ASSERT(req == &open_req1);
268
+ ASSERT(req->fs_type == UV_FS_OPEN);
269
+ if (req->result < 0) {
270
+ /* TODO get error with uv_last_error() */
271
+ fprintf(stderr, "async open error: %d\n", req->errorno);
272
+ ASSERT(0);
273
+ }
274
+ open_cb_count++;
275
+ ASSERT(req->path);
276
+ ASSERT(memcmp(req->path, "test_file2\0", 11) == 0);
277
+ uv_fs_req_cleanup(req);
278
+ memset(buf, 0, sizeof(buf));
279
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
280
+ read_cb);
281
+ ASSERT(r == 0);
282
+ }
283
+
284
+
285
+ static void open_cb_simple(uv_fs_t* req) {
286
+ ASSERT(req->fs_type == UV_FS_OPEN);
287
+ if (req->result < 0) {
288
+ /* TODO get error with uv_last_error() */
289
+ fprintf(stderr, "async open error: %d\n", req->errorno);
290
+ ASSERT(0);
291
+ }
292
+ open_cb_count++;
293
+ ASSERT(req->path);
294
+ uv_fs_req_cleanup(req);
295
+ }
296
+
297
+
298
+ static void fsync_cb(uv_fs_t* req) {
299
+ int r;
300
+ ASSERT(req == &fsync_req);
301
+ ASSERT(req->fs_type == UV_FS_FSYNC);
302
+ ASSERT(req->result != -1);
303
+ fsync_cb_count++;
304
+ uv_fs_req_cleanup(req);
305
+ r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
306
+ ASSERT(r == 0);
307
+ }
308
+
309
+
310
+ static void fdatasync_cb(uv_fs_t* req) {
311
+ int r;
312
+ ASSERT(req == &fdatasync_req);
313
+ ASSERT(req->fs_type == UV_FS_FDATASYNC);
314
+ ASSERT(req->result != -1);
315
+ fdatasync_cb_count++;
316
+ uv_fs_req_cleanup(req);
317
+ r = uv_fs_fsync(loop, &fsync_req, open_req1.result, fsync_cb);
318
+ ASSERT(r == 0);
319
+ }
320
+
321
+
322
+ static void write_cb(uv_fs_t* req) {
323
+ int r;
324
+ ASSERT(req == &write_req);
325
+ ASSERT(req->fs_type == UV_FS_WRITE);
326
+ ASSERT(req->result != -1);
327
+ write_cb_count++;
328
+ uv_fs_req_cleanup(req);
329
+ r = uv_fs_fdatasync(loop, &fdatasync_req, open_req1.result, fdatasync_cb);
330
+ ASSERT(r == 0);
331
+ }
332
+
333
+
334
+ static void create_cb(uv_fs_t* req) {
335
+ int r;
336
+ ASSERT(req == &open_req1);
337
+ ASSERT(req->fs_type == UV_FS_OPEN);
338
+ ASSERT(req->result != -1);
339
+ create_cb_count++;
340
+ uv_fs_req_cleanup(req);
341
+ r = uv_fs_write(loop, &write_req, req->result, test_buf, sizeof(test_buf),
342
+ -1, write_cb);
343
+ ASSERT(r == 0);
344
+ }
345
+
346
+
347
+ static void rename_cb(uv_fs_t* req) {
348
+ ASSERT(req == &rename_req);
349
+ ASSERT(req->fs_type == UV_FS_RENAME);
350
+ ASSERT(req->result != -1);
351
+ rename_cb_count++;
352
+ uv_fs_req_cleanup(req);
353
+ }
354
+
355
+
356
+ static void mkdir_cb(uv_fs_t* req) {
357
+ ASSERT(req == &mkdir_req);
358
+ ASSERT(req->fs_type == UV_FS_MKDIR);
359
+ ASSERT(req->result != -1);
360
+ mkdir_cb_count++;
361
+ ASSERT(req->path);
362
+ ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
363
+ uv_fs_req_cleanup(req);
364
+ }
365
+
366
+
367
+ static void rmdir_cb(uv_fs_t* req) {
368
+ ASSERT(req == &rmdir_req);
369
+ ASSERT(req->fs_type == UV_FS_RMDIR);
370
+ ASSERT(req->result != -1);
371
+ rmdir_cb_count++;
372
+ ASSERT(req->path);
373
+ ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
374
+ uv_fs_req_cleanup(req);
375
+ }
376
+
377
+
378
+ static void readdir_cb(uv_fs_t* req) {
379
+ ASSERT(req == &readdir_req);
380
+ ASSERT(req->fs_type == UV_FS_READDIR);
381
+ ASSERT(req->result == 2);
382
+ ASSERT(req->ptr);
383
+ ASSERT(memcmp(req->ptr, "file1\0file2\0", 12) == 0
384
+ || memcmp(req->ptr, "file2\0file1\0", 12) == 0);
385
+ readdir_cb_count++;
386
+ ASSERT(req->path);
387
+ ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
388
+ uv_fs_req_cleanup(req);
389
+ ASSERT(!req->ptr);
390
+ }
391
+
392
+
393
+ static void empty_readdir_cb(uv_fs_t* req) {
394
+ ASSERT(req == &readdir_req);
395
+ ASSERT(req->fs_type == UV_FS_READDIR);
396
+ ASSERT(req->result == 0);
397
+ ASSERT(req->ptr == NULL);
398
+ uv_fs_req_cleanup(req);
399
+ readdir_cb_count++;
400
+ }
401
+
402
+
403
+ static void file_readdir_cb(uv_fs_t* req) {
404
+ ASSERT(req == &readdir_req);
405
+ ASSERT(req->fs_type == UV_FS_READDIR);
406
+ ASSERT(req->result == -1);
407
+ ASSERT(req->ptr == NULL);
408
+ ASSERT(uv_last_error(req->loop).code == UV_ENOTDIR);
409
+ uv_fs_req_cleanup(req);
410
+ readdir_cb_count++;
411
+ }
412
+
413
+
414
+ static void stat_cb(uv_fs_t* req) {
415
+ ASSERT(req == &stat_req);
416
+ ASSERT(req->fs_type == UV_FS_STAT || req->fs_type == UV_FS_LSTAT);
417
+ ASSERT(req->result != -1);
418
+ ASSERT(req->ptr);
419
+ stat_cb_count++;
420
+ uv_fs_req_cleanup(req);
421
+ ASSERT(!req->ptr);
422
+ }
423
+
424
+
425
+ static void sendfile_cb(uv_fs_t* req) {
426
+ ASSERT(req == &sendfile_req);
427
+ ASSERT(req->fs_type == UV_FS_SENDFILE);
428
+ ASSERT(req->result == 65546);
429
+ sendfile_cb_count++;
430
+ uv_fs_req_cleanup(req);
431
+ }
432
+
433
+
434
+ static void open_noent_cb(uv_fs_t* req) {
435
+ ASSERT(req->fs_type == UV_FS_OPEN);
436
+ ASSERT(req->errorno == UV_ENOENT);
437
+ ASSERT(req->result == -1);
438
+ open_cb_count++;
439
+ uv_fs_req_cleanup(req);
440
+ }
441
+
442
+ static void open_nametoolong_cb(uv_fs_t* req) {
443
+ ASSERT(req->fs_type == UV_FS_OPEN);
444
+ ASSERT(req->errorno == UV_ENAMETOOLONG);
445
+ ASSERT(req->result == -1);
446
+ open_cb_count++;
447
+ uv_fs_req_cleanup(req);
448
+ }
449
+
450
+ static void open_loop_cb(uv_fs_t* req) {
451
+ ASSERT(req->fs_type == UV_FS_OPEN);
452
+ ASSERT(req->errorno == UV_ELOOP);
453
+ ASSERT(req->result == -1);
454
+ open_cb_count++;
455
+ uv_fs_req_cleanup(req);
456
+ }
457
+
458
+
459
+ TEST_IMPL(fs_file_noent) {
460
+ uv_fs_t req;
461
+ int r;
462
+
463
+ loop = uv_default_loop();
464
+
465
+ r = uv_fs_open(loop, &req, "does_not_exist", O_RDONLY, 0, NULL);
466
+ ASSERT(r == -1);
467
+ ASSERT(req.result == -1);
468
+ ASSERT(uv_last_error(loop).code == UV_ENOENT);
469
+ uv_fs_req_cleanup(&req);
470
+
471
+ r = uv_fs_open(loop, &req, "does_not_exist", O_RDONLY, 0, open_noent_cb);
472
+ ASSERT(r == 0);
473
+
474
+ ASSERT(open_cb_count == 0);
475
+ uv_run(loop);
476
+ ASSERT(open_cb_count == 1);
477
+
478
+ /* TODO add EACCES test */
479
+
480
+ return 0;
481
+ }
482
+
483
+ TEST_IMPL(fs_file_nametoolong) {
484
+ uv_fs_t req;
485
+ int r;
486
+ char name[TOO_LONG_NAME_LENGTH + 1];
487
+
488
+ loop = uv_default_loop();
489
+
490
+ memset(name, 'a', TOO_LONG_NAME_LENGTH);
491
+ name[TOO_LONG_NAME_LENGTH] = 0;
492
+
493
+ r = uv_fs_open(loop, &req, name, O_RDONLY, 0, NULL);
494
+ ASSERT(r == -1);
495
+ ASSERT(req.result == -1);
496
+ ASSERT(uv_last_error(loop).code == UV_ENAMETOOLONG);
497
+ uv_fs_req_cleanup(&req);
498
+
499
+ r = uv_fs_open(loop, &req, name, O_RDONLY, 0, open_nametoolong_cb);
500
+ ASSERT(r == 0);
501
+
502
+ ASSERT(open_cb_count == 0);
503
+ uv_run(loop);
504
+ ASSERT(open_cb_count == 1);
505
+
506
+ return 0;
507
+ }
508
+
509
+ TEST_IMPL(fs_file_loop) {
510
+ uv_fs_t req;
511
+ int r;
512
+
513
+ loop = uv_default_loop();
514
+
515
+ unlink("test_symlink");
516
+ uv_fs_symlink(loop, &req, "test_symlink", "test_symlink", 0, NULL);
517
+ uv_fs_req_cleanup(&req);
518
+
519
+ r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, NULL);
520
+ ASSERT(r == -1);
521
+ ASSERT(req.result == -1);
522
+ ASSERT(uv_last_error(loop).code == UV_ELOOP);
523
+ uv_fs_req_cleanup(&req);
524
+
525
+ r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, open_loop_cb);
526
+ ASSERT(r == 0);
527
+
528
+ ASSERT(open_cb_count == 0);
529
+ uv_run(loop);
530
+ ASSERT(open_cb_count == 1);
531
+
532
+ unlink("test_symlink");
533
+
534
+ return 0;
535
+ }
536
+
537
+ static void check_utime(const char* path, double atime, double mtime) {
538
+ struct stat* s;
539
+ uv_fs_t req;
540
+ int r;
541
+
542
+ r = uv_fs_stat(loop, &req, path, NULL);
543
+ ASSERT(r == 0);
544
+
545
+ ASSERT(req.result == 0);
546
+ s = req.ptr;
547
+
548
+ #if _WIN32
549
+ ASSERT(s->st_atime == atime);
550
+ ASSERT(s->st_mtime == mtime);
551
+ #elif !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
552
+ ASSERT(s->st_atimespec.tv_sec == atime);
553
+ ASSERT(s->st_mtimespec.tv_sec == mtime);
554
+ #else
555
+ ASSERT(s->st_atim.tv_sec == atime);
556
+ ASSERT(s->st_mtim.tv_sec == mtime);
557
+ #endif
558
+
559
+ uv_fs_req_cleanup(&req);
560
+ }
561
+
562
+
563
+ static void utime_cb(uv_fs_t* req) {
564
+ utime_check_t* c;
565
+
566
+ ASSERT(req == &utime_req);
567
+ ASSERT(req->result == 0);
568
+ ASSERT(req->fs_type == UV_FS_UTIME);
569
+
570
+ c = req->data;
571
+ check_utime(c->path, c->atime, c->mtime);
572
+
573
+ uv_fs_req_cleanup(req);
574
+ utime_cb_count++;
575
+ }
576
+
577
+
578
+ static void futime_cb(uv_fs_t* req) {
579
+ utime_check_t* c;
580
+
581
+ ASSERT(req == &futime_req);
582
+ ASSERT(req->result == 0);
583
+ ASSERT(req->fs_type == UV_FS_FUTIME);
584
+
585
+ c = req->data;
586
+ check_utime(c->path, c->atime, c->mtime);
587
+
588
+ uv_fs_req_cleanup(req);
589
+ futime_cb_count++;
590
+ }
591
+
592
+
593
+ TEST_IMPL(fs_file_async) {
594
+ int r;
595
+
596
+ /* Setup. */
597
+ unlink("test_file");
598
+ unlink("test_file2");
599
+
600
+ loop = uv_default_loop();
601
+
602
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
603
+ S_IREAD | S_IWRITE, create_cb);
604
+ ASSERT(r == 0);
605
+ uv_run(loop);
606
+
607
+ ASSERT(create_cb_count == 1);
608
+ ASSERT(write_cb_count == 1);
609
+ ASSERT(fsync_cb_count == 1);
610
+ ASSERT(fdatasync_cb_count == 1);
611
+ ASSERT(close_cb_count == 1);
612
+
613
+ r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", rename_cb);
614
+ ASSERT(r == 0);
615
+
616
+ uv_run(loop);
617
+ ASSERT(create_cb_count == 1);
618
+ ASSERT(write_cb_count == 1);
619
+ ASSERT(close_cb_count == 1);
620
+ ASSERT(rename_cb_count == 1);
621
+
622
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_RDWR, 0, open_cb);
623
+ ASSERT(r == 0);
624
+
625
+ uv_run(loop);
626
+ ASSERT(open_cb_count == 1);
627
+ ASSERT(read_cb_count == 1);
628
+ ASSERT(close_cb_count == 2);
629
+ ASSERT(rename_cb_count == 1);
630
+ ASSERT(create_cb_count == 1);
631
+ ASSERT(write_cb_count == 1);
632
+ ASSERT(ftruncate_cb_count == 1);
633
+
634
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, open_cb);
635
+ ASSERT(r == 0);
636
+
637
+ uv_run(loop);
638
+ ASSERT(open_cb_count == 2);
639
+ ASSERT(read_cb_count == 2);
640
+ ASSERT(close_cb_count == 3);
641
+ ASSERT(rename_cb_count == 1);
642
+ ASSERT(unlink_cb_count == 1);
643
+ ASSERT(create_cb_count == 1);
644
+ ASSERT(write_cb_count == 1);
645
+ ASSERT(ftruncate_cb_count == 1);
646
+
647
+ /* Cleanup. */
648
+ unlink("test_file");
649
+ unlink("test_file2");
650
+
651
+ return 0;
652
+ }
653
+
654
+
655
+ TEST_IMPL(fs_file_sync) {
656
+ int r;
657
+
658
+ /* Setup. */
659
+ unlink("test_file");
660
+ unlink("test_file2");
661
+
662
+ loop = uv_default_loop();
663
+
664
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
665
+ S_IWRITE | S_IREAD, NULL);
666
+ ASSERT(r != -1);
667
+ ASSERT(open_req1.result != -1);
668
+ uv_fs_req_cleanup(&open_req1);
669
+
670
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
671
+ sizeof(test_buf), -1, NULL);
672
+ ASSERT(r != -1);
673
+ ASSERT(write_req.result != -1);
674
+ uv_fs_req_cleanup(&write_req);
675
+
676
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
677
+ ASSERT(r != -1);
678
+ ASSERT(close_req.result != -1);
679
+ uv_fs_req_cleanup(&close_req);
680
+
681
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDWR, 0, NULL);
682
+ ASSERT(r != -1);
683
+ ASSERT(open_req1.result != -1);
684
+ uv_fs_req_cleanup(&open_req1);
685
+
686
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
687
+ NULL);
688
+ ASSERT(r != -1);
689
+ ASSERT(read_req.result != -1);
690
+ ASSERT(strcmp(buf, test_buf) == 0);
691
+ uv_fs_req_cleanup(&read_req);
692
+
693
+ r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7, NULL);
694
+ ASSERT(r != -1);
695
+ ASSERT(ftruncate_req.result != -1);
696
+ uv_fs_req_cleanup(&ftruncate_req);
697
+
698
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
699
+ ASSERT(r != -1);
700
+ ASSERT(close_req.result != -1);
701
+ uv_fs_req_cleanup(&close_req);
702
+
703
+ r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", NULL);
704
+ ASSERT(r != -1);
705
+ ASSERT(rename_req.result != -1);
706
+ uv_fs_req_cleanup(&rename_req);
707
+
708
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, NULL);
709
+ ASSERT(r != -1);
710
+ ASSERT(open_req1.result != -1);
711
+ uv_fs_req_cleanup(&open_req1);
712
+
713
+ memset(buf, 0, sizeof(buf));
714
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
715
+ NULL);
716
+ ASSERT(r != -1);
717
+ ASSERT(read_req.result != -1);
718
+ ASSERT(strcmp(buf, "test-bu") == 0);
719
+ uv_fs_req_cleanup(&read_req);
720
+
721
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
722
+ ASSERT(r != -1);
723
+ ASSERT(close_req.result != -1);
724
+ uv_fs_req_cleanup(&close_req);
725
+
726
+ r = uv_fs_unlink(loop, &unlink_req, "test_file2", NULL);
727
+ ASSERT(r != -1);
728
+ ASSERT(unlink_req.result != -1);
729
+ uv_fs_req_cleanup(&unlink_req);
730
+
731
+ /* Cleanup */
732
+ unlink("test_file");
733
+ unlink("test_file2");
734
+
735
+ return 0;
736
+ }
737
+
738
+
739
+ TEST_IMPL(fs_async_dir) {
740
+ int r;
741
+
742
+ /* Setup */
743
+ unlink("test_dir/file1");
744
+ unlink("test_dir/file2");
745
+ rmdir("test_dir");
746
+
747
+ loop = uv_default_loop();
748
+
749
+ r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb);
750
+ ASSERT(r == 0);
751
+
752
+ uv_run(loop);
753
+ ASSERT(mkdir_cb_count == 1);
754
+
755
+ /* Create 2 files synchronously. */
756
+ r = uv_fs_open(loop, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT,
757
+ S_IWRITE | S_IREAD, NULL);
758
+ ASSERT(r != -1);
759
+ uv_fs_req_cleanup(&open_req1);
760
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
761
+ ASSERT(r == 0);
762
+ uv_fs_req_cleanup(&close_req);
763
+
764
+ r = uv_fs_open(loop, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT,
765
+ S_IWRITE | S_IREAD, NULL);
766
+ ASSERT(r != -1);
767
+ uv_fs_req_cleanup(&open_req1);
768
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
769
+ ASSERT(r == 0);
770
+ uv_fs_req_cleanup(&close_req);
771
+
772
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, readdir_cb);
773
+ ASSERT(r == 0);
774
+
775
+ uv_run(loop);
776
+ ASSERT(readdir_cb_count == 1);
777
+
778
+ /* sync uv_fs_readdir */
779
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, NULL);
780
+ ASSERT(r == 2);
781
+ ASSERT(readdir_req.result == 2);
782
+ ASSERT(readdir_req.ptr);
783
+ ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
784
+ || memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
785
+ uv_fs_req_cleanup(&readdir_req);
786
+ ASSERT(!readdir_req.ptr);
787
+
788
+ r = uv_fs_stat(loop, &stat_req, "test_dir", stat_cb);
789
+ ASSERT(r == 0);
790
+ uv_run(loop);
791
+
792
+ r = uv_fs_stat(loop, &stat_req, "test_dir\\", stat_cb);
793
+ ASSERT(r == 0);
794
+ uv_run(loop);
795
+
796
+ r = uv_fs_lstat(loop, &stat_req, "test_dir", stat_cb);
797
+ ASSERT(r == 0);
798
+ uv_run(loop);
799
+
800
+ r = uv_fs_lstat(loop, &stat_req, "test_dir\\", stat_cb);
801
+ ASSERT(r == 0);
802
+ uv_run(loop);
803
+
804
+ ASSERT(stat_cb_count == 4);
805
+
806
+ r = uv_fs_unlink(loop, &unlink_req, "test_dir/file1", unlink_cb);
807
+ ASSERT(r == 0);
808
+ uv_run(loop);
809
+ ASSERT(unlink_cb_count == 1);
810
+
811
+ r = uv_fs_unlink(loop, &unlink_req, "test_dir/file2", unlink_cb);
812
+ ASSERT(r == 0);
813
+ uv_run(loop);
814
+ ASSERT(unlink_cb_count == 2);
815
+
816
+ r = uv_fs_rmdir(loop, &rmdir_req, "test_dir", rmdir_cb);
817
+ ASSERT(r == 0);
818
+ uv_run(loop);
819
+ ASSERT(rmdir_cb_count == 1);
820
+
821
+ /* Cleanup */
822
+ unlink("test_dir/file1");
823
+ unlink("test_dir/file2");
824
+ rmdir("test_dir");
825
+
826
+ return 0;
827
+ }
828
+
829
+
830
+ TEST_IMPL(fs_async_sendfile) {
831
+ int f, r;
832
+ struct stat s1, s2;
833
+
834
+ loop = uv_default_loop();
835
+
836
+ /* Setup. */
837
+ unlink("test_file");
838
+ unlink("test_file2");
839
+
840
+ f = open("test_file", O_WRONLY | O_CREAT, S_IWRITE | S_IREAD);
841
+ ASSERT(f != -1);
842
+
843
+ r = write(f, "begin\n", 6);
844
+ ASSERT(r == 6);
845
+
846
+ r = lseek(f, 65536, SEEK_CUR);
847
+ ASSERT(r == 65542);
848
+
849
+ r = write(f, "end\n", 4);
850
+ ASSERT(r != -1);
851
+
852
+ r = close(f);
853
+ ASSERT(r == 0);
854
+
855
+ /* Test starts here. */
856
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDWR, 0, NULL);
857
+ ASSERT(r != -1);
858
+ ASSERT(open_req1.result != -1);
859
+ uv_fs_req_cleanup(&open_req1);
860
+
861
+ r = uv_fs_open(loop, &open_req2, "test_file2", O_WRONLY | O_CREAT,
862
+ S_IWRITE | S_IREAD, NULL);
863
+ ASSERT(r != -1);
864
+ ASSERT(open_req2.result != -1);
865
+ uv_fs_req_cleanup(&open_req2);
866
+
867
+ r = uv_fs_sendfile(loop, &sendfile_req, open_req2.result, open_req1.result,
868
+ 0, 131072, sendfile_cb);
869
+ ASSERT(r == 0);
870
+ uv_run(loop);
871
+
872
+ ASSERT(sendfile_cb_count == 1);
873
+
874
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
875
+ ASSERT(r == 0);
876
+ uv_fs_req_cleanup(&close_req);
877
+ r = uv_fs_close(loop, &close_req, open_req2.result, NULL);
878
+ ASSERT(r == 0);
879
+ uv_fs_req_cleanup(&close_req);
880
+
881
+ stat("test_file", &s1);
882
+ stat("test_file2", &s2);
883
+ ASSERT(65546 == s2.st_size && s1.st_size == s2.st_size);
884
+
885
+ /* Cleanup. */
886
+ unlink("test_file");
887
+ unlink("test_file2");
888
+
889
+ return 0;
890
+ }
891
+
892
+
893
+ TEST_IMPL(fs_fstat) {
894
+ int r;
895
+ uv_fs_t req;
896
+ uv_file file;
897
+ struct stat* s;
898
+
899
+ /* Setup. */
900
+ unlink("test_file");
901
+
902
+ loop = uv_default_loop();
903
+
904
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
905
+ S_IWRITE | S_IREAD, NULL);
906
+ ASSERT(r != -1);
907
+ ASSERT(req.result != -1);
908
+ file = req.result;
909
+ uv_fs_req_cleanup(&req);
910
+
911
+ r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
912
+ ASSERT(r == sizeof(test_buf));
913
+ ASSERT(req.result == sizeof(test_buf));
914
+ uv_fs_req_cleanup(&req);
915
+
916
+ r = uv_fs_fstat(loop, &req, file, NULL);
917
+ ASSERT(r == 0);
918
+ ASSERT(req.result == 0);
919
+ s = req.ptr;
920
+ ASSERT(s->st_size == sizeof(test_buf));
921
+ uv_fs_req_cleanup(&req);
922
+
923
+ /* Now do the uv_fs_fstat call asynchronously */
924
+ r = uv_fs_fstat(loop, &req, file, fstat_cb);
925
+ ASSERT(r == 0);
926
+ uv_run(loop);
927
+ ASSERT(fstat_cb_count == 1);
928
+
929
+
930
+ r = uv_fs_close(loop, &req, file, NULL);
931
+ ASSERT(r == 0);
932
+ ASSERT(req.result == 0);
933
+ uv_fs_req_cleanup(&req);
934
+
935
+ /*
936
+ * Run the loop just to check we don't have make any extraneous uv_ref()
937
+ * calls. This should drop out immediately.
938
+ */
939
+ uv_run(loop);
940
+
941
+ /* Cleanup. */
942
+ unlink("test_file");
943
+
944
+ return 0;
945
+ }
946
+
947
+
948
+ TEST_IMPL(fs_chmod) {
949
+ int r;
950
+ uv_fs_t req;
951
+ uv_file file;
952
+
953
+ /* Setup. */
954
+ unlink("test_file");
955
+
956
+ loop = uv_default_loop();
957
+
958
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
959
+ S_IWRITE | S_IREAD, NULL);
960
+ ASSERT(r != -1);
961
+ ASSERT(req.result != -1);
962
+ file = req.result;
963
+ uv_fs_req_cleanup(&req);
964
+
965
+ r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
966
+ ASSERT(r == sizeof(test_buf));
967
+ ASSERT(req.result == sizeof(test_buf));
968
+ uv_fs_req_cleanup(&req);
969
+
970
+ #ifndef _WIN32
971
+ /* Make the file write-only */
972
+ r = uv_fs_chmod(loop, &req, "test_file", 0200, NULL);
973
+ ASSERT(r == 0);
974
+ ASSERT(req.result == 0);
975
+ uv_fs_req_cleanup(&req);
976
+
977
+ check_permission("test_file", 0200);
978
+ #endif
979
+
980
+ /* Make the file read-only */
981
+ r = uv_fs_chmod(loop, &req, "test_file", 0400, NULL);
982
+ ASSERT(r == 0);
983
+ ASSERT(req.result == 0);
984
+ uv_fs_req_cleanup(&req);
985
+
986
+ check_permission("test_file", 0400);
987
+
988
+ /* Make the file read+write with sync uv_fs_fchmod */
989
+ r = uv_fs_fchmod(loop, &req, file, 0600, NULL);
990
+ ASSERT(r == 0);
991
+ ASSERT(req.result == 0);
992
+ uv_fs_req_cleanup(&req);
993
+
994
+ check_permission("test_file", 0600);
995
+
996
+ #ifndef _WIN32
997
+ /* async chmod */
998
+ {
999
+ static int mode = 0200;
1000
+ req.data = &mode;
1001
+ }
1002
+ r = uv_fs_chmod(loop, &req, "test_file", 0200, chmod_cb);
1003
+ ASSERT(r == 0);
1004
+ uv_run(loop);
1005
+ ASSERT(chmod_cb_count == 1);
1006
+ chmod_cb_count = 0; /* reset for the next test */
1007
+ #endif
1008
+
1009
+ /* async chmod */
1010
+ {
1011
+ static int mode = 0400;
1012
+ req.data = &mode;
1013
+ }
1014
+ r = uv_fs_chmod(loop, &req, "test_file", 0400, chmod_cb);
1015
+ ASSERT(r == 0);
1016
+ uv_run(loop);
1017
+ ASSERT(chmod_cb_count == 1);
1018
+
1019
+ /* async fchmod */
1020
+ {
1021
+ static int mode = 0600;
1022
+ req.data = &mode;
1023
+ }
1024
+ r = uv_fs_fchmod(loop, &req, file, 0600, fchmod_cb);
1025
+ ASSERT(r == 0);
1026
+ uv_run(loop);
1027
+ ASSERT(fchmod_cb_count == 1);
1028
+
1029
+ close(file);
1030
+
1031
+ /*
1032
+ * Run the loop just to check we don't have make any extraneous uv_ref()
1033
+ * calls. This should drop out immediately.
1034
+ */
1035
+ uv_run(loop);
1036
+
1037
+ /* Cleanup. */
1038
+ unlink("test_file");
1039
+
1040
+ return 0;
1041
+ }
1042
+
1043
+
1044
+ TEST_IMPL(fs_chown) {
1045
+ int r;
1046
+ uv_fs_t req;
1047
+ uv_file file;
1048
+
1049
+ /* Setup. */
1050
+ unlink("test_file");
1051
+
1052
+ loop = uv_default_loop();
1053
+
1054
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
1055
+ S_IWRITE | S_IREAD, NULL);
1056
+ ASSERT(r != -1);
1057
+ ASSERT(req.result != -1);
1058
+ file = req.result;
1059
+ uv_fs_req_cleanup(&req);
1060
+
1061
+ /* sync chown */
1062
+ r = uv_fs_chown(loop, &req, "test_file", -1, -1, NULL);
1063
+ ASSERT(r == 0);
1064
+ ASSERT(req.result == 0);
1065
+ uv_fs_req_cleanup(&req);
1066
+
1067
+ /* sync fchown */
1068
+ r = uv_fs_fchown(loop, &req, file, -1, -1, NULL);
1069
+ ASSERT(r == 0);
1070
+ ASSERT(req.result == 0);
1071
+ uv_fs_req_cleanup(&req);
1072
+
1073
+ /* async chown */
1074
+ r = uv_fs_chown(loop, &req, "test_file", -1, -1, chown_cb);
1075
+ ASSERT(r == 0);
1076
+ uv_run(loop);
1077
+ ASSERT(chown_cb_count == 1);
1078
+
1079
+ /* chown to root (fail) */
1080
+ chown_cb_count = 0;
1081
+ r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb);
1082
+ uv_run(loop);
1083
+ ASSERT(chown_cb_count == 1);
1084
+
1085
+ /* async fchown */
1086
+ r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb);
1087
+ ASSERT(r == 0);
1088
+ uv_run(loop);
1089
+ ASSERT(fchown_cb_count == 1);
1090
+
1091
+ close(file);
1092
+
1093
+ /*
1094
+ * Run the loop just to check we don't have make any extraneous uv_ref()
1095
+ * calls. This should drop out immediately.
1096
+ */
1097
+ uv_run(loop);
1098
+
1099
+ /* Cleanup. */
1100
+ unlink("test_file");
1101
+
1102
+ return 0;
1103
+ }
1104
+
1105
+
1106
+ TEST_IMPL(fs_link) {
1107
+ int r;
1108
+ uv_fs_t req;
1109
+ uv_file file;
1110
+ uv_file link;
1111
+
1112
+ /* Setup. */
1113
+ unlink("test_file");
1114
+ unlink("test_file_link");
1115
+ unlink("test_file_link2");
1116
+
1117
+ loop = uv_default_loop();
1118
+
1119
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
1120
+ S_IWRITE | S_IREAD, NULL);
1121
+ ASSERT(r != -1);
1122
+ ASSERT(req.result != -1);
1123
+ file = req.result;
1124
+ uv_fs_req_cleanup(&req);
1125
+
1126
+ r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
1127
+ ASSERT(r == sizeof(test_buf));
1128
+ ASSERT(req.result == sizeof(test_buf));
1129
+ uv_fs_req_cleanup(&req);
1130
+
1131
+ close(file);
1132
+
1133
+ /* sync link */
1134
+ r = uv_fs_link(loop, &req, "test_file", "test_file_link", NULL);
1135
+ ASSERT(r == 0);
1136
+ ASSERT(req.result == 0);
1137
+ uv_fs_req_cleanup(&req);
1138
+
1139
+ r = uv_fs_open(loop, &req, "test_file_link", O_RDWR, 0, NULL);
1140
+ ASSERT(r != -1);
1141
+ ASSERT(req.result != -1);
1142
+ link = req.result;
1143
+ uv_fs_req_cleanup(&req);
1144
+
1145
+ memset(buf, 0, sizeof(buf));
1146
+ r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
1147
+ ASSERT(r != -1);
1148
+ ASSERT(req.result != -1);
1149
+ ASSERT(strcmp(buf, test_buf) == 0);
1150
+
1151
+ close(link);
1152
+
1153
+ /* async link */
1154
+ r = uv_fs_link(loop, &req, "test_file", "test_file_link2", link_cb);
1155
+ ASSERT(r == 0);
1156
+ uv_run(loop);
1157
+ ASSERT(link_cb_count == 1);
1158
+
1159
+ r = uv_fs_open(loop, &req, "test_file_link2", O_RDWR, 0, NULL);
1160
+ ASSERT(r != -1);
1161
+ ASSERT(req.result != -1);
1162
+ link = req.result;
1163
+ uv_fs_req_cleanup(&req);
1164
+
1165
+ memset(buf, 0, sizeof(buf));
1166
+ r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
1167
+ ASSERT(r != -1);
1168
+ ASSERT(req.result != -1);
1169
+ ASSERT(strcmp(buf, test_buf) == 0);
1170
+
1171
+ close(link);
1172
+
1173
+ /*
1174
+ * Run the loop just to check we don't have make any extraneous uv_ref()
1175
+ * calls. This should drop out immediately.
1176
+ */
1177
+ uv_run(loop);
1178
+
1179
+ /* Cleanup. */
1180
+ unlink("test_file");
1181
+ unlink("test_file_link");
1182
+ unlink("test_file_link2");
1183
+
1184
+ return 0;
1185
+ }
1186
+
1187
+
1188
+ TEST_IMPL(fs_symlink) {
1189
+ int r;
1190
+ uv_fs_t req;
1191
+ uv_file file;
1192
+ uv_file link;
1193
+
1194
+ /* Setup. */
1195
+ unlink("test_file");
1196
+ unlink("test_file_symlink");
1197
+ unlink("test_file_symlink2");
1198
+ unlink("test_file_symlink_symlink");
1199
+ unlink("test_file_symlink2_symlink");
1200
+
1201
+ loop = uv_default_loop();
1202
+
1203
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
1204
+ S_IWRITE | S_IREAD, NULL);
1205
+ ASSERT(r != -1);
1206
+ ASSERT(req.result != -1);
1207
+ file = req.result;
1208
+ uv_fs_req_cleanup(&req);
1209
+
1210
+ r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
1211
+ ASSERT(r == sizeof(test_buf));
1212
+ ASSERT(req.result == sizeof(test_buf));
1213
+ uv_fs_req_cleanup(&req);
1214
+
1215
+ close(file);
1216
+
1217
+ /* sync symlink */
1218
+ r = uv_fs_symlink(loop, &req, "test_file", "test_file_symlink", 0, NULL);
1219
+ #ifdef _WIN32
1220
+ if (r == -1) {
1221
+ if (uv_last_error(loop).code == UV_ENOTSUP) {
1222
+ /*
1223
+ * Windows doesn't support symlinks on older versions.
1224
+ * We just pass the test and bail out early if we get ENOTSUP.
1225
+ */
1226
+ return 0;
1227
+ } else if (uv_last_error(loop).code == UV_EPERM) {
1228
+ /*
1229
+ * Creating a symlink is only allowed when running elevated.
1230
+ * We pass the test and bail out early if we get UV_EPERM.
1231
+ */
1232
+ return 0;
1233
+ }
1234
+ }
1235
+ #endif
1236
+ ASSERT(r == 0);
1237
+ ASSERT(req.result == 0);
1238
+ uv_fs_req_cleanup(&req);
1239
+
1240
+ r = uv_fs_open(loop, &req, "test_file_symlink", O_RDWR, 0, NULL);
1241
+ ASSERT(r != -1);
1242
+ ASSERT(req.result != -1);
1243
+ link = req.result;
1244
+ uv_fs_req_cleanup(&req);
1245
+
1246
+ memset(buf, 0, sizeof(buf));
1247
+ r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
1248
+ ASSERT(r != -1);
1249
+ ASSERT(req.result != -1);
1250
+ ASSERT(strcmp(buf, test_buf) == 0);
1251
+
1252
+ close(link);
1253
+
1254
+ r = uv_fs_symlink(loop, &req, "test_file_symlink", "test_file_symlink_symlink", 0, NULL);
1255
+ ASSERT(r != -1);
1256
+ r = uv_fs_readlink(loop, &req, "test_file_symlink_symlink", NULL);
1257
+ ASSERT(r != -1);
1258
+ ASSERT(strcmp(req.ptr, "test_file_symlink") == 0);
1259
+ uv_fs_req_cleanup(&req);
1260
+
1261
+ /* async link */
1262
+ r = uv_fs_symlink(loop, &req, "test_file", "test_file_symlink2", 0, symlink_cb);
1263
+ ASSERT(r == 0);
1264
+ uv_run(loop);
1265
+ ASSERT(symlink_cb_count == 1);
1266
+
1267
+ r = uv_fs_open(loop, &req, "test_file_symlink2", O_RDWR, 0, NULL);
1268
+ ASSERT(r != -1);
1269
+ ASSERT(req.result != -1);
1270
+ link = req.result;
1271
+ uv_fs_req_cleanup(&req);
1272
+
1273
+ memset(buf, 0, sizeof(buf));
1274
+ r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
1275
+ ASSERT(r != -1);
1276
+ ASSERT(req.result != -1);
1277
+ ASSERT(strcmp(buf, test_buf) == 0);
1278
+
1279
+ close(link);
1280
+
1281
+ r = uv_fs_symlink(loop, &req, "test_file_symlink2", "test_file_symlink2_symlink", 0, NULL);
1282
+ ASSERT(r != -1);
1283
+ r = uv_fs_readlink(loop, &req, "test_file_symlink2_symlink", readlink_cb);
1284
+ ASSERT(r != -1);
1285
+ uv_run(loop);
1286
+ ASSERT(readlink_cb_count == 1);
1287
+
1288
+ /*
1289
+ * Run the loop just to check we don't have make any extraneous uv_ref()
1290
+ * calls. This should drop out immediately.
1291
+ */
1292
+ uv_run(loop);
1293
+
1294
+ /* Cleanup. */
1295
+ unlink("test_file");
1296
+ unlink("test_file_symlink");
1297
+ unlink("test_file_symlink_symlink");
1298
+ unlink("test_file_symlink2");
1299
+ unlink("test_file_symlink2_symlink");
1300
+
1301
+ return 0;
1302
+ }
1303
+
1304
+
1305
+ TEST_IMPL(fs_symlink_dir) {
1306
+ uv_fs_t req;
1307
+ int r;
1308
+ char* test_dir;
1309
+
1310
+ /* set-up */
1311
+ unlink("test_dir/file1");
1312
+ unlink("test_dir/file2");
1313
+ rmdir("test_dir");
1314
+ rmdir("test_dir_symlink");
1315
+
1316
+ loop = uv_default_loop();
1317
+
1318
+ uv_fs_mkdir(loop, &req, "test_dir", 0777, NULL);
1319
+ uv_fs_req_cleanup(&req);
1320
+
1321
+ #ifdef _WIN32
1322
+ {
1323
+ static char src_path_buf[PATHMAX];
1324
+ strcpy(src_path_buf, "\\\\?\\");
1325
+ uv_cwd(src_path_buf + 4, sizeof(src_path_buf));
1326
+ strcat(src_path_buf, "\\test_dir\\");
1327
+ test_dir = src_path_buf;
1328
+ }
1329
+ #else
1330
+ test_dir = "test_dir";
1331
+ #endif
1332
+
1333
+ r = uv_fs_symlink(loop, &req, test_dir, "test_dir_symlink",
1334
+ UV_FS_SYMLINK_JUNCTION, NULL);
1335
+ ASSERT(r == 0);
1336
+ ASSERT(req.result == 0);
1337
+ uv_fs_req_cleanup(&req);
1338
+
1339
+ r = uv_fs_stat(loop, &req, "test_dir_symlink", NULL);
1340
+ ASSERT(r == 0);
1341
+ ASSERT(((struct stat*)req.ptr)->st_mode & S_IFDIR);
1342
+ uv_fs_req_cleanup(&req);
1343
+
1344
+ r = uv_fs_lstat(loop, &req, "test_dir_symlink", NULL);
1345
+ ASSERT(r == 0);
1346
+ ASSERT(((struct stat*)req.ptr)->st_mode & S_IFLNK);
1347
+ #ifdef _WIN32
1348
+ ASSERT(((struct stat*)req.ptr)->st_size == strlen(test_dir + 4));
1349
+ #else
1350
+ ASSERT(((struct stat*)req.ptr)->st_size == strlen(test_dir));
1351
+ #endif
1352
+ uv_fs_req_cleanup(&req);
1353
+
1354
+ r = uv_fs_readlink(loop, &req, "test_dir_symlink", NULL);
1355
+ ASSERT(r == 0);
1356
+ #ifdef _WIN32
1357
+ ASSERT(strcmp(req.ptr, test_dir + 4) == 0);
1358
+ #else
1359
+ ASSERT(strcmp(req.ptr, test_dir) == 0);
1360
+ #endif
1361
+ uv_fs_req_cleanup(&req);
1362
+
1363
+ r = uv_fs_open(loop, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT,
1364
+ S_IWRITE | S_IREAD, NULL);
1365
+ ASSERT(r != -1);
1366
+ uv_fs_req_cleanup(&open_req1);
1367
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1368
+ ASSERT(r == 0);
1369
+ uv_fs_req_cleanup(&close_req);
1370
+
1371
+ r = uv_fs_open(loop, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT,
1372
+ S_IWRITE | S_IREAD, NULL);
1373
+ ASSERT(r != -1);
1374
+ uv_fs_req_cleanup(&open_req1);
1375
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1376
+ ASSERT(r == 0);
1377
+ uv_fs_req_cleanup(&close_req);
1378
+
1379
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir_symlink", 0, NULL);
1380
+ ASSERT(r == 2);
1381
+ ASSERT(readdir_req.result == 2);
1382
+ ASSERT(readdir_req.ptr);
1383
+ ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
1384
+ || memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
1385
+ uv_fs_req_cleanup(&readdir_req);
1386
+ ASSERT(!readdir_req.ptr);
1387
+
1388
+ /* unlink will remove the directory symlink */
1389
+ r = uv_fs_unlink(loop, &req, "test_dir_symlink", NULL);
1390
+ ASSERT(r == 0);
1391
+ uv_fs_req_cleanup(&req);
1392
+
1393
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir_symlink", 0, NULL);
1394
+ ASSERT(r == -1);
1395
+ uv_fs_req_cleanup(&readdir_req);
1396
+
1397
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, NULL);
1398
+ ASSERT(r == 2);
1399
+ ASSERT(readdir_req.result == 2);
1400
+ ASSERT(readdir_req.ptr);
1401
+ ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
1402
+ || memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
1403
+ uv_fs_req_cleanup(&readdir_req);
1404
+ ASSERT(!readdir_req.ptr);
1405
+
1406
+ /* clean-up */
1407
+ unlink("test_dir/file1");
1408
+ unlink("test_dir/file2");
1409
+ rmdir("test_dir");
1410
+ rmdir("test_dir_symlink");
1411
+
1412
+ return 0;
1413
+ }
1414
+
1415
+
1416
+ TEST_IMPL(fs_utime) {
1417
+ utime_check_t checkme;
1418
+ const char* path = "test_file";
1419
+ double atime;
1420
+ double mtime;
1421
+ uv_fs_t req;
1422
+ int r;
1423
+
1424
+ /* Setup. */
1425
+ loop = uv_default_loop();
1426
+ unlink(path);
1427
+ r = uv_fs_open(loop, &req, path, O_RDWR | O_CREAT,
1428
+ S_IWRITE | S_IREAD, NULL);
1429
+ ASSERT(r != -1);
1430
+ ASSERT(req.result != -1);
1431
+ uv_fs_req_cleanup(&req);
1432
+ close(r);
1433
+
1434
+ atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
1435
+
1436
+ r = uv_fs_utime(loop, &req, path, atime, mtime, NULL);
1437
+ ASSERT(r == 0);
1438
+ ASSERT(req.result == 0);
1439
+ uv_fs_req_cleanup(&req);
1440
+
1441
+ r = uv_fs_stat(loop, &req, path, NULL);
1442
+ ASSERT(r == 0);
1443
+ ASSERT(req.result == 0);
1444
+ check_utime(path, atime, mtime);
1445
+ uv_fs_req_cleanup(&req);
1446
+
1447
+ atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
1448
+ checkme.path = path;
1449
+ checkme.atime = atime;
1450
+ checkme.mtime = mtime;
1451
+
1452
+ /* async utime */
1453
+ utime_req.data = &checkme;
1454
+ r = uv_fs_utime(loop, &utime_req, path, atime, mtime, utime_cb);
1455
+ ASSERT(r == 0);
1456
+ uv_run(loop);
1457
+ ASSERT(utime_cb_count == 1);
1458
+
1459
+ /* Cleanup. */
1460
+ unlink(path);
1461
+
1462
+ return 0;
1463
+ }
1464
+
1465
+
1466
+ #ifdef _WIN32
1467
+ TEST_IMPL(fs_stat_root) {
1468
+ int r;
1469
+ uv_loop_t* loop = uv_default_loop();
1470
+
1471
+ r = uv_fs_stat(loop, &stat_req, "\\", NULL);
1472
+ ASSERT(r == 0);
1473
+
1474
+ r = uv_fs_stat(loop, &stat_req, "..\\..\\..\\..\\..\\..\\..", NULL);
1475
+ ASSERT(r == 0);
1476
+
1477
+ r = uv_fs_stat(loop, &stat_req, "..", NULL);
1478
+ ASSERT(r == 0);
1479
+
1480
+ r = uv_fs_stat(loop, &stat_req, "..\\", NULL);
1481
+ ASSERT(r == 0);
1482
+
1483
+ /* stats the current directory on c: */
1484
+ r = uv_fs_stat(loop, &stat_req, "c:", NULL);
1485
+ ASSERT(r == 0);
1486
+
1487
+ r = uv_fs_stat(loop, &stat_req, "c:\\", NULL);
1488
+ ASSERT(r == 0);
1489
+
1490
+ r = uv_fs_stat(loop, &stat_req, "\\\\?\\C:\\", NULL);
1491
+ ASSERT(r == 0);
1492
+
1493
+ return 0;
1494
+ }
1495
+ #endif
1496
+
1497
+
1498
+ TEST_IMPL(fs_futime) {
1499
+ utime_check_t checkme;
1500
+ const char* path = "test_file";
1501
+ double atime;
1502
+ double mtime;
1503
+ uv_file file;
1504
+ uv_fs_t req;
1505
+ int r;
1506
+
1507
+ /* Setup. */
1508
+ loop = uv_default_loop();
1509
+ unlink(path);
1510
+ r = uv_fs_open(loop, &req, path, O_RDWR | O_CREAT,
1511
+ S_IWRITE | S_IREAD, NULL);
1512
+ ASSERT(r != -1);
1513
+ ASSERT(req.result != -1);
1514
+ uv_fs_req_cleanup(&req);
1515
+ close(r);
1516
+
1517
+ atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
1518
+
1519
+ r = uv_fs_open(loop, &req, path, O_RDWR, 0, NULL);
1520
+ ASSERT(r != -1);
1521
+ ASSERT(req.result != -1);
1522
+ file = req.result; /* FIXME probably not how it's supposed to be used */
1523
+ uv_fs_req_cleanup(&req);
1524
+
1525
+ r = uv_fs_futime(loop, &req, file, atime, mtime, NULL);
1526
+ ASSERT(r == 0);
1527
+ ASSERT(req.result == 0);
1528
+ uv_fs_req_cleanup(&req);
1529
+
1530
+ r = uv_fs_stat(loop, &req, path, NULL);
1531
+ ASSERT(r == 0);
1532
+ ASSERT(req.result == 0);
1533
+ check_utime(path, atime, mtime);
1534
+ uv_fs_req_cleanup(&req);
1535
+
1536
+ atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
1537
+
1538
+ checkme.atime = atime;
1539
+ checkme.mtime = mtime;
1540
+ checkme.path = path;
1541
+
1542
+ /* async futime */
1543
+ futime_req.data = &checkme;
1544
+ r = uv_fs_futime(loop, &futime_req, file, atime, mtime, futime_cb);
1545
+ ASSERT(r == 0);
1546
+ uv_run(loop);
1547
+ ASSERT(futime_cb_count == 1);
1548
+
1549
+ /* Cleanup. */
1550
+ unlink(path);
1551
+
1552
+ return 0;
1553
+ }
1554
+
1555
+
1556
+ TEST_IMPL(fs_stat_missing_path) {
1557
+ uv_fs_t req;
1558
+ int r;
1559
+
1560
+ loop = uv_default_loop();
1561
+
1562
+ r = uv_fs_stat(loop, &req, "non_existent_file", NULL);
1563
+ ASSERT(r == -1);
1564
+ ASSERT(req.result == -1);
1565
+ ASSERT(uv_last_error(loop).code == UV_ENOENT);
1566
+ uv_fs_req_cleanup(&req);
1567
+
1568
+ return 0;
1569
+ }
1570
+
1571
+
1572
+ TEST_IMPL(fs_readdir_empty_dir) {
1573
+ const char* path;
1574
+ uv_fs_t req;
1575
+ int r;
1576
+
1577
+ path = "./empty_dir/";
1578
+ loop = uv_default_loop();
1579
+
1580
+ uv_fs_mkdir(loop, &req, path, 0777, NULL);
1581
+ uv_fs_req_cleanup(&req);
1582
+
1583
+ r = uv_fs_readdir(loop, &req, path, 0, NULL);
1584
+ ASSERT(r == 0);
1585
+ ASSERT(req.result == 0);
1586
+ ASSERT(req.ptr == NULL);
1587
+ uv_fs_req_cleanup(&req);
1588
+
1589
+ r = uv_fs_readdir(loop, &readdir_req, path, 0, empty_readdir_cb);
1590
+ ASSERT(r == 0);
1591
+
1592
+ ASSERT(readdir_cb_count == 0);
1593
+ uv_run(loop);
1594
+ ASSERT(readdir_cb_count == 1);
1595
+
1596
+ uv_fs_rmdir(loop, &req, path, NULL);
1597
+ uv_fs_req_cleanup(&req);
1598
+
1599
+ return 0;
1600
+ }
1601
+
1602
+
1603
+ TEST_IMPL(fs_readdir_file) {
1604
+ const char* path;
1605
+ int r;
1606
+
1607
+ path = "test/fixtures/empty_file";
1608
+ loop = uv_default_loop();
1609
+
1610
+ r = uv_fs_readdir(loop, &readdir_req, path, 0, NULL);
1611
+ ASSERT(r == -1);
1612
+ ASSERT(uv_last_error(loop).code == UV_ENOTDIR);
1613
+
1614
+ r = uv_fs_readdir(loop, &readdir_req, path, 0, file_readdir_cb);
1615
+ ASSERT(r == 0);
1616
+
1617
+ ASSERT(readdir_cb_count == 0);
1618
+ uv_run(loop);
1619
+ ASSERT(readdir_cb_count == 1);
1620
+
1621
+ return 0;
1622
+ }
1623
+
1624
+
1625
+ TEST_IMPL(fs_open_dir) {
1626
+ const char* path;
1627
+ uv_fs_t req;
1628
+ int r, file;
1629
+
1630
+ path = ".";
1631
+ loop = uv_default_loop();
1632
+
1633
+ r = uv_fs_open(loop, &req, path, O_RDONLY, 0, NULL);
1634
+ ASSERT(r != -1);
1635
+ ASSERT(req.result != -1);
1636
+ ASSERT(req.ptr == NULL);
1637
+ file = r;
1638
+ uv_fs_req_cleanup(&req);
1639
+
1640
+ r = uv_fs_close(loop, &req, file, NULL);
1641
+ ASSERT(r == 0);
1642
+
1643
+ r = uv_fs_open(loop, &req, path, O_RDONLY, 0, open_cb_simple);
1644
+ ASSERT(r == 0);
1645
+
1646
+ ASSERT(open_cb_count == 0);
1647
+ uv_run(loop);
1648
+ ASSERT(open_cb_count == 1);
1649
+
1650
+ return 0;
1651
+ }
1652
+
1653
+
1654
+ TEST_IMPL(fs_file_open_append) {
1655
+ int r;
1656
+
1657
+ /* Setup. */
1658
+ unlink("test_file");
1659
+
1660
+ loop = uv_default_loop();
1661
+
1662
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
1663
+ S_IWRITE | S_IREAD, NULL);
1664
+ ASSERT(r != -1);
1665
+ ASSERT(open_req1.result != -1);
1666
+ uv_fs_req_cleanup(&open_req1);
1667
+
1668
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
1669
+ sizeof(test_buf), -1, NULL);
1670
+ ASSERT(r != -1);
1671
+ ASSERT(write_req.result != -1);
1672
+ uv_fs_req_cleanup(&write_req);
1673
+
1674
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1675
+ ASSERT(r != -1);
1676
+ ASSERT(close_req.result != -1);
1677
+ uv_fs_req_cleanup(&close_req);
1678
+
1679
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDWR | O_APPEND, 0, NULL);
1680
+ ASSERT(r != -1);
1681
+ ASSERT(open_req1.result != -1);
1682
+ uv_fs_req_cleanup(&open_req1);
1683
+
1684
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
1685
+ sizeof(test_buf), -1, NULL);
1686
+ ASSERT(r != -1);
1687
+ ASSERT(write_req.result != -1);
1688
+ uv_fs_req_cleanup(&write_req);
1689
+
1690
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1691
+ ASSERT(r != -1);
1692
+ ASSERT(close_req.result != -1);
1693
+ uv_fs_req_cleanup(&close_req);
1694
+
1695
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDONLY, S_IREAD, NULL);
1696
+ ASSERT(r != -1);
1697
+ ASSERT(open_req1.result != -1);
1698
+ uv_fs_req_cleanup(&open_req1);
1699
+
1700
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
1701
+ NULL);
1702
+ printf("read = %d\n", r);
1703
+ ASSERT(r == 26);
1704
+ ASSERT(read_req.result == 26);
1705
+ ASSERT(memcmp(buf,
1706
+ "test-buffer\n\0test-buffer\n\0",
1707
+ sizeof("test-buffer\n\0test-buffer\n\0") - 1) == 0);
1708
+ uv_fs_req_cleanup(&read_req);
1709
+
1710
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1711
+ ASSERT(r != -1);
1712
+ ASSERT(close_req.result != -1);
1713
+ uv_fs_req_cleanup(&close_req);
1714
+
1715
+ /* Cleanup */
1716
+ unlink("test_file");
1717
+
1718
+ return 0;
1719
+ }
1720
+
1721
+
1722
+ TEST_IMPL(fs_rename_to_existing_file) {
1723
+ int r;
1724
+
1725
+ /* Setup. */
1726
+ unlink("test_file");
1727
+ unlink("test_file2");
1728
+
1729
+ loop = uv_default_loop();
1730
+
1731
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
1732
+ S_IWRITE | S_IREAD, NULL);
1733
+ ASSERT(r != -1);
1734
+ ASSERT(open_req1.result != -1);
1735
+ uv_fs_req_cleanup(&open_req1);
1736
+
1737
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
1738
+ sizeof(test_buf), -1, NULL);
1739
+ ASSERT(r != -1);
1740
+ ASSERT(write_req.result != -1);
1741
+ uv_fs_req_cleanup(&write_req);
1742
+
1743
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1744
+ ASSERT(r != -1);
1745
+ ASSERT(close_req.result != -1);
1746
+ uv_fs_req_cleanup(&close_req);
1747
+
1748
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_WRONLY | O_CREAT,
1749
+ S_IWRITE | S_IREAD, NULL);
1750
+ ASSERT(r != -1);
1751
+ ASSERT(open_req1.result != -1);
1752
+ uv_fs_req_cleanup(&open_req1);
1753
+
1754
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1755
+ ASSERT(r != -1);
1756
+ ASSERT(close_req.result != -1);
1757
+ uv_fs_req_cleanup(&close_req);
1758
+
1759
+ r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", NULL);
1760
+ ASSERT(r != -1);
1761
+ ASSERT(rename_req.result != -1);
1762
+ uv_fs_req_cleanup(&rename_req);
1763
+
1764
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, NULL);
1765
+ ASSERT(r != -1);
1766
+ ASSERT(open_req1.result != -1);
1767
+ uv_fs_req_cleanup(&open_req1);
1768
+
1769
+ memset(buf, 0, sizeof(buf));
1770
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
1771
+ NULL);
1772
+ ASSERT(r != -1);
1773
+ ASSERT(read_req.result != -1);
1774
+ ASSERT(strcmp(buf, test_buf) == 0);
1775
+ uv_fs_req_cleanup(&read_req);
1776
+
1777
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1778
+ ASSERT(r != -1);
1779
+ ASSERT(close_req.result != -1);
1780
+ uv_fs_req_cleanup(&close_req);
1781
+
1782
+ /* Cleanup */
1783
+ unlink("test_file");
1784
+ unlink("test_file2");
1785
+
1786
+ return 0;
1787
+ }
1788
+
1789
+
1790
+ TEST_IMPL(fs_read_file_eof) {
1791
+ int r;
1792
+
1793
+ /* Setup. */
1794
+ unlink("test_file");
1795
+
1796
+ loop = uv_default_loop();
1797
+
1798
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
1799
+ S_IWRITE | S_IREAD, NULL);
1800
+ ASSERT(r != -1);
1801
+ ASSERT(open_req1.result != -1);
1802
+ uv_fs_req_cleanup(&open_req1);
1803
+
1804
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
1805
+ sizeof(test_buf), -1, NULL);
1806
+ ASSERT(r != -1);
1807
+ ASSERT(write_req.result != -1);
1808
+ uv_fs_req_cleanup(&write_req);
1809
+
1810
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1811
+ ASSERT(r != -1);
1812
+ ASSERT(close_req.result != -1);
1813
+ uv_fs_req_cleanup(&close_req);
1814
+
1815
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDONLY, 0, NULL);
1816
+ ASSERT(r != -1);
1817
+ ASSERT(open_req1.result != -1);
1818
+ uv_fs_req_cleanup(&open_req1);
1819
+
1820
+ memset(buf, 0, sizeof(buf));
1821
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
1822
+ NULL);
1823
+ ASSERT(r != -1);
1824
+ ASSERT(read_req.result != -1);
1825
+ ASSERT(strcmp(buf, test_buf) == 0);
1826
+ uv_fs_req_cleanup(&read_req);
1827
+
1828
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf),
1829
+ read_req.result, NULL);
1830
+ ASSERT(r == 0);
1831
+ ASSERT(read_req.result == 0);
1832
+ uv_fs_req_cleanup(&read_req);
1833
+
1834
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
1835
+ ASSERT(r != -1);
1836
+ ASSERT(close_req.result != -1);
1837
+ uv_fs_req_cleanup(&close_req);
1838
+
1839
+ /* Cleanup */
1840
+ unlink("test_file");
1841
+
1842
+ return 0;
1843
+ }