foolio 0.0.3

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