|
160
|
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 <errno.h>
|
|
|
26 #include <string.h> /* memset */
|
|
|
27 #include <fcntl.h>
|
|
|
28 #include <sys/stat.h>
|
|
|
29 #include <limits.h> /* INT_MAX, PATH_MAX, IOV_MAX */
|
|
|
30
|
|
|
31 #ifndef _WIN32
|
|
|
32 # include <unistd.h> /* unlink, rmdir, etc. */
|
|
|
33 #else
|
|
|
34 # include <winioctl.h>
|
|
|
35 # include <direct.h>
|
|
|
36 # include <io.h>
|
|
|
37 # ifndef ERROR_SYMLINK_NOT_SUPPORTED
|
|
|
38 # define ERROR_SYMLINK_NOT_SUPPORTED 1464
|
|
|
39 # endif
|
|
|
40 # ifndef S_IFIFO
|
|
|
41 # define S_IFIFO _S_IFIFO
|
|
|
42 # endif
|
|
|
43 # define unlink _unlink
|
|
|
44 # define rmdir _rmdir
|
|
|
45 # define open _open
|
|
|
46 # define write _write
|
|
|
47 # define close _close
|
|
|
48 # ifndef stat
|
|
|
49 # define stat _stati64
|
|
|
50 # endif
|
|
|
51 # ifndef lseek
|
|
|
52 # define lseek _lseek
|
|
|
53 # endif
|
|
|
54 # define S_IFDIR _S_IFDIR
|
|
|
55 # define S_IFCHR _S_IFCHR
|
|
|
56 # define S_IFREG _S_IFREG
|
|
|
57 #endif
|
|
|
58
|
|
|
59 #define TOO_LONG_NAME_LENGTH 65536
|
|
|
60 #define PATHMAX 4096
|
|
|
61
|
|
|
62 #ifdef _WIN32
|
|
|
63 static const int is_win32 = 1;
|
|
|
64 #else
|
|
|
65 static const int is_win32 = 0;
|
|
|
66 #endif
|
|
|
67
|
|
|
68 #if defined(__APPLE__) || defined(__SUNPRO_C)
|
|
|
69 static const int is_apple_or_sunpro_c = 1;
|
|
|
70 #else
|
|
|
71 static const int is_apple_or_sunpro_c = 0;
|
|
|
72 #endif
|
|
|
73
|
|
|
74 typedef struct {
|
|
|
75 const char* path;
|
|
|
76 double atime;
|
|
|
77 double mtime;
|
|
|
78 } utime_check_t;
|
|
|
79
|
|
|
80
|
|
|
81 static int dummy_cb_count;
|
|
|
82 static int close_cb_count;
|
|
|
83 static int create_cb_count;
|
|
|
84 static int open_cb_count;
|
|
|
85 static int read_cb_count;
|
|
|
86 static int write_cb_count;
|
|
|
87 static int unlink_cb_count;
|
|
|
88 static int mkdir_cb_count;
|
|
|
89 static int mkdtemp_cb_count;
|
|
|
90 static int mkstemp_cb_count;
|
|
|
91 static int rmdir_cb_count;
|
|
|
92 static int scandir_cb_count;
|
|
|
93 static int stat_cb_count;
|
|
|
94 static int rename_cb_count;
|
|
|
95 static int fsync_cb_count;
|
|
|
96 static int fdatasync_cb_count;
|
|
|
97 static int ftruncate_cb_count;
|
|
|
98 static int sendfile_cb_count;
|
|
|
99 static int fstat_cb_count;
|
|
|
100 static int access_cb_count;
|
|
|
101 static int chmod_cb_count;
|
|
|
102 static int fchmod_cb_count;
|
|
|
103 static int chown_cb_count;
|
|
|
104 static int fchown_cb_count;
|
|
|
105 static int lchown_cb_count;
|
|
|
106 static int link_cb_count;
|
|
|
107 static int symlink_cb_count;
|
|
|
108 static int readlink_cb_count;
|
|
|
109 static int realpath_cb_count;
|
|
|
110 static int utime_cb_count;
|
|
|
111 static int futime_cb_count;
|
|
|
112 static int lutime_cb_count;
|
|
|
113 static int statfs_cb_count;
|
|
|
114
|
|
|
115 static uv_loop_t* loop;
|
|
|
116
|
|
|
117 static uv_fs_t open_req1;
|
|
|
118 static uv_fs_t open_req2;
|
|
|
119 static uv_fs_t open_req_noclose;
|
|
|
120 static uv_fs_t read_req;
|
|
|
121 static uv_fs_t write_req;
|
|
|
122 static uv_fs_t unlink_req;
|
|
|
123 static uv_fs_t close_req;
|
|
|
124 static uv_fs_t mkdir_req;
|
|
|
125 static uv_fs_t mkdtemp_req1;
|
|
|
126 static uv_fs_t mkdtemp_req2;
|
|
|
127 static uv_fs_t mkstemp_req1;
|
|
|
128 static uv_fs_t mkstemp_req2;
|
|
|
129 static uv_fs_t mkstemp_req3;
|
|
|
130 static uv_fs_t rmdir_req;
|
|
|
131 static uv_fs_t scandir_req;
|
|
|
132 static uv_fs_t stat_req;
|
|
|
133 static uv_fs_t rename_req;
|
|
|
134 static uv_fs_t fsync_req;
|
|
|
135 static uv_fs_t fdatasync_req;
|
|
|
136 static uv_fs_t ftruncate_req;
|
|
|
137 static uv_fs_t sendfile_req;
|
|
|
138 static uv_fs_t utime_req;
|
|
|
139 static uv_fs_t futime_req;
|
|
|
140
|
|
|
141 static char buf[32];
|
|
|
142 static char buf2[32];
|
|
|
143 static char test_buf[] = "test-buffer\n";
|
|
|
144 static char test_buf2[] = "second-buffer\n";
|
|
|
145 static uv_buf_t iov;
|
|
|
146
|
|
|
147 #ifdef _WIN32
|
|
|
148 int uv_test_getiovmax(void) {
|
|
|
149 return INT32_MAX; /* Emulated by libuv, so no real limit. */
|
|
|
150 }
|
|
|
151 #else
|
|
|
152 int uv_test_getiovmax(void) {
|
|
|
153 #if defined(IOV_MAX)
|
|
|
154 return IOV_MAX;
|
|
|
155 #elif defined(_SC_IOV_MAX)
|
|
|
156 static int iovmax = -1;
|
|
|
157 if (iovmax == -1) {
|
|
|
158 iovmax = sysconf(_SC_IOV_MAX);
|
|
|
159 /* On some embedded devices (arm-linux-uclibc based ip camera),
|
|
|
160 * sysconf(_SC_IOV_MAX) can not get the correct value. The return
|
|
|
161 * value is -1 and the errno is EINPROGRESS. Degrade the value to 1.
|
|
|
162 */
|
|
|
163 if (iovmax == -1) iovmax = 1;
|
|
|
164 }
|
|
|
165 return iovmax;
|
|
|
166 #else
|
|
|
167 return 1024;
|
|
|
168 #endif
|
|
|
169 }
|
|
|
170 #endif
|
|
|
171
|
|
|
172 #ifdef _WIN32
|
|
|
173 /*
|
|
|
174 * This tag and guid have no special meaning, and don't conflict with
|
|
|
175 * reserved ids.
|
|
|
176 */
|
|
|
177 static unsigned REPARSE_TAG = 0x9913;
|
|
|
178 static GUID REPARSE_GUID = {
|
|
|
179 0x1bf6205f, 0x46ae, 0x4527,
|
|
|
180 { 0xb1, 0x0c, 0xc5, 0x09, 0xb7, 0x55, 0x22, 0x80 }};
|
|
|
181 #endif
|
|
|
182
|
|
|
183 static void check_permission(const char* filename, unsigned int mode) {
|
|
|
184 int r;
|
|
|
185 uv_fs_t req;
|
|
|
186 uv_stat_t* s;
|
|
|
187
|
|
|
188 r = uv_fs_stat(NULL, &req, filename, NULL);
|
|
|
189 ASSERT_OK(r);
|
|
|
190 ASSERT_OK(req.result);
|
|
|
191
|
|
|
192 s = &req.statbuf;
|
|
|
193 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__)
|
|
|
194 /*
|
|
|
195 * On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit,
|
|
|
196 * so only testing for the specified flags.
|
|
|
197 */
|
|
|
198 ASSERT((s->st_mode & 0777) & mode);
|
|
|
199 #else
|
|
|
200 ASSERT((s->st_mode & 0777) == mode);
|
|
|
201 #endif
|
|
|
202
|
|
|
203 uv_fs_req_cleanup(&req);
|
|
|
204 }
|
|
|
205
|
|
|
206
|
|
|
207 static void dummy_cb(uv_fs_t* req) {
|
|
|
208 (void) req;
|
|
|
209 dummy_cb_count++;
|
|
|
210 }
|
|
|
211
|
|
|
212
|
|
|
213 static void link_cb(uv_fs_t* req) {
|
|
|
214 ASSERT_EQ(req->fs_type, UV_FS_LINK);
|
|
|
215 ASSERT_OK(req->result);
|
|
|
216 link_cb_count++;
|
|
|
217 uv_fs_req_cleanup(req);
|
|
|
218 }
|
|
|
219
|
|
|
220
|
|
|
221 static void symlink_cb(uv_fs_t* req) {
|
|
|
222 ASSERT_EQ(req->fs_type, UV_FS_SYMLINK);
|
|
|
223 ASSERT_OK(req->result);
|
|
|
224 symlink_cb_count++;
|
|
|
225 uv_fs_req_cleanup(req);
|
|
|
226 }
|
|
|
227
|
|
|
228 static void readlink_cb(uv_fs_t* req) {
|
|
|
229 ASSERT_EQ(req->fs_type, UV_FS_READLINK);
|
|
|
230 ASSERT_OK(req->result);
|
|
|
231 ASSERT_OK(strcmp(req->ptr, "test_file_symlink2"));
|
|
|
232 readlink_cb_count++;
|
|
|
233 uv_fs_req_cleanup(req);
|
|
|
234 }
|
|
|
235
|
|
|
236
|
|
|
237 static void realpath_cb(uv_fs_t* req) {
|
|
|
238 char test_file_abs_buf[PATHMAX];
|
|
|
239 size_t test_file_abs_size = sizeof(test_file_abs_buf);
|
|
|
240 ASSERT_EQ(req->fs_type, UV_FS_REALPATH);
|
|
|
241 ASSERT_OK(req->result);
|
|
|
242
|
|
|
243 uv_cwd(test_file_abs_buf, &test_file_abs_size);
|
|
|
244 #ifdef _WIN32
|
|
|
245 strcat(test_file_abs_buf, "\\test_file");
|
|
|
246 ASSERT_OK(_stricmp(req->ptr, test_file_abs_buf));
|
|
|
247 #else
|
|
|
248 strcat(test_file_abs_buf, "/test_file");
|
|
|
249 ASSERT_OK(strcmp(req->ptr, test_file_abs_buf));
|
|
|
250 #endif
|
|
|
251 realpath_cb_count++;
|
|
|
252 uv_fs_req_cleanup(req);
|
|
|
253 }
|
|
|
254
|
|
|
255
|
|
|
256 static void access_cb(uv_fs_t* req) {
|
|
|
257 ASSERT_EQ(req->fs_type, UV_FS_ACCESS);
|
|
|
258 access_cb_count++;
|
|
|
259 uv_fs_req_cleanup(req);
|
|
|
260 }
|
|
|
261
|
|
|
262
|
|
|
263 static void fchmod_cb(uv_fs_t* req) {
|
|
|
264 ASSERT_EQ(req->fs_type, UV_FS_FCHMOD);
|
|
|
265 ASSERT_OK(req->result);
|
|
|
266 fchmod_cb_count++;
|
|
|
267 uv_fs_req_cleanup(req);
|
|
|
268 check_permission("test_file", *(int*)req->data);
|
|
|
269 }
|
|
|
270
|
|
|
271
|
|
|
272 static void chmod_cb(uv_fs_t* req) {
|
|
|
273 ASSERT_EQ(req->fs_type, UV_FS_CHMOD);
|
|
|
274 ASSERT_OK(req->result);
|
|
|
275 chmod_cb_count++;
|
|
|
276 uv_fs_req_cleanup(req);
|
|
|
277 check_permission("test_file", *(int*)req->data);
|
|
|
278 }
|
|
|
279
|
|
|
280
|
|
|
281 static void fchown_cb(uv_fs_t* req) {
|
|
|
282 ASSERT_EQ(req->fs_type, UV_FS_FCHOWN);
|
|
|
283 ASSERT_OK(req->result);
|
|
|
284 fchown_cb_count++;
|
|
|
285 uv_fs_req_cleanup(req);
|
|
|
286 }
|
|
|
287
|
|
|
288
|
|
|
289 static void chown_cb(uv_fs_t* req) {
|
|
|
290 ASSERT_EQ(req->fs_type, UV_FS_CHOWN);
|
|
|
291 ASSERT_OK(req->result);
|
|
|
292 chown_cb_count++;
|
|
|
293 uv_fs_req_cleanup(req);
|
|
|
294 }
|
|
|
295
|
|
|
296 static void lchown_cb(uv_fs_t* req) {
|
|
|
297 ASSERT_EQ(req->fs_type, UV_FS_LCHOWN);
|
|
|
298 ASSERT_OK(req->result);
|
|
|
299 lchown_cb_count++;
|
|
|
300 uv_fs_req_cleanup(req);
|
|
|
301 }
|
|
|
302
|
|
|
303 static void chown_root_cb(uv_fs_t* req) {
|
|
|
304 ASSERT_EQ(req->fs_type, UV_FS_CHOWN);
|
|
|
305 #if defined(_WIN32) || defined(__MSYS__)
|
|
|
306 /* On windows, chown is a no-op and always succeeds. */
|
|
|
307 ASSERT_OK(req->result);
|
|
|
308 #else
|
|
|
309 /* On unix, chown'ing the root directory is not allowed -
|
|
|
310 * unless you're root, of course.
|
|
|
311 */
|
|
|
312 if (geteuid() == 0)
|
|
|
313 ASSERT_OK(req->result);
|
|
|
314 else
|
|
|
315 # if defined(__CYGWIN__)
|
|
|
316 /* On Cygwin, uid 0 is invalid (no root). */
|
|
|
317 ASSERT_EQ(req->result, UV_EINVAL);
|
|
|
318 # elif defined(__PASE__)
|
|
|
319 /* On IBMi PASE, there is no root user. uid 0 is user qsecofr.
|
|
|
320 * User may grant qsecofr's privileges, including changing
|
|
|
321 * the file's ownership to uid 0.
|
|
|
322 */
|
|
|
323 ASSERT(req->result == 0 || req->result == UV_EPERM);
|
|
|
324 # else
|
|
|
325 ASSERT_EQ(req->result, UV_EPERM);
|
|
|
326 # endif
|
|
|
327 #endif
|
|
|
328 chown_cb_count++;
|
|
|
329 uv_fs_req_cleanup(req);
|
|
|
330 }
|
|
|
331
|
|
|
332 static void unlink_cb(uv_fs_t* req) {
|
|
|
333 ASSERT_PTR_EQ(req, &unlink_req);
|
|
|
334 ASSERT_EQ(req->fs_type, UV_FS_UNLINK);
|
|
|
335 ASSERT_OK(req->result);
|
|
|
336 unlink_cb_count++;
|
|
|
337 uv_fs_req_cleanup(req);
|
|
|
338 }
|
|
|
339
|
|
|
340 static void fstat_cb(uv_fs_t* req) {
|
|
|
341 uv_stat_t* s = req->ptr;
|
|
|
342 ASSERT_EQ(req->fs_type, UV_FS_FSTAT);
|
|
|
343 ASSERT_OK(req->result);
|
|
|
344 ASSERT_EQ(s->st_size, sizeof(test_buf));
|
|
|
345 uv_fs_req_cleanup(req);
|
|
|
346 fstat_cb_count++;
|
|
|
347 }
|
|
|
348
|
|
|
349
|
|
|
350 static void statfs_cb(uv_fs_t* req) {
|
|
|
351 uv_statfs_t* stats;
|
|
|
352
|
|
|
353 ASSERT_EQ(req->fs_type, UV_FS_STATFS);
|
|
|
354 ASSERT_OK(req->result);
|
|
|
355 ASSERT_NOT_NULL(req->ptr);
|
|
|
356 stats = req->ptr;
|
|
|
357
|
|
|
358 #if defined(_WIN32) || defined(__sun) || defined(_AIX) || defined(__MVS__) || \
|
|
|
359 defined(__OpenBSD__) || defined(__NetBSD__)
|
|
|
360 ASSERT_OK(stats->f_type);
|
|
|
361 #else
|
|
|
362 ASSERT_UINT64_GT(stats->f_type, 0);
|
|
|
363 #endif
|
|
|
364
|
|
|
365 ASSERT_GT(stats->f_bsize, 0);
|
|
|
366 ASSERT_GT(stats->f_blocks, 0);
|
|
|
367 ASSERT_LE(stats->f_bfree, stats->f_blocks);
|
|
|
368 ASSERT_LE(stats->f_bavail, stats->f_bfree);
|
|
|
369
|
|
|
370 #ifdef _WIN32
|
|
|
371 ASSERT_OK(stats->f_files);
|
|
|
372 ASSERT_OK(stats->f_ffree);
|
|
|
373 #else
|
|
|
374 /* There is no assertion for stats->f_files that makes sense, so ignore it. */
|
|
|
375 ASSERT_LE(stats->f_ffree, stats->f_files);
|
|
|
376 #endif
|
|
|
377 uv_fs_req_cleanup(req);
|
|
|
378 ASSERT_NULL(req->ptr);
|
|
|
379 statfs_cb_count++;
|
|
|
380 }
|
|
|
381
|
|
|
382
|
|
|
383 static void close_cb(uv_fs_t* req) {
|
|
|
384 int r;
|
|
|
385 ASSERT_PTR_EQ(req, &close_req);
|
|
|
386 ASSERT_EQ(req->fs_type, UV_FS_CLOSE);
|
|
|
387 ASSERT_OK(req->result);
|
|
|
388 close_cb_count++;
|
|
|
389 uv_fs_req_cleanup(req);
|
|
|
390 if (close_cb_count == 3) {
|
|
|
391 r = uv_fs_unlink(loop, &unlink_req, "test_file2", unlink_cb);
|
|
|
392 ASSERT_OK(r);
|
|
|
393 }
|
|
|
394 }
|
|
|
395
|
|
|
396
|
|
|
397 static void ftruncate_cb(uv_fs_t* req) {
|
|
|
398 int r;
|
|
|
399 ASSERT_PTR_EQ(req, &ftruncate_req);
|
|
|
400 ASSERT_EQ(req->fs_type, UV_FS_FTRUNCATE);
|
|
|
401 ASSERT_OK(req->result);
|
|
|
402 ftruncate_cb_count++;
|
|
|
403 uv_fs_req_cleanup(req);
|
|
|
404 r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
|
|
|
405 ASSERT_OK(r);
|
|
|
406 }
|
|
|
407
|
|
|
408 static void fail_cb(uv_fs_t* req) {
|
|
|
409 FATAL("fail_cb should not have been called");
|
|
|
410 }
|
|
|
411
|
|
|
412 static void read_cb(uv_fs_t* req) {
|
|
|
413 int r;
|
|
|
414 ASSERT_PTR_EQ(req, &read_req);
|
|
|
415 ASSERT_EQ(req->fs_type, UV_FS_READ);
|
|
|
416 ASSERT_GE(req->result, 0); /* FIXME(bnoordhuis) Check if requested size? */
|
|
|
417 read_cb_count++;
|
|
|
418 uv_fs_req_cleanup(req);
|
|
|
419 if (read_cb_count == 1) {
|
|
|
420 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
421 r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7,
|
|
|
422 ftruncate_cb);
|
|
|
423 } else {
|
|
|
424 ASSERT_OK(strcmp(buf, "test-bu"));
|
|
|
425 r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
|
|
|
426 }
|
|
|
427 ASSERT_OK(r);
|
|
|
428 }
|
|
|
429
|
|
|
430
|
|
|
431 static void open_cb(uv_fs_t* req) {
|
|
|
432 int r;
|
|
|
433 ASSERT_PTR_EQ(req, &open_req1);
|
|
|
434 ASSERT_EQ(req->fs_type, UV_FS_OPEN);
|
|
|
435 if (req->result < 0) {
|
|
|
436 fprintf(stderr, "async open error: %d\n", (int) req->result);
|
|
|
437 ASSERT(0);
|
|
|
438 }
|
|
|
439 open_cb_count++;
|
|
|
440 ASSERT(req->path);
|
|
|
441 ASSERT_OK(memcmp(req->path, "test_file2\0", 11));
|
|
|
442 uv_fs_req_cleanup(req);
|
|
|
443 memset(buf, 0, sizeof(buf));
|
|
|
444 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
445 r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1,
|
|
|
446 read_cb);
|
|
|
447 ASSERT_OK(r);
|
|
|
448 }
|
|
|
449
|
|
|
450
|
|
|
451 static void open_cb_simple(uv_fs_t* req) {
|
|
|
452 ASSERT_EQ(req->fs_type, UV_FS_OPEN);
|
|
|
453 if (req->result < 0) {
|
|
|
454 fprintf(stderr, "async open error: %d\n", (int) req->result);
|
|
|
455 ASSERT(0);
|
|
|
456 }
|
|
|
457 open_cb_count++;
|
|
|
458 ASSERT(req->path);
|
|
|
459 uv_fs_req_cleanup(req);
|
|
|
460 }
|
|
|
461
|
|
|
462
|
|
|
463 static void fsync_cb(uv_fs_t* req) {
|
|
|
464 int r;
|
|
|
465 ASSERT_PTR_EQ(req, &fsync_req);
|
|
|
466 ASSERT_EQ(req->fs_type, UV_FS_FSYNC);
|
|
|
467 ASSERT_OK(req->result);
|
|
|
468 fsync_cb_count++;
|
|
|
469 uv_fs_req_cleanup(req);
|
|
|
470 r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
|
|
|
471 ASSERT_OK(r);
|
|
|
472 }
|
|
|
473
|
|
|
474
|
|
|
475 static void fdatasync_cb(uv_fs_t* req) {
|
|
|
476 int r;
|
|
|
477 ASSERT_PTR_EQ(req, &fdatasync_req);
|
|
|
478 ASSERT_EQ(req->fs_type, UV_FS_FDATASYNC);
|
|
|
479 ASSERT_OK(req->result);
|
|
|
480 fdatasync_cb_count++;
|
|
|
481 uv_fs_req_cleanup(req);
|
|
|
482 r = uv_fs_fsync(loop, &fsync_req, open_req1.result, fsync_cb);
|
|
|
483 ASSERT_OK(r);
|
|
|
484 }
|
|
|
485
|
|
|
486
|
|
|
487 static void write_cb(uv_fs_t* req) {
|
|
|
488 int r;
|
|
|
489 ASSERT_PTR_EQ(req, &write_req);
|
|
|
490 ASSERT_EQ(req->fs_type, UV_FS_WRITE);
|
|
|
491 ASSERT_GE(req->result, 0); /* FIXME(bnoordhuis) Check if requested size? */
|
|
|
492 write_cb_count++;
|
|
|
493 uv_fs_req_cleanup(req);
|
|
|
494 r = uv_fs_fdatasync(loop, &fdatasync_req, open_req1.result, fdatasync_cb);
|
|
|
495 ASSERT_OK(r);
|
|
|
496 }
|
|
|
497
|
|
|
498
|
|
|
499 static void create_cb(uv_fs_t* req) {
|
|
|
500 int r;
|
|
|
501 ASSERT_PTR_EQ(req, &open_req1);
|
|
|
502 ASSERT_EQ(req->fs_type, UV_FS_OPEN);
|
|
|
503 ASSERT_GE(req->result, 0);
|
|
|
504 create_cb_count++;
|
|
|
505 uv_fs_req_cleanup(req);
|
|
|
506 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
507 r = uv_fs_write(loop, &write_req, req->result, &iov, 1, -1, write_cb);
|
|
|
508 ASSERT_OK(r);
|
|
|
509 }
|
|
|
510
|
|
|
511
|
|
|
512 static void rename_cb(uv_fs_t* req) {
|
|
|
513 ASSERT_PTR_EQ(req, &rename_req);
|
|
|
514 ASSERT_EQ(req->fs_type, UV_FS_RENAME);
|
|
|
515 ASSERT_OK(req->result);
|
|
|
516 rename_cb_count++;
|
|
|
517 uv_fs_req_cleanup(req);
|
|
|
518 }
|
|
|
519
|
|
|
520
|
|
|
521 static void mkdir_cb(uv_fs_t* req) {
|
|
|
522 ASSERT_PTR_EQ(req, &mkdir_req);
|
|
|
523 ASSERT_EQ(req->fs_type, UV_FS_MKDIR);
|
|
|
524 ASSERT_OK(req->result);
|
|
|
525 mkdir_cb_count++;
|
|
|
526 ASSERT(req->path);
|
|
|
527 ASSERT_OK(memcmp(req->path, "test_dir\0", 9));
|
|
|
528 uv_fs_req_cleanup(req);
|
|
|
529 }
|
|
|
530
|
|
|
531
|
|
|
532 static void check_mkdtemp_result(uv_fs_t* req) {
|
|
|
533 int r;
|
|
|
534
|
|
|
535 ASSERT_EQ(req->fs_type, UV_FS_MKDTEMP);
|
|
|
536 ASSERT_OK(req->result);
|
|
|
537 ASSERT(req->path);
|
|
|
538 ASSERT_EQ(15, strlen(req->path));
|
|
|
539 ASSERT_OK(memcmp(req->path, "test_dir_", 9));
|
|
|
540 ASSERT_NE(0, memcmp(req->path + 9, "XXXXXX", 6));
|
|
|
541 check_permission(req->path, 0700);
|
|
|
542
|
|
|
543 /* Check if req->path is actually a directory */
|
|
|
544 r = uv_fs_stat(NULL, &stat_req, req->path, NULL);
|
|
|
545 ASSERT_OK(r);
|
|
|
546 ASSERT(((uv_stat_t*)stat_req.ptr)->st_mode & S_IFDIR);
|
|
|
547 uv_fs_req_cleanup(&stat_req);
|
|
|
548 }
|
|
|
549
|
|
|
550
|
|
|
551 static void mkdtemp_cb(uv_fs_t* req) {
|
|
|
552 ASSERT_PTR_EQ(req, &mkdtemp_req1);
|
|
|
553 check_mkdtemp_result(req);
|
|
|
554 mkdtemp_cb_count++;
|
|
|
555 }
|
|
|
556
|
|
|
557
|
|
|
558 static void check_mkstemp_result(uv_fs_t* req) {
|
|
|
559 int r;
|
|
|
560
|
|
|
561 ASSERT_EQ(req->fs_type, UV_FS_MKSTEMP);
|
|
|
562 ASSERT_GE(req->result, 0);
|
|
|
563 ASSERT(req->path);
|
|
|
564 ASSERT_EQ(16, strlen(req->path));
|
|
|
565 ASSERT_OK(memcmp(req->path, "test_file_", 10));
|
|
|
566 ASSERT_NE(0, memcmp(req->path + 10, "XXXXXX", 6));
|
|
|
567 check_permission(req->path, 0600);
|
|
|
568
|
|
|
569 /* Check if req->path is actually a file */
|
|
|
570 r = uv_fs_stat(NULL, &stat_req, req->path, NULL);
|
|
|
571 ASSERT_OK(r);
|
|
|
572 ASSERT(stat_req.statbuf.st_mode & S_IFREG);
|
|
|
573 uv_fs_req_cleanup(&stat_req);
|
|
|
574 }
|
|
|
575
|
|
|
576
|
|
|
577 static void mkstemp_cb(uv_fs_t* req) {
|
|
|
578 ASSERT_PTR_EQ(req, &mkstemp_req1);
|
|
|
579 check_mkstemp_result(req);
|
|
|
580 mkstemp_cb_count++;
|
|
|
581 }
|
|
|
582
|
|
|
583
|
|
|
584 static void rmdir_cb(uv_fs_t* req) {
|
|
|
585 ASSERT_PTR_EQ(req, &rmdir_req);
|
|
|
586 ASSERT_EQ(req->fs_type, UV_FS_RMDIR);
|
|
|
587 ASSERT_OK(req->result);
|
|
|
588 rmdir_cb_count++;
|
|
|
589 ASSERT(req->path);
|
|
|
590 ASSERT_OK(memcmp(req->path, "test_dir\0", 9));
|
|
|
591 uv_fs_req_cleanup(req);
|
|
|
592 }
|
|
|
593
|
|
|
594
|
|
|
595 static void assert_is_file_type(uv_dirent_t dent) {
|
|
|
596 #ifdef HAVE_DIRENT_TYPES
|
|
|
597 /*
|
|
|
598 * For Apple and Windows, we know getdents is expected to work but for other
|
|
|
599 * environments, the filesystem dictates whether or not getdents supports
|
|
|
600 * returning the file type.
|
|
|
601 *
|
|
|
602 * See:
|
|
|
603 * http://man7.org/linux/man-pages/man2/getdents.2.html
|
|
|
604 * https://github.com/libuv/libuv/issues/501
|
|
|
605 */
|
|
|
606 #if defined(__APPLE__) || defined(_WIN32)
|
|
|
607 ASSERT_EQ(dent.type, UV_DIRENT_FILE);
|
|
|
608 #else
|
|
|
609 ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
|
|
610 #endif
|
|
|
611 #else
|
|
|
612 ASSERT_EQ(dent.type, UV_DIRENT_UNKNOWN);
|
|
|
613 #endif
|
|
|
614 }
|
|
|
615
|
|
|
616
|
|
|
617 static void scandir_cb(uv_fs_t* req) {
|
|
|
618 uv_dirent_t dent;
|
|
|
619 ASSERT_PTR_EQ(req, &scandir_req);
|
|
|
620 ASSERT_EQ(req->fs_type, UV_FS_SCANDIR);
|
|
|
621 ASSERT_EQ(2, req->result);
|
|
|
622 ASSERT(req->ptr);
|
|
|
623
|
|
|
624 while (UV_EOF != uv_fs_scandir_next(req, &dent)) {
|
|
|
625 ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
|
|
626 assert_is_file_type(dent);
|
|
|
627 }
|
|
|
628 scandir_cb_count++;
|
|
|
629 ASSERT(req->path);
|
|
|
630 ASSERT_OK(memcmp(req->path, "test_dir\0", 9));
|
|
|
631 uv_fs_req_cleanup(req);
|
|
|
632 ASSERT(!req->ptr);
|
|
|
633 }
|
|
|
634
|
|
|
635
|
|
|
636 static void empty_scandir_cb(uv_fs_t* req) {
|
|
|
637 uv_dirent_t dent;
|
|
|
638
|
|
|
639 ASSERT_PTR_EQ(req, &scandir_req);
|
|
|
640 ASSERT_EQ(req->fs_type, UV_FS_SCANDIR);
|
|
|
641 ASSERT_OK(req->result);
|
|
|
642 ASSERT_NULL(req->ptr);
|
|
|
643 ASSERT_EQ(UV_EOF, uv_fs_scandir_next(req, &dent));
|
|
|
644 uv_fs_req_cleanup(req);
|
|
|
645 scandir_cb_count++;
|
|
|
646 }
|
|
|
647
|
|
|
648 static void non_existent_scandir_cb(uv_fs_t* req) {
|
|
|
649 uv_dirent_t dent;
|
|
|
650
|
|
|
651 ASSERT_PTR_EQ(req, &scandir_req);
|
|
|
652 ASSERT_EQ(req->fs_type, UV_FS_SCANDIR);
|
|
|
653 ASSERT_EQ(req->result, UV_ENOENT);
|
|
|
654 ASSERT_NULL(req->ptr);
|
|
|
655 ASSERT_EQ(UV_ENOENT, uv_fs_scandir_next(req, &dent));
|
|
|
656 uv_fs_req_cleanup(req);
|
|
|
657 scandir_cb_count++;
|
|
|
658 }
|
|
|
659
|
|
|
660
|
|
|
661 static void file_scandir_cb(uv_fs_t* req) {
|
|
|
662 ASSERT_PTR_EQ(req, &scandir_req);
|
|
|
663 ASSERT_EQ(req->fs_type, UV_FS_SCANDIR);
|
|
|
664 ASSERT_EQ(req->result, UV_ENOTDIR);
|
|
|
665 ASSERT_NULL(req->ptr);
|
|
|
666 uv_fs_req_cleanup(req);
|
|
|
667 scandir_cb_count++;
|
|
|
668 }
|
|
|
669
|
|
|
670
|
|
|
671 static void stat_cb(uv_fs_t* req) {
|
|
|
672 ASSERT_PTR_EQ(req, &stat_req);
|
|
|
673 ASSERT(req->fs_type == UV_FS_STAT || req->fs_type == UV_FS_LSTAT);
|
|
|
674 ASSERT_OK(req->result);
|
|
|
675 ASSERT(req->ptr);
|
|
|
676 stat_cb_count++;
|
|
|
677 uv_fs_req_cleanup(req);
|
|
|
678 ASSERT(!req->ptr);
|
|
|
679 }
|
|
|
680
|
|
|
681 static void stat_batch_cb(uv_fs_t* req) {
|
|
|
682 ASSERT(req->fs_type == UV_FS_STAT || req->fs_type == UV_FS_LSTAT);
|
|
|
683 ASSERT_OK(req->result);
|
|
|
684 ASSERT(req->ptr);
|
|
|
685 stat_cb_count++;
|
|
|
686 uv_fs_req_cleanup(req);
|
|
|
687 ASSERT(!req->ptr);
|
|
|
688 }
|
|
|
689
|
|
|
690
|
|
|
691 static void sendfile_cb(uv_fs_t* req) {
|
|
|
692 ASSERT_PTR_EQ(req, &sendfile_req);
|
|
|
693 ASSERT_EQ(req->fs_type, UV_FS_SENDFILE);
|
|
|
694 ASSERT_EQ(65545, req->result);
|
|
|
695 sendfile_cb_count++;
|
|
|
696 uv_fs_req_cleanup(req);
|
|
|
697 }
|
|
|
698
|
|
|
699
|
|
|
700 static void sendfile_nodata_cb(uv_fs_t* req) {
|
|
|
701 ASSERT_PTR_EQ(req, &sendfile_req);
|
|
|
702 ASSERT_EQ(req->fs_type, UV_FS_SENDFILE);
|
|
|
703 ASSERT_OK(req->result);
|
|
|
704 sendfile_cb_count++;
|
|
|
705 uv_fs_req_cleanup(req);
|
|
|
706 }
|
|
|
707
|
|
|
708
|
|
|
709 static void open_noent_cb(uv_fs_t* req) {
|
|
|
710 ASSERT_EQ(req->fs_type, UV_FS_OPEN);
|
|
|
711 ASSERT_EQ(req->result, UV_ENOENT);
|
|
|
712 open_cb_count++;
|
|
|
713 uv_fs_req_cleanup(req);
|
|
|
714 }
|
|
|
715
|
|
|
716 static void open_nametoolong_cb(uv_fs_t* req) {
|
|
|
717 ASSERT_EQ(req->fs_type, UV_FS_OPEN);
|
|
|
718 ASSERT_EQ(req->result, UV_ENAMETOOLONG);
|
|
|
719 open_cb_count++;
|
|
|
720 uv_fs_req_cleanup(req);
|
|
|
721 }
|
|
|
722
|
|
|
723 static void open_loop_cb(uv_fs_t* req) {
|
|
|
724 ASSERT_EQ(req->fs_type, UV_FS_OPEN);
|
|
|
725 ASSERT_EQ(req->result, UV_ELOOP);
|
|
|
726 open_cb_count++;
|
|
|
727 uv_fs_req_cleanup(req);
|
|
|
728 }
|
|
|
729
|
|
|
730
|
|
|
731 TEST_IMPL(fs_file_noent) {
|
|
|
732 uv_fs_t req;
|
|
|
733 int r;
|
|
|
734
|
|
|
735 loop = uv_default_loop();
|
|
|
736
|
|
|
737 r = uv_fs_open(NULL, &req, "does_not_exist", UV_FS_O_RDONLY, 0, NULL);
|
|
|
738 ASSERT_EQ(r, UV_ENOENT);
|
|
|
739 ASSERT_EQ(req.result, UV_ENOENT);
|
|
|
740 uv_fs_req_cleanup(&req);
|
|
|
741
|
|
|
742 r = uv_fs_open(loop, &req, "does_not_exist", UV_FS_O_RDONLY, 0,
|
|
|
743 open_noent_cb);
|
|
|
744 ASSERT_OK(r);
|
|
|
745
|
|
|
746 ASSERT_OK(open_cb_count);
|
|
|
747 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
748 ASSERT_EQ(1, open_cb_count);
|
|
|
749
|
|
|
750 /* TODO add EACCES test */
|
|
|
751
|
|
|
752 MAKE_VALGRIND_HAPPY(loop);
|
|
|
753 return 0;
|
|
|
754 }
|
|
|
755
|
|
|
756 TEST_IMPL(fs_file_nametoolong) {
|
|
|
757 uv_fs_t req;
|
|
|
758 int r;
|
|
|
759 char name[TOO_LONG_NAME_LENGTH + 1];
|
|
|
760
|
|
|
761 loop = uv_default_loop();
|
|
|
762
|
|
|
763 memset(name, 'a', TOO_LONG_NAME_LENGTH);
|
|
|
764 name[TOO_LONG_NAME_LENGTH] = 0;
|
|
|
765
|
|
|
766 r = uv_fs_open(NULL, &req, name, UV_FS_O_RDONLY, 0, NULL);
|
|
|
767 ASSERT_EQ(r, UV_ENAMETOOLONG);
|
|
|
768 ASSERT_EQ(req.result, UV_ENAMETOOLONG);
|
|
|
769 uv_fs_req_cleanup(&req);
|
|
|
770
|
|
|
771 r = uv_fs_open(loop, &req, name, UV_FS_O_RDONLY, 0, open_nametoolong_cb);
|
|
|
772 ASSERT_OK(r);
|
|
|
773
|
|
|
774 ASSERT_OK(open_cb_count);
|
|
|
775 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
776 ASSERT_EQ(1, open_cb_count);
|
|
|
777
|
|
|
778 MAKE_VALGRIND_HAPPY(loop);
|
|
|
779 return 0;
|
|
|
780 }
|
|
|
781
|
|
|
782 TEST_IMPL(fs_file_loop) {
|
|
|
783 uv_fs_t req;
|
|
|
784 int r;
|
|
|
785
|
|
|
786 loop = uv_default_loop();
|
|
|
787
|
|
|
788 unlink("test_symlink");
|
|
|
789 r = uv_fs_symlink(NULL, &req, "test_symlink", "test_symlink", 0, NULL);
|
|
|
790 #ifdef _WIN32
|
|
|
791 /*
|
|
|
792 * Symlinks are only suported but only when elevated, otherwise
|
|
|
793 * we'll see UV_EPERM.
|
|
|
794 */
|
|
|
795 if (r == UV_EPERM)
|
|
|
796 return 0;
|
|
|
797 #elif defined(__MSYS__)
|
|
|
798 /* MSYS2's approximation of symlinks with copies does not work for broken
|
|
|
799 links. */
|
|
|
800 if (r == UV_ENOENT)
|
|
|
801 return 0;
|
|
|
802 #endif
|
|
|
803 ASSERT_OK(r);
|
|
|
804 uv_fs_req_cleanup(&req);
|
|
|
805
|
|
|
806 r = uv_fs_open(NULL, &req, "test_symlink", UV_FS_O_RDONLY, 0, NULL);
|
|
|
807 ASSERT_EQ(r, UV_ELOOP);
|
|
|
808 ASSERT_EQ(req.result, UV_ELOOP);
|
|
|
809 uv_fs_req_cleanup(&req);
|
|
|
810
|
|
|
811 r = uv_fs_open(loop, &req, "test_symlink", UV_FS_O_RDONLY, 0, open_loop_cb);
|
|
|
812 ASSERT_OK(r);
|
|
|
813
|
|
|
814 ASSERT_OK(open_cb_count);
|
|
|
815 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
816 ASSERT_EQ(1, open_cb_count);
|
|
|
817
|
|
|
818 unlink("test_symlink");
|
|
|
819
|
|
|
820 MAKE_VALGRIND_HAPPY(loop);
|
|
|
821 return 0;
|
|
|
822 }
|
|
|
823
|
|
|
824 static void check_utime(const char* path,
|
|
|
825 double atime,
|
|
|
826 double mtime,
|
|
|
827 int test_lutime) {
|
|
|
828 uv_stat_t* s;
|
|
|
829 uv_fs_t req;
|
|
|
830 int r;
|
|
|
831
|
|
|
832 if (test_lutime)
|
|
|
833 r = uv_fs_lstat(loop, &req, path, NULL);
|
|
|
834 else
|
|
|
835 r = uv_fs_stat(loop, &req, path, NULL);
|
|
|
836
|
|
|
837 ASSERT_OK(r);
|
|
|
838
|
|
|
839 ASSERT_OK(req.result);
|
|
|
840 s = &req.statbuf;
|
|
|
841
|
|
|
842 if (isfinite(atime)) {
|
|
|
843 /* Test sub-second timestamps only when supported (such as Windows with
|
|
|
844 * NTFS). Some other platforms support sub-second timestamps, but that
|
|
|
845 * support is filesystem-dependent. Notably OS X (HFS Plus) does NOT
|
|
|
846 * support sub-second timestamps. But kernels may round or truncate in
|
|
|
847 * either direction, so we may accept either possible answer.
|
|
|
848 */
|
|
|
849 if (s->st_atim.tv_nsec == 0) {
|
|
|
850 if (is_win32)
|
|
|
851 ASSERT_DOUBLE_EQ(atime, (long) atime);
|
|
|
852 if (atime > 0 || (long) atime == atime)
|
|
|
853 ASSERT_EQ(s->st_atim.tv_sec, (long) atime);
|
|
|
854 ASSERT_GE(s->st_atim.tv_sec, (long) atime - 1);
|
|
|
855 ASSERT_LE(s->st_atim.tv_sec, (long) atime);
|
|
|
856 } else {
|
|
|
857 double st_atim;
|
|
|
858 /* TODO(vtjnash): would it be better to normalize this? */
|
|
|
859 if (!is_apple_or_sunpro_c)
|
|
|
860 ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0);
|
|
|
861 st_atim = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9;
|
|
|
862 /* Linux does not allow reading reliably the atime of a symlink
|
|
|
863 * since readlink() can update it
|
|
|
864 */
|
|
|
865 if (!test_lutime)
|
|
|
866 ASSERT_DOUBLE_EQ(st_atim, atime);
|
|
|
867 }
|
|
|
868 } else if (isinf(atime)) {
|
|
|
869 /* We test with timestamps that are in the distant past
|
|
|
870 * (if you're a Gen Z-er) so check it's more recent than that.
|
|
|
871 */
|
|
|
872 ASSERT_GT(s->st_atim.tv_sec, 1739710000);
|
|
|
873 } else {
|
|
|
874 ASSERT_OK(0);
|
|
|
875 }
|
|
|
876
|
|
|
877 if (isfinite(mtime)) {
|
|
|
878 /* Test sub-second timestamps only when supported (such as Windows with
|
|
|
879 * NTFS). Some other platforms support sub-second timestamps, but that
|
|
|
880 * support is filesystem-dependent. Notably OS X (HFS Plus) does NOT
|
|
|
881 * support sub-second timestamps. But kernels may round or truncate in
|
|
|
882 * either direction, so we may accept either possible answer.
|
|
|
883 */
|
|
|
884 if (s->st_mtim.tv_nsec == 0) {
|
|
|
885 if (is_win32)
|
|
|
886 ASSERT_DOUBLE_EQ(mtime, (long) atime);
|
|
|
887 if (mtime > 0 || (long) mtime == mtime)
|
|
|
888 ASSERT_EQ(s->st_mtim.tv_sec, (long) mtime);
|
|
|
889 ASSERT_GE(s->st_mtim.tv_sec, (long) mtime - 1);
|
|
|
890 ASSERT_LE(s->st_mtim.tv_sec, (long) mtime);
|
|
|
891 } else {
|
|
|
892 double st_mtim;
|
|
|
893 /* TODO(vtjnash): would it be better to normalize this? */
|
|
|
894 if (!is_apple_or_sunpro_c)
|
|
|
895 ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0);
|
|
|
896 st_mtim = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9;
|
|
|
897 ASSERT_DOUBLE_EQ(st_mtim, mtime);
|
|
|
898 }
|
|
|
899 } else if (isinf(mtime)) {
|
|
|
900 /* We test with timestamps that are in the distant past
|
|
|
901 * (if you're a Gen Z-er) so check it's more recent than that.
|
|
|
902 */
|
|
|
903 ASSERT_GT(s->st_mtim.tv_sec, 1739710000);
|
|
|
904 } else {
|
|
|
905 ASSERT_OK(0);
|
|
|
906 }
|
|
|
907
|
|
|
908 uv_fs_req_cleanup(&req);
|
|
|
909 }
|
|
|
910
|
|
|
911
|
|
|
912 static void utime_cb(uv_fs_t* req) {
|
|
|
913 utime_check_t* c;
|
|
|
914
|
|
|
915 ASSERT_PTR_EQ(req, &utime_req);
|
|
|
916 ASSERT_OK(req->result);
|
|
|
917 ASSERT_EQ(req->fs_type, UV_FS_UTIME);
|
|
|
918
|
|
|
919 c = req->data;
|
|
|
920 check_utime(c->path, c->atime, c->mtime, /* test_lutime */ 0);
|
|
|
921
|
|
|
922 uv_fs_req_cleanup(req);
|
|
|
923 utime_cb_count++;
|
|
|
924 }
|
|
|
925
|
|
|
926
|
|
|
927 static void futime_cb(uv_fs_t* req) {
|
|
|
928 utime_check_t* c;
|
|
|
929
|
|
|
930 ASSERT_PTR_EQ(req, &futime_req);
|
|
|
931 ASSERT_OK(req->result);
|
|
|
932 ASSERT_EQ(req->fs_type, UV_FS_FUTIME);
|
|
|
933
|
|
|
934 c = req->data;
|
|
|
935 check_utime(c->path, c->atime, c->mtime, /* test_lutime */ 0);
|
|
|
936
|
|
|
937 uv_fs_req_cleanup(req);
|
|
|
938 futime_cb_count++;
|
|
|
939 }
|
|
|
940
|
|
|
941
|
|
|
942 static void lutime_cb(uv_fs_t* req) {
|
|
|
943 utime_check_t* c;
|
|
|
944
|
|
|
945 ASSERT_OK(req->result);
|
|
|
946 ASSERT_EQ(req->fs_type, UV_FS_LUTIME);
|
|
|
947
|
|
|
948 c = req->data;
|
|
|
949 check_utime(c->path, c->atime, c->mtime, /* test_lutime */ 1);
|
|
|
950
|
|
|
951 uv_fs_req_cleanup(req);
|
|
|
952 lutime_cb_count++;
|
|
|
953 }
|
|
|
954
|
|
|
955
|
|
|
956 TEST_IMPL(fs_file_async) {
|
|
|
957 int r;
|
|
|
958
|
|
|
959 /* Setup. */
|
|
|
960 unlink("test_file");
|
|
|
961 unlink("test_file2");
|
|
|
962
|
|
|
963 loop = uv_default_loop();
|
|
|
964
|
|
|
965 r = uv_fs_open(loop, &open_req1, "test_file", UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
|
|
966 S_IRUSR | S_IWUSR, create_cb);
|
|
|
967 ASSERT_OK(r);
|
|
|
968 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
969
|
|
|
970 ASSERT_EQ(1, create_cb_count);
|
|
|
971 ASSERT_EQ(1, write_cb_count);
|
|
|
972 ASSERT_EQ(1, fsync_cb_count);
|
|
|
973 ASSERT_EQ(1, fdatasync_cb_count);
|
|
|
974 ASSERT_EQ(1, close_cb_count);
|
|
|
975
|
|
|
976 r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", rename_cb);
|
|
|
977 ASSERT_OK(r);
|
|
|
978
|
|
|
979 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
980 ASSERT_EQ(1, create_cb_count);
|
|
|
981 ASSERT_EQ(1, write_cb_count);
|
|
|
982 ASSERT_EQ(1, close_cb_count);
|
|
|
983 ASSERT_EQ(1, rename_cb_count);
|
|
|
984
|
|
|
985 r = uv_fs_open(loop, &open_req1, "test_file2", UV_FS_O_RDWR, 0, open_cb);
|
|
|
986 ASSERT_OK(r);
|
|
|
987
|
|
|
988 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
989 ASSERT_EQ(1, open_cb_count);
|
|
|
990 ASSERT_EQ(1, read_cb_count);
|
|
|
991 ASSERT_EQ(2, close_cb_count);
|
|
|
992 ASSERT_EQ(1, rename_cb_count);
|
|
|
993 ASSERT_EQ(1, create_cb_count);
|
|
|
994 ASSERT_EQ(1, write_cb_count);
|
|
|
995 ASSERT_EQ(1, ftruncate_cb_count);
|
|
|
996
|
|
|
997 r = uv_fs_open(loop, &open_req1, "test_file2", UV_FS_O_RDONLY, 0, open_cb);
|
|
|
998 ASSERT_OK(r);
|
|
|
999
|
|
|
1000 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1001 ASSERT_EQ(2, open_cb_count);
|
|
|
1002 ASSERT_EQ(2, read_cb_count);
|
|
|
1003 ASSERT_EQ(3, close_cb_count);
|
|
|
1004 ASSERT_EQ(1, rename_cb_count);
|
|
|
1005 ASSERT_EQ(1, unlink_cb_count);
|
|
|
1006 ASSERT_EQ(1, create_cb_count);
|
|
|
1007 ASSERT_EQ(1, write_cb_count);
|
|
|
1008 ASSERT_EQ(1, ftruncate_cb_count);
|
|
|
1009
|
|
|
1010 /* Cleanup. */
|
|
|
1011 unlink("test_file");
|
|
|
1012 unlink("test_file2");
|
|
|
1013
|
|
|
1014 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1015 return 0;
|
|
|
1016 }
|
|
|
1017
|
|
|
1018
|
|
|
1019 static void fs_file_sync(int add_flags) {
|
|
|
1020 int r;
|
|
|
1021
|
|
|
1022 /* Setup. */
|
|
|
1023 unlink("test_file");
|
|
|
1024 unlink("test_file2");
|
|
|
1025
|
|
|
1026 loop = uv_default_loop();
|
|
|
1027
|
|
|
1028 r = uv_fs_open(loop, &open_req1, "test_file",
|
|
|
1029 UV_FS_O_WRONLY | UV_FS_O_CREAT | add_flags, S_IWUSR | S_IRUSR,
|
|
|
1030 NULL);
|
|
|
1031 ASSERT_GE(r, 0);
|
|
|
1032 ASSERT_GE(open_req1.result, 0);
|
|
|
1033 uv_fs_req_cleanup(&open_req1);
|
|
|
1034
|
|
|
1035 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
1036 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
1037 ASSERT_GE(r, 0);
|
|
|
1038 ASSERT_GE(write_req.result, 0);
|
|
|
1039 uv_fs_req_cleanup(&write_req);
|
|
|
1040
|
|
|
1041 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
1042 ASSERT_OK(r);
|
|
|
1043 ASSERT_OK(close_req.result);
|
|
|
1044 uv_fs_req_cleanup(&close_req);
|
|
|
1045
|
|
|
1046 r = uv_fs_open(NULL, &open_req1, "test_file", UV_FS_O_RDWR | add_flags, 0,
|
|
|
1047 NULL);
|
|
|
1048 ASSERT_GE(r, 0);
|
|
|
1049 ASSERT_GE(open_req1.result, 0);
|
|
|
1050 uv_fs_req_cleanup(&open_req1);
|
|
|
1051
|
|
|
1052 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
1053 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
1054 ASSERT_GE(r, 0);
|
|
|
1055 ASSERT_GE(read_req.result, 0);
|
|
|
1056 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
1057 uv_fs_req_cleanup(&read_req);
|
|
|
1058
|
|
|
1059 r = uv_fs_ftruncate(NULL, &ftruncate_req, open_req1.result, 7, NULL);
|
|
|
1060 ASSERT_OK(r);
|
|
|
1061 ASSERT_OK(ftruncate_req.result);
|
|
|
1062 uv_fs_req_cleanup(&ftruncate_req);
|
|
|
1063
|
|
|
1064 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
1065 ASSERT_OK(r);
|
|
|
1066 ASSERT_OK(close_req.result);
|
|
|
1067 uv_fs_req_cleanup(&close_req);
|
|
|
1068
|
|
|
1069 r = uv_fs_rename(NULL, &rename_req, "test_file", "test_file2", NULL);
|
|
|
1070 ASSERT_OK(r);
|
|
|
1071 ASSERT_OK(rename_req.result);
|
|
|
1072 uv_fs_req_cleanup(&rename_req);
|
|
|
1073
|
|
|
1074 r = uv_fs_open(NULL, &open_req1, "test_file2", UV_FS_O_RDONLY | add_flags, 0,
|
|
|
1075 NULL);
|
|
|
1076 ASSERT_GE(r, 0);
|
|
|
1077 ASSERT_GE(open_req1.result, 0);
|
|
|
1078 uv_fs_req_cleanup(&open_req1);
|
|
|
1079
|
|
|
1080 memset(buf, 0, sizeof(buf));
|
|
|
1081 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
1082 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
1083 ASSERT_GE(r, 0);
|
|
|
1084 ASSERT_GE(read_req.result, 0);
|
|
|
1085 ASSERT_OK(strcmp(buf, "test-bu"));
|
|
|
1086 uv_fs_req_cleanup(&read_req);
|
|
|
1087
|
|
|
1088 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
1089 ASSERT_OK(r);
|
|
|
1090 ASSERT_OK(close_req.result);
|
|
|
1091 uv_fs_req_cleanup(&close_req);
|
|
|
1092
|
|
|
1093 r = uv_fs_unlink(NULL, &unlink_req, "test_file2", NULL);
|
|
|
1094 ASSERT_OK(r);
|
|
|
1095 ASSERT_OK(unlink_req.result);
|
|
|
1096 uv_fs_req_cleanup(&unlink_req);
|
|
|
1097
|
|
|
1098 /* Cleanup */
|
|
|
1099 unlink("test_file");
|
|
|
1100 unlink("test_file2");
|
|
|
1101 }
|
|
|
1102 TEST_IMPL(fs_file_sync) {
|
|
|
1103 fs_file_sync(0);
|
|
|
1104 fs_file_sync(UV_FS_O_FILEMAP);
|
|
|
1105
|
|
|
1106 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
1107 return 0;
|
|
|
1108 }
|
|
|
1109
|
|
|
1110 TEST_IMPL(fs_posix_delete) {
|
|
|
1111 int r;
|
|
|
1112
|
|
|
1113 /* Setup. */
|
|
|
1114 unlink("test_dir/file");
|
|
|
1115 rmdir("test_dir");
|
|
|
1116
|
|
|
1117 r = uv_fs_mkdir(NULL, &mkdir_req, "test_dir", 0755, NULL);
|
|
|
1118 ASSERT_OK(r);
|
|
|
1119
|
|
|
1120 r = uv_fs_open(NULL, &open_req_noclose, "test_dir/file", UV_FS_O_WRONLY | UV_FS_O_CREAT, S_IWUSR | S_IRUSR, NULL);
|
|
|
1121 ASSERT_GE(r, 0);
|
|
|
1122 uv_fs_req_cleanup(&open_req_noclose);
|
|
|
1123
|
|
|
1124 /* should not be possible to delete the non-empty dir */
|
|
|
1125 r = uv_fs_rmdir(NULL, &rmdir_req, "test_dir", NULL);
|
|
|
1126 ASSERT((r == UV_ENOTEMPTY) || (r == UV_EEXIST));
|
|
|
1127 ASSERT_EQ(r, rmdir_req.result);
|
|
|
1128 uv_fs_req_cleanup(&rmdir_req);
|
|
|
1129
|
|
|
1130 r = uv_fs_rmdir(NULL, &rmdir_req, "test_dir/file", NULL);
|
|
|
1131 ASSERT((r == UV_ENOTDIR) || (r == UV_ENOENT));
|
|
|
1132 ASSERT_EQ(r, rmdir_req.result);
|
|
|
1133 uv_fs_req_cleanup(&rmdir_req);
|
|
|
1134
|
|
|
1135 r = uv_fs_unlink(NULL, &unlink_req, "test_dir/file", NULL);
|
|
|
1136 ASSERT_OK(r);
|
|
|
1137 ASSERT_OK(unlink_req.result);
|
|
|
1138 uv_fs_req_cleanup(&unlink_req);
|
|
|
1139
|
|
|
1140 /* delete the dir while the file is still open, which should succeed on posix */
|
|
|
1141 r = uv_fs_rmdir(NULL, &rmdir_req, "test_dir", NULL);
|
|
|
1142 ASSERT_OK(r);
|
|
|
1143 ASSERT_OK(rmdir_req.result);
|
|
|
1144 uv_fs_req_cleanup(&rmdir_req);
|
|
|
1145
|
|
|
1146 /* Cleanup */
|
|
|
1147 r = uv_fs_close(NULL, &close_req, open_req_noclose.result, NULL);
|
|
|
1148 ASSERT_OK(r);
|
|
|
1149 uv_fs_req_cleanup(&close_req);
|
|
|
1150
|
|
|
1151 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
1152 return 0;
|
|
|
1153 }
|
|
|
1154
|
|
|
1155 static void fs_file_write_null_buffer(int add_flags) {
|
|
|
1156 int r;
|
|
|
1157
|
|
|
1158 /* Setup. */
|
|
|
1159 unlink("test_file");
|
|
|
1160
|
|
|
1161 loop = uv_default_loop();
|
|
|
1162
|
|
|
1163 r = uv_fs_open(NULL, &open_req1, "test_file",
|
|
|
1164 UV_FS_O_WRONLY | UV_FS_O_CREAT | add_flags, S_IWUSR | S_IRUSR,
|
|
|
1165 NULL);
|
|
|
1166 ASSERT_GE(r, 0);
|
|
|
1167 ASSERT_GE(open_req1.result, 0);
|
|
|
1168 uv_fs_req_cleanup(&open_req1);
|
|
|
1169
|
|
|
1170 iov = uv_buf_init(NULL, 0);
|
|
|
1171 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
1172 ASSERT_OK(r);
|
|
|
1173 ASSERT_OK(write_req.result);
|
|
|
1174 uv_fs_req_cleanup(&write_req);
|
|
|
1175
|
|
|
1176 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
1177 ASSERT_OK(r);
|
|
|
1178 ASSERT_OK(close_req.result);
|
|
|
1179 uv_fs_req_cleanup(&close_req);
|
|
|
1180
|
|
|
1181 unlink("test_file");
|
|
|
1182 }
|
|
|
1183 TEST_IMPL(fs_file_write_null_buffer) {
|
|
|
1184 fs_file_write_null_buffer(0);
|
|
|
1185 fs_file_write_null_buffer(UV_FS_O_FILEMAP);
|
|
|
1186
|
|
|
1187 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1188 return 0;
|
|
|
1189 }
|
|
|
1190
|
|
|
1191
|
|
|
1192 TEST_IMPL(fs_async_dir) {
|
|
|
1193 int r;
|
|
|
1194 uv_dirent_t dent;
|
|
|
1195
|
|
|
1196 /* Setup */
|
|
|
1197 unlink("test_dir/file1");
|
|
|
1198 unlink("test_dir/file2");
|
|
|
1199 rmdir("test_dir");
|
|
|
1200
|
|
|
1201 loop = uv_default_loop();
|
|
|
1202
|
|
|
1203 r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb);
|
|
|
1204 ASSERT_OK(r);
|
|
|
1205
|
|
|
1206 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1207 ASSERT_EQ(1, mkdir_cb_count);
|
|
|
1208
|
|
|
1209 /* Create 2 files synchronously. */
|
|
|
1210 r = uv_fs_open(NULL, &open_req1, "test_dir/file1",
|
|
|
1211 UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
|
|
1212 S_IWUSR | S_IRUSR, NULL);
|
|
|
1213 ASSERT_GE(r, 0);
|
|
|
1214 uv_fs_req_cleanup(&open_req1);
|
|
|
1215 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
1216 ASSERT_OK(r);
|
|
|
1217 uv_fs_req_cleanup(&close_req);
|
|
|
1218
|
|
|
1219 r = uv_fs_open(NULL, &open_req1, "test_dir/file2",
|
|
|
1220 UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
|
|
1221 S_IWUSR | S_IRUSR, NULL);
|
|
|
1222 ASSERT_GE(r, 0);
|
|
|
1223 uv_fs_req_cleanup(&open_req1);
|
|
|
1224 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
1225 ASSERT_OK(r);
|
|
|
1226 uv_fs_req_cleanup(&close_req);
|
|
|
1227
|
|
|
1228 r = uv_fs_scandir(loop, &scandir_req, "test_dir", 0, scandir_cb);
|
|
|
1229 ASSERT_OK(r);
|
|
|
1230
|
|
|
1231 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1232 ASSERT_EQ(1, scandir_cb_count);
|
|
|
1233
|
|
|
1234 /* sync uv_fs_scandir */
|
|
|
1235 r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL);
|
|
|
1236 ASSERT_EQ(2, r);
|
|
|
1237 ASSERT_EQ(2, scandir_req.result);
|
|
|
1238 ASSERT(scandir_req.ptr);
|
|
|
1239 while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
|
|
|
1240 ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
|
|
1241 assert_is_file_type(dent);
|
|
|
1242 }
|
|
|
1243 uv_fs_req_cleanup(&scandir_req);
|
|
|
1244 ASSERT(!scandir_req.ptr);
|
|
|
1245
|
|
|
1246 r = uv_fs_stat(loop, &stat_req, "test_dir", stat_cb);
|
|
|
1247 ASSERT_OK(r);
|
|
|
1248 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1249
|
|
|
1250 r = uv_fs_stat(loop, &stat_req, "test_dir/", stat_cb);
|
|
|
1251 ASSERT_OK(r);
|
|
|
1252 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1253
|
|
|
1254 r = uv_fs_lstat(loop, &stat_req, "test_dir", stat_cb);
|
|
|
1255 ASSERT_OK(r);
|
|
|
1256 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1257
|
|
|
1258 r = uv_fs_lstat(loop, &stat_req, "test_dir/", stat_cb);
|
|
|
1259 ASSERT_OK(r);
|
|
|
1260 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1261
|
|
|
1262 ASSERT_EQ(4, stat_cb_count);
|
|
|
1263
|
|
|
1264 r = uv_fs_unlink(loop, &unlink_req, "test_dir/file1", unlink_cb);
|
|
|
1265 ASSERT_OK(r);
|
|
|
1266 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1267 ASSERT_EQ(1, unlink_cb_count);
|
|
|
1268
|
|
|
1269 r = uv_fs_unlink(loop, &unlink_req, "test_dir/file2", unlink_cb);
|
|
|
1270 ASSERT_OK(r);
|
|
|
1271 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1272 ASSERT_EQ(2, unlink_cb_count);
|
|
|
1273
|
|
|
1274 r = uv_fs_rmdir(loop, &rmdir_req, "test_dir", rmdir_cb);
|
|
|
1275 ASSERT_OK(r);
|
|
|
1276 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1277 ASSERT_EQ(1, rmdir_cb_count);
|
|
|
1278
|
|
|
1279 /* Cleanup */
|
|
|
1280 unlink("test_dir/file1");
|
|
|
1281 unlink("test_dir/file2");
|
|
|
1282 rmdir("test_dir");
|
|
|
1283
|
|
|
1284 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1285 return 0;
|
|
|
1286 }
|
|
|
1287
|
|
|
1288
|
|
|
1289 static int test_sendfile(void (*setup)(int), uv_fs_cb cb, size_t expected_size) {
|
|
|
1290 int f, r;
|
|
|
1291 struct stat s1, s2;
|
|
|
1292 uv_fs_t req;
|
|
|
1293 char buf1[1];
|
|
|
1294
|
|
|
1295 loop = uv_default_loop();
|
|
|
1296
|
|
|
1297 /* Setup. */
|
|
|
1298 unlink("test_file");
|
|
|
1299 unlink("test_file2");
|
|
|
1300
|
|
|
1301 f = open("test_file", UV_FS_O_WRONLY | UV_FS_O_CREAT, S_IWUSR | S_IRUSR);
|
|
|
1302 ASSERT_NE(f, -1);
|
|
|
1303
|
|
|
1304 if (setup != NULL)
|
|
|
1305 setup(f);
|
|
|
1306
|
|
|
1307 r = close(f);
|
|
|
1308 ASSERT_OK(r);
|
|
|
1309
|
|
|
1310 /* Test starts here. */
|
|
|
1311 r = uv_fs_open(NULL, &open_req1, "test_file", UV_FS_O_RDWR, 0, NULL);
|
|
|
1312 ASSERT_GE(r, 0);
|
|
|
1313 ASSERT_GE(open_req1.result, 0);
|
|
|
1314 uv_fs_req_cleanup(&open_req1);
|
|
|
1315
|
|
|
1316 r = uv_fs_open(NULL, &open_req2, "test_file2", UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
|
|
1317 S_IWUSR | S_IRUSR, NULL);
|
|
|
1318 ASSERT_GE(r, 0);
|
|
|
1319 ASSERT_GE(open_req2.result, 0);
|
|
|
1320 uv_fs_req_cleanup(&open_req2);
|
|
|
1321
|
|
|
1322 r = uv_fs_sendfile(loop, &sendfile_req, open_req2.result, open_req1.result,
|
|
|
1323 1, 131072, cb);
|
|
|
1324 ASSERT_OK(r);
|
|
|
1325 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1326
|
|
|
1327 ASSERT_EQ(1, sendfile_cb_count);
|
|
|
1328
|
|
|
1329 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
1330 ASSERT_OK(r);
|
|
|
1331 uv_fs_req_cleanup(&close_req);
|
|
|
1332 r = uv_fs_close(NULL, &close_req, open_req2.result, NULL);
|
|
|
1333 ASSERT_OK(r);
|
|
|
1334 uv_fs_req_cleanup(&close_req);
|
|
|
1335
|
|
|
1336 memset(&s1, 0, sizeof(s1));
|
|
|
1337 memset(&s2, 0, sizeof(s2));
|
|
|
1338 ASSERT_OK(stat("test_file", &s1));
|
|
|
1339 ASSERT_OK(stat("test_file2", &s2));
|
|
|
1340 ASSERT_EQ(s2.st_size, expected_size);
|
|
|
1341
|
|
|
1342 if (expected_size > 0) {
|
|
|
1343 ASSERT_UINT64_EQ(s1.st_size, s2.st_size + 1);
|
|
|
1344 r = uv_fs_open(NULL, &open_req1, "test_file2", UV_FS_O_RDWR, 0, NULL);
|
|
|
1345 ASSERT_GE(r, 0);
|
|
|
1346 ASSERT_GE(open_req1.result, 0);
|
|
|
1347 uv_fs_req_cleanup(&open_req1);
|
|
|
1348
|
|
|
1349 memset(buf1, 0, sizeof(buf1));
|
|
|
1350 iov = uv_buf_init(buf1, sizeof(buf1));
|
|
|
1351 r = uv_fs_read(NULL, &req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
1352 ASSERT_GE(r, 0);
|
|
|
1353 ASSERT_GE(req.result, 0);
|
|
|
1354 ASSERT_EQ(buf1[0], 'e'); /* 'e' from begin */
|
|
|
1355 uv_fs_req_cleanup(&req);
|
|
|
1356 } else {
|
|
|
1357 ASSERT_UINT64_EQ(s1.st_size, s2.st_size);
|
|
|
1358 }
|
|
|
1359
|
|
|
1360 /* Cleanup. */
|
|
|
1361 unlink("test_file");
|
|
|
1362 unlink("test_file2");
|
|
|
1363
|
|
|
1364 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1365 return 0;
|
|
|
1366 }
|
|
|
1367
|
|
|
1368
|
|
|
1369 static void sendfile_setup(int f) {
|
|
|
1370 ASSERT_EQ(6, write(f, "begin\n", 6));
|
|
|
1371 ASSERT_EQ(65542, lseek(f, 65536, SEEK_CUR));
|
|
|
1372 ASSERT_EQ(4, write(f, "end\n", 4));
|
|
|
1373 }
|
|
|
1374
|
|
|
1375
|
|
|
1376 TEST_IMPL(fs_async_sendfile) {
|
|
|
1377 return test_sendfile(sendfile_setup, sendfile_cb, 65545);
|
|
|
1378 }
|
|
|
1379
|
|
|
1380
|
|
|
1381 TEST_IMPL(fs_async_sendfile_nodata) {
|
|
|
1382 return test_sendfile(NULL, sendfile_nodata_cb, 0);
|
|
|
1383 }
|
|
|
1384
|
|
|
1385
|
|
|
1386 TEST_IMPL(fs_mkdtemp) {
|
|
|
1387 int r;
|
|
|
1388 const char* path_template = "test_dir_XXXXXX";
|
|
|
1389
|
|
|
1390 loop = uv_default_loop();
|
|
|
1391
|
|
|
1392 r = uv_fs_mkdtemp(loop, &mkdtemp_req1, path_template, mkdtemp_cb);
|
|
|
1393 ASSERT_OK(r);
|
|
|
1394
|
|
|
1395 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1396 ASSERT_EQ(1, mkdtemp_cb_count);
|
|
|
1397
|
|
|
1398 /* sync mkdtemp */
|
|
|
1399 r = uv_fs_mkdtemp(NULL, &mkdtemp_req2, path_template, NULL);
|
|
|
1400 ASSERT_OK(r);
|
|
|
1401 check_mkdtemp_result(&mkdtemp_req2);
|
|
|
1402
|
|
|
1403 /* mkdtemp return different values on subsequent calls */
|
|
|
1404 ASSERT_NE(0, strcmp(mkdtemp_req1.path, mkdtemp_req2.path));
|
|
|
1405
|
|
|
1406 /* Cleanup */
|
|
|
1407 rmdir(mkdtemp_req1.path);
|
|
|
1408 rmdir(mkdtemp_req2.path);
|
|
|
1409 uv_fs_req_cleanup(&mkdtemp_req1);
|
|
|
1410 uv_fs_req_cleanup(&mkdtemp_req2);
|
|
|
1411
|
|
|
1412 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1413 return 0;
|
|
|
1414 }
|
|
|
1415
|
|
|
1416
|
|
|
1417 TEST_IMPL(fs_mkstemp) {
|
|
|
1418 int r;
|
|
|
1419 int fd;
|
|
|
1420 const char path_template[] = "test_file_XXXXXX";
|
|
|
1421 uv_fs_t req;
|
|
|
1422
|
|
|
1423 loop = uv_default_loop();
|
|
|
1424
|
|
|
1425 r = uv_fs_mkstemp(loop, &mkstemp_req1, path_template, mkstemp_cb);
|
|
|
1426 ASSERT_OK(r);
|
|
|
1427
|
|
|
1428 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1429 ASSERT_EQ(1, mkstemp_cb_count);
|
|
|
1430
|
|
|
1431 /* sync mkstemp */
|
|
|
1432 r = uv_fs_mkstemp(NULL, &mkstemp_req2, path_template, NULL);
|
|
|
1433 ASSERT_GE(r, 0);
|
|
|
1434 check_mkstemp_result(&mkstemp_req2);
|
|
|
1435
|
|
|
1436 /* mkstemp return different values on subsequent calls */
|
|
|
1437 ASSERT_NE(0, strcmp(mkstemp_req1.path, mkstemp_req2.path));
|
|
|
1438
|
|
|
1439 /* invalid template returns EINVAL */
|
|
|
1440 ASSERT_EQ(UV_EINVAL, uv_fs_mkstemp(NULL, &mkstemp_req3, "test_file", NULL));
|
|
|
1441
|
|
|
1442 /* Make sure that path is empty string */
|
|
|
1443 ASSERT_OK(strlen(mkstemp_req3.path));
|
|
|
1444
|
|
|
1445 uv_fs_req_cleanup(&mkstemp_req3);
|
|
|
1446
|
|
|
1447 /* We can write to the opened file */
|
|
|
1448 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
1449 r = uv_fs_write(NULL, &req, mkstemp_req1.result, &iov, 1, -1, NULL);
|
|
|
1450 ASSERT_EQ(r, sizeof(test_buf));
|
|
|
1451 ASSERT_EQ(req.result, sizeof(test_buf));
|
|
|
1452 uv_fs_req_cleanup(&req);
|
|
|
1453
|
|
|
1454 /* Cleanup */
|
|
|
1455 uv_fs_close(NULL, &req, mkstemp_req1.result, NULL);
|
|
|
1456 uv_fs_req_cleanup(&req);
|
|
|
1457 uv_fs_close(NULL, &req, mkstemp_req2.result, NULL);
|
|
|
1458 uv_fs_req_cleanup(&req);
|
|
|
1459
|
|
|
1460 fd = uv_fs_open(NULL, &req, mkstemp_req1.path, UV_FS_O_RDONLY, 0, NULL);
|
|
|
1461 ASSERT_GE(fd, 0);
|
|
|
1462 uv_fs_req_cleanup(&req);
|
|
|
1463
|
|
|
1464 memset(buf, 0, sizeof(buf));
|
|
|
1465 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
1466 r = uv_fs_read(NULL, &req, fd, &iov, 1, -1, NULL);
|
|
|
1467 ASSERT_GE(r, 0);
|
|
|
1468 ASSERT_GE(req.result, 0);
|
|
|
1469 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
1470 uv_fs_req_cleanup(&req);
|
|
|
1471
|
|
|
1472 uv_fs_close(NULL, &req, fd, NULL);
|
|
|
1473 uv_fs_req_cleanup(&req);
|
|
|
1474
|
|
|
1475 unlink(mkstemp_req1.path);
|
|
|
1476 unlink(mkstemp_req2.path);
|
|
|
1477 uv_fs_req_cleanup(&mkstemp_req1);
|
|
|
1478 uv_fs_req_cleanup(&mkstemp_req2);
|
|
|
1479
|
|
|
1480 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1481 return 0;
|
|
|
1482 }
|
|
|
1483
|
|
|
1484
|
|
|
1485 TEST_IMPL(fs_fstat) {
|
|
|
1486 int r;
|
|
|
1487 uv_fs_t req;
|
|
|
1488 uv_file file;
|
|
|
1489 uv_stat_t* s;
|
|
|
1490 #ifndef _WIN32
|
|
|
1491 struct stat t;
|
|
|
1492 #endif
|
|
|
1493
|
|
|
1494 #if defined(__s390__) && defined(__QEMU__)
|
|
|
1495 /* qemu-user-s390x has this weird bug where statx() reports nanoseconds
|
|
|
1496 * but plain fstat() does not.
|
|
|
1497 */
|
|
|
1498 RETURN_SKIP("Test does not currently work in QEMU");
|
|
|
1499 #endif
|
|
|
1500
|
|
|
1501 /* Setup. */
|
|
|
1502 unlink("test_file");
|
|
|
1503
|
|
|
1504 loop = uv_default_loop();
|
|
|
1505
|
|
|
1506 r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
1507 S_IWUSR | S_IRUSR, NULL);
|
|
|
1508 ASSERT_GE(r, 0);
|
|
|
1509 ASSERT_GE(req.result, 0);
|
|
|
1510 file = req.result;
|
|
|
1511 uv_fs_req_cleanup(&req);
|
|
|
1512
|
|
|
1513 #ifndef _WIN32
|
|
|
1514 memset(&t, 0, sizeof(t));
|
|
|
1515 ASSERT_OK(fstat(file, &t));
|
|
|
1516 ASSERT_OK(uv_fs_fstat(NULL, &req, file, NULL));
|
|
|
1517 ASSERT_OK(req.result);
|
|
|
1518 s = req.ptr;
|
|
|
1519 # if defined(__APPLE__)
|
|
|
1520 ASSERT_EQ(s->st_birthtim.tv_sec, t.st_birthtimespec.tv_sec);
|
|
|
1521 ASSERT_EQ(s->st_birthtim.tv_nsec, t.st_birthtimespec.tv_nsec);
|
|
|
1522 # elif defined(__linux__)
|
|
|
1523 /* If statx() is supported, the birth time should be equal to the change time
|
|
|
1524 * because we just created the file. On older kernels, it's set to zero.
|
|
|
1525 */
|
|
|
1526 ASSERT(s->st_birthtim.tv_sec == 0 ||
|
|
|
1527 s->st_birthtim.tv_sec == t.st_ctim.tv_sec);
|
|
|
1528 ASSERT(s->st_birthtim.tv_nsec == 0 ||
|
|
|
1529 s->st_birthtim.tv_nsec == t.st_ctim.tv_nsec);
|
|
|
1530 # endif
|
|
|
1531 #endif
|
|
|
1532
|
|
|
1533 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
1534 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
|
|
|
1535 ASSERT_EQ(r, sizeof(test_buf));
|
|
|
1536 ASSERT_EQ(req.result, sizeof(test_buf));
|
|
|
1537 uv_fs_req_cleanup(&req);
|
|
|
1538
|
|
|
1539 memset(&req.statbuf, 0xaa, sizeof(req.statbuf));
|
|
|
1540 r = uv_fs_fstat(NULL, &req, file, NULL);
|
|
|
1541 ASSERT_OK(r);
|
|
|
1542 ASSERT_OK(req.result);
|
|
|
1543 s = req.ptr;
|
|
|
1544 ASSERT_EQ(s->st_size, sizeof(test_buf));
|
|
|
1545
|
|
|
1546 #ifndef _WIN32
|
|
|
1547 r = fstat(file, &t);
|
|
|
1548 ASSERT_OK(r);
|
|
|
1549
|
|
|
1550 ASSERT_EQ(s->st_dev, (uint64_t) t.st_dev);
|
|
|
1551 ASSERT_EQ(s->st_mode, (uint64_t) t.st_mode);
|
|
|
1552 ASSERT_EQ(s->st_nlink, (uint64_t) t.st_nlink);
|
|
|
1553 ASSERT_EQ(s->st_uid, (uint64_t) t.st_uid);
|
|
|
1554 ASSERT_EQ(s->st_gid, (uint64_t) t.st_gid);
|
|
|
1555 ASSERT_EQ(s->st_rdev, (uint64_t) t.st_rdev);
|
|
|
1556 ASSERT_EQ(s->st_ino, (uint64_t) t.st_ino);
|
|
|
1557 ASSERT_EQ(s->st_size, (uint64_t) t.st_size);
|
|
|
1558 ASSERT_EQ(s->st_blksize, (uint64_t) t.st_blksize);
|
|
|
1559 ASSERT_EQ(s->st_blocks, (uint64_t) t.st_blocks);
|
|
|
1560 #if defined(__APPLE__)
|
|
|
1561 ASSERT_EQ(s->st_atim.tv_sec, t.st_atimespec.tv_sec);
|
|
|
1562 ASSERT_EQ(s->st_atim.tv_nsec, t.st_atimespec.tv_nsec);
|
|
|
1563 ASSERT_EQ(s->st_mtim.tv_sec, t.st_mtimespec.tv_sec);
|
|
|
1564 ASSERT_EQ(s->st_mtim.tv_nsec, t.st_mtimespec.tv_nsec);
|
|
|
1565 ASSERT_EQ(s->st_ctim.tv_sec, t.st_ctimespec.tv_sec);
|
|
|
1566 ASSERT_EQ(s->st_ctim.tv_nsec, t.st_ctimespec.tv_nsec);
|
|
|
1567 #elif defined(_AIX) || \
|
|
|
1568 defined(__MVS__)
|
|
|
1569 ASSERT_EQ(s->st_atim.tv_sec, t.st_atime);
|
|
|
1570 ASSERT_OK(s->st_atim.tv_nsec);
|
|
|
1571 ASSERT_EQ(s->st_mtim.tv_sec, t.st_mtime);
|
|
|
1572 ASSERT_OK(s->st_mtim.tv_nsec);
|
|
|
1573 ASSERT_EQ(s->st_ctim.tv_sec, t.st_ctime);
|
|
|
1574 ASSERT_OK(s->st_ctim.tv_nsec);
|
|
|
1575 #elif defined(__ANDROID__)
|
|
|
1576 ASSERT_EQ(s->st_atim.tv_sec, t.st_atime);
|
|
|
1577 ASSERT_EQ(s->st_atim.tv_nsec, t.st_atimensec);
|
|
|
1578 ASSERT_EQ(s->st_mtim.tv_sec, t.st_mtime);
|
|
|
1579 ASSERT_EQ(s->st_mtim.tv_nsec, t.st_mtimensec);
|
|
|
1580 ASSERT_EQ(s->st_ctim.tv_sec, t.st_ctime);
|
|
|
1581 ASSERT_EQ(s->st_ctim.tv_nsec, t.st_ctimensec);
|
|
|
1582 #elif defined(__sun) || \
|
|
|
1583 defined(__DragonFly__) || \
|
|
|
1584 defined(__FreeBSD__) || \
|
|
|
1585 defined(__OpenBSD__) || \
|
|
|
1586 defined(__NetBSD__) || \
|
|
|
1587 defined(_GNU_SOURCE) || \
|
|
|
1588 defined(_BSD_SOURCE) || \
|
|
|
1589 defined(_SVID_SOURCE) || \
|
|
|
1590 defined(_XOPEN_SOURCE) || \
|
|
|
1591 defined(_DEFAULT_SOURCE)
|
|
|
1592 ASSERT_EQ(s->st_atim.tv_sec, t.st_atim.tv_sec);
|
|
|
1593 ASSERT_EQ(s->st_atim.tv_nsec, t.st_atim.tv_nsec);
|
|
|
1594 ASSERT_EQ(s->st_mtim.tv_sec, t.st_mtim.tv_sec);
|
|
|
1595 ASSERT_EQ(s->st_mtim.tv_nsec, t.st_mtim.tv_nsec);
|
|
|
1596 ASSERT_EQ(s->st_ctim.tv_sec, t.st_ctim.tv_sec);
|
|
|
1597 ASSERT_EQ(s->st_ctim.tv_nsec, t.st_ctim.tv_nsec);
|
|
|
1598 # if defined(__FreeBSD__) || \
|
|
|
1599 defined(__NetBSD__)
|
|
|
1600 ASSERT_EQ(s->st_birthtim.tv_sec, t.st_birthtim.tv_sec);
|
|
|
1601 ASSERT_EQ(s->st_birthtim.tv_nsec, t.st_birthtim.tv_nsec);
|
|
|
1602 # endif
|
|
|
1603 #else
|
|
|
1604 ASSERT_EQ(s->st_atim.tv_sec, t.st_atime);
|
|
|
1605 ASSERT_OK(s->st_atim.tv_nsec);
|
|
|
1606 ASSERT_EQ(s->st_mtim.tv_sec, t.st_mtime);
|
|
|
1607 ASSERT_OK(s->st_mtim.tv_nsec);
|
|
|
1608 ASSERT_EQ(s->st_ctim.tv_sec, t.st_ctime);
|
|
|
1609 ASSERT_OK(s->st_ctim.tv_nsec);
|
|
|
1610 #endif
|
|
|
1611 #endif
|
|
|
1612
|
|
|
1613 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
|
|
|
1614 ASSERT_EQ(s->st_flags, t.st_flags);
|
|
|
1615 ASSERT_EQ(s->st_gen, t.st_gen);
|
|
|
1616 #else
|
|
|
1617 ASSERT_OK(s->st_flags);
|
|
|
1618 ASSERT_OK(s->st_gen);
|
|
|
1619 #endif
|
|
|
1620
|
|
|
1621 uv_fs_req_cleanup(&req);
|
|
|
1622
|
|
|
1623 /* Now do the uv_fs_fstat call asynchronously */
|
|
|
1624 r = uv_fs_fstat(loop, &req, file, fstat_cb);
|
|
|
1625 ASSERT_OK(r);
|
|
|
1626 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1627 ASSERT_EQ(1, fstat_cb_count);
|
|
|
1628
|
|
|
1629
|
|
|
1630 r = uv_fs_close(NULL, &req, file, NULL);
|
|
|
1631 ASSERT_OK(r);
|
|
|
1632 ASSERT_OK(req.result);
|
|
|
1633 uv_fs_req_cleanup(&req);
|
|
|
1634
|
|
|
1635 /*
|
|
|
1636 * Run the loop just to check we don't have make any extraneous uv_ref()
|
|
|
1637 * calls. This should drop out immediately.
|
|
|
1638 */
|
|
|
1639 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1640
|
|
|
1641 /* Cleanup. */
|
|
|
1642 unlink("test_file");
|
|
|
1643
|
|
|
1644 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1645 return 0;
|
|
|
1646 }
|
|
|
1647
|
|
|
1648
|
|
|
1649 TEST_IMPL(fs_fstat_st_dev) {
|
|
|
1650 uv_fs_t req;
|
|
|
1651 uv_fs_t req_link;
|
|
|
1652 uv_loop_t* loop = uv_default_loop();
|
|
|
1653 char* test_file = "tmp_st_dev";
|
|
|
1654 char* symlink_file = "tmp_st_dev_link";
|
|
|
1655
|
|
|
1656 unlink(test_file);
|
|
|
1657 unlink(symlink_file);
|
|
|
1658
|
|
|
1659 // Create file
|
|
|
1660 int r = uv_fs_open(NULL, &req, test_file, UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
1661 S_IWUSR | S_IRUSR, NULL);
|
|
|
1662 ASSERT_GE(r, 0);
|
|
|
1663 ASSERT_GE(req.result, 0);
|
|
|
1664 uv_fs_req_cleanup(&req);
|
|
|
1665
|
|
|
1666 // Create a symlink
|
|
|
1667 r = uv_fs_symlink(loop, &req, test_file, symlink_file, 0, NULL);
|
|
|
1668 ASSERT_EQ(r, 0);
|
|
|
1669 uv_fs_req_cleanup(&req);
|
|
|
1670
|
|
|
1671 // Call uv_fs_fstat for file
|
|
|
1672 r = uv_fs_stat(loop, &req, test_file, NULL);
|
|
|
1673 ASSERT_EQ(r, 0);
|
|
|
1674
|
|
|
1675 // Call uv_fs_fstat for symlink
|
|
|
1676 r = uv_fs_stat(loop, &req_link, symlink_file, NULL);
|
|
|
1677 ASSERT_EQ(r, 0);
|
|
|
1678
|
|
|
1679 // Compare st_dev
|
|
|
1680 ASSERT_EQ(((uv_stat_t*)req.ptr)->st_dev, ((uv_stat_t*)req_link.ptr)->st_dev);
|
|
|
1681
|
|
|
1682 // Cleanup
|
|
|
1683 uv_fs_req_cleanup(&req);
|
|
|
1684 uv_fs_req_cleanup(&req_link);
|
|
|
1685 unlink(test_file);
|
|
|
1686 unlink(symlink_file);
|
|
|
1687
|
|
|
1688 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1689 return 0;
|
|
|
1690 }
|
|
|
1691
|
|
|
1692
|
|
|
1693 TEST_IMPL(fs_fstat_stdio) {
|
|
|
1694 int fd;
|
|
|
1695 int res;
|
|
|
1696 uv_fs_t req;
|
|
|
1697 #ifdef _WIN32
|
|
|
1698 uv_stat_t* st;
|
|
|
1699 DWORD ft;
|
|
|
1700 #endif
|
|
|
1701
|
|
|
1702 for (fd = 0; fd <= 2; ++fd) {
|
|
|
1703 res = uv_fs_fstat(NULL, &req, fd, NULL);
|
|
|
1704 ASSERT_OK(res);
|
|
|
1705 ASSERT_OK(req.result);
|
|
|
1706
|
|
|
1707 #ifdef _WIN32
|
|
|
1708 st = req.ptr;
|
|
|
1709 ft = uv_guess_handle(fd);
|
|
|
1710 switch (ft) {
|
|
|
1711 case UV_TTY:
|
|
|
1712 case UV_NAMED_PIPE:
|
|
|
1713 ASSERT_EQ(st->st_mode, (ft == UV_TTY ? S_IFCHR : S_IFIFO));
|
|
|
1714 ASSERT_EQ(1, st->st_nlink);
|
|
|
1715 ASSERT_EQ(st->st_rdev,
|
|
|
1716 (ft == UV_TTY ? FILE_DEVICE_CONSOLE : FILE_DEVICE_NAMED_PIPE)
|
|
|
1717 << 16);
|
|
|
1718 break;
|
|
|
1719 default:
|
|
|
1720 break;
|
|
|
1721 }
|
|
|
1722 #endif
|
|
|
1723
|
|
|
1724 uv_fs_req_cleanup(&req);
|
|
|
1725 }
|
|
|
1726
|
|
|
1727 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
1728 return 0;
|
|
|
1729 }
|
|
|
1730
|
|
|
1731
|
|
|
1732 TEST_IMPL(fs_access) {
|
|
|
1733 int r;
|
|
|
1734 uv_fs_t req;
|
|
|
1735 uv_file file;
|
|
|
1736
|
|
|
1737 /* Setup. */
|
|
|
1738 unlink("test_file");
|
|
|
1739 rmdir("test_dir");
|
|
|
1740
|
|
|
1741 loop = uv_default_loop();
|
|
|
1742
|
|
|
1743 /* File should not exist */
|
|
|
1744 r = uv_fs_access(NULL, &req, "test_file", F_OK, NULL);
|
|
|
1745 ASSERT_LT(r, 0);
|
|
|
1746 ASSERT_LT(req.result, 0);
|
|
|
1747 uv_fs_req_cleanup(&req);
|
|
|
1748
|
|
|
1749 /* File should not exist */
|
|
|
1750 r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb);
|
|
|
1751 ASSERT_OK(r);
|
|
|
1752 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1753 ASSERT_EQ(1, access_cb_count);
|
|
|
1754 access_cb_count = 0; /* reset for the next test */
|
|
|
1755
|
|
|
1756 /* Create file */
|
|
|
1757 r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
1758 S_IWUSR | S_IRUSR, NULL);
|
|
|
1759 ASSERT_GE(r, 0);
|
|
|
1760 ASSERT_GE(req.result, 0);
|
|
|
1761 file = req.result;
|
|
|
1762 uv_fs_req_cleanup(&req);
|
|
|
1763
|
|
|
1764 /* File should exist */
|
|
|
1765 r = uv_fs_access(NULL, &req, "test_file", F_OK, NULL);
|
|
|
1766 ASSERT_OK(r);
|
|
|
1767 ASSERT_OK(req.result);
|
|
|
1768 uv_fs_req_cleanup(&req);
|
|
|
1769
|
|
|
1770 /* File should exist */
|
|
|
1771 r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb);
|
|
|
1772 ASSERT_OK(r);
|
|
|
1773 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1774 ASSERT_EQ(1, access_cb_count);
|
|
|
1775 access_cb_count = 0; /* reset for the next test */
|
|
|
1776
|
|
|
1777 /* Close file */
|
|
|
1778 r = uv_fs_close(NULL, &req, file, NULL);
|
|
|
1779 ASSERT_OK(r);
|
|
|
1780 ASSERT_OK(req.result);
|
|
|
1781 uv_fs_req_cleanup(&req);
|
|
|
1782
|
|
|
1783 /* Directory access */
|
|
|
1784 r = uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL);
|
|
|
1785 ASSERT_OK(r);
|
|
|
1786 uv_fs_req_cleanup(&req);
|
|
|
1787
|
|
|
1788 r = uv_fs_access(NULL, &req, "test_dir", W_OK, NULL);
|
|
|
1789 ASSERT_OK(r);
|
|
|
1790 ASSERT_OK(req.result);
|
|
|
1791 uv_fs_req_cleanup(&req);
|
|
|
1792
|
|
|
1793 /*
|
|
|
1794 * Run the loop just to check we don't have make any extraneous uv_ref()
|
|
|
1795 * calls. This should drop out immediately.
|
|
|
1796 */
|
|
|
1797 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1798
|
|
|
1799 /* Cleanup. */
|
|
|
1800 unlink("test_file");
|
|
|
1801 rmdir("test_dir");
|
|
|
1802
|
|
|
1803 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1804 return 0;
|
|
|
1805 }
|
|
|
1806
|
|
|
1807
|
|
|
1808 TEST_IMPL(fs_chmod) {
|
|
|
1809 int r;
|
|
|
1810 uv_fs_t req;
|
|
|
1811 uv_file file;
|
|
|
1812
|
|
|
1813 /* Setup. */
|
|
|
1814 unlink("test_file");
|
|
|
1815
|
|
|
1816 loop = uv_default_loop();
|
|
|
1817
|
|
|
1818 r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
1819 S_IWUSR | S_IRUSR, NULL);
|
|
|
1820 ASSERT_GE(r, 0);
|
|
|
1821 ASSERT_GE(req.result, 0);
|
|
|
1822 file = req.result;
|
|
|
1823 uv_fs_req_cleanup(&req);
|
|
|
1824
|
|
|
1825 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
1826 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
|
|
|
1827 ASSERT_EQ(r, sizeof(test_buf));
|
|
|
1828 ASSERT_EQ(req.result, sizeof(test_buf));
|
|
|
1829 uv_fs_req_cleanup(&req);
|
|
|
1830
|
|
|
1831 #ifndef _WIN32
|
|
|
1832 /* Make the file write-only */
|
|
|
1833 r = uv_fs_chmod(NULL, &req, "test_file", 0200, NULL);
|
|
|
1834 ASSERT_OK(r);
|
|
|
1835 ASSERT_OK(req.result);
|
|
|
1836 uv_fs_req_cleanup(&req);
|
|
|
1837
|
|
|
1838 check_permission("test_file", 0200);
|
|
|
1839 #endif
|
|
|
1840
|
|
|
1841 /* Make the file read-only */
|
|
|
1842 r = uv_fs_chmod(NULL, &req, "test_file", 0400, NULL);
|
|
|
1843 ASSERT_OK(r);
|
|
|
1844 ASSERT_OK(req.result);
|
|
|
1845 uv_fs_req_cleanup(&req);
|
|
|
1846
|
|
|
1847 check_permission("test_file", 0400);
|
|
|
1848
|
|
|
1849 /* Make the file read+write with sync uv_fs_fchmod */
|
|
|
1850 r = uv_fs_fchmod(NULL, &req, file, 0600, NULL);
|
|
|
1851 ASSERT_OK(r);
|
|
|
1852 ASSERT_OK(req.result);
|
|
|
1853 uv_fs_req_cleanup(&req);
|
|
|
1854
|
|
|
1855 check_permission("test_file", 0600);
|
|
|
1856
|
|
|
1857 #ifndef _WIN32
|
|
|
1858 /* async chmod */
|
|
|
1859 {
|
|
|
1860 static int mode = 0200;
|
|
|
1861 req.data = &mode;
|
|
|
1862 }
|
|
|
1863 r = uv_fs_chmod(loop, &req, "test_file", 0200, chmod_cb);
|
|
|
1864 ASSERT_OK(r);
|
|
|
1865 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1866 ASSERT_EQ(1, chmod_cb_count);
|
|
|
1867 chmod_cb_count = 0; /* reset for the next test */
|
|
|
1868 #endif
|
|
|
1869
|
|
|
1870 /* async chmod */
|
|
|
1871 {
|
|
|
1872 static int mode = 0400;
|
|
|
1873 req.data = &mode;
|
|
|
1874 }
|
|
|
1875 r = uv_fs_chmod(loop, &req, "test_file", 0400, chmod_cb);
|
|
|
1876 ASSERT_OK(r);
|
|
|
1877 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1878 ASSERT_EQ(1, chmod_cb_count);
|
|
|
1879
|
|
|
1880 /* async fchmod */
|
|
|
1881 {
|
|
|
1882 static int mode = 0600;
|
|
|
1883 req.data = &mode;
|
|
|
1884 }
|
|
|
1885 r = uv_fs_fchmod(loop, &req, file, 0600, fchmod_cb);
|
|
|
1886 ASSERT_OK(r);
|
|
|
1887 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1888 ASSERT_EQ(1, fchmod_cb_count);
|
|
|
1889
|
|
|
1890 uv_fs_close(loop, &req, file, NULL);
|
|
|
1891
|
|
|
1892 /*
|
|
|
1893 * Run the loop just to check we don't have make any extraneous uv_ref()
|
|
|
1894 * calls. This should drop out immediately.
|
|
|
1895 */
|
|
|
1896 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1897
|
|
|
1898 /* Cleanup. */
|
|
|
1899 unlink("test_file");
|
|
|
1900
|
|
|
1901 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1902 return 0;
|
|
|
1903 }
|
|
|
1904
|
|
|
1905
|
|
|
1906 TEST_IMPL(fs_unlink_readonly) {
|
|
|
1907 int r;
|
|
|
1908 uv_fs_t req;
|
|
|
1909 uv_file file;
|
|
|
1910
|
|
|
1911 /* Setup. */
|
|
|
1912 unlink("test_file");
|
|
|
1913
|
|
|
1914 loop = uv_default_loop();
|
|
|
1915
|
|
|
1916 r = uv_fs_open(NULL,
|
|
|
1917 &req, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
1918 S_IWUSR | S_IRUSR,
|
|
|
1919 NULL);
|
|
|
1920 ASSERT_GE(r, 0);
|
|
|
1921 ASSERT_GE(req.result, 0);
|
|
|
1922 file = req.result;
|
|
|
1923 uv_fs_req_cleanup(&req);
|
|
|
1924
|
|
|
1925 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
1926 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
|
|
|
1927 ASSERT_EQ(r, sizeof(test_buf));
|
|
|
1928 ASSERT_EQ(req.result, sizeof(test_buf));
|
|
|
1929 uv_fs_req_cleanup(&req);
|
|
|
1930
|
|
|
1931 uv_fs_close(loop, &req, file, NULL);
|
|
|
1932
|
|
|
1933 /* Make the file read-only */
|
|
|
1934 r = uv_fs_chmod(NULL, &req, "test_file", 0400, NULL);
|
|
|
1935 ASSERT_OK(r);
|
|
|
1936 ASSERT_OK(req.result);
|
|
|
1937 uv_fs_req_cleanup(&req);
|
|
|
1938
|
|
|
1939 check_permission("test_file", 0400);
|
|
|
1940
|
|
|
1941 /* Try to unlink the file */
|
|
|
1942 r = uv_fs_unlink(NULL, &req, "test_file", NULL);
|
|
|
1943 ASSERT_OK(r);
|
|
|
1944 ASSERT_OK(req.result);
|
|
|
1945 uv_fs_req_cleanup(&req);
|
|
|
1946
|
|
|
1947 /*
|
|
|
1948 * Run the loop just to check we don't have make any extraneous uv_ref()
|
|
|
1949 * calls. This should drop out immediately.
|
|
|
1950 */
|
|
|
1951 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
1952
|
|
|
1953 /* Cleanup. */
|
|
|
1954 uv_fs_chmod(NULL, &req, "test_file", 0600, NULL);
|
|
|
1955 uv_fs_req_cleanup(&req);
|
|
|
1956 unlink("test_file");
|
|
|
1957
|
|
|
1958 MAKE_VALGRIND_HAPPY(loop);
|
|
|
1959 return 0;
|
|
|
1960 }
|
|
|
1961
|
|
|
1962 #ifdef _WIN32
|
|
|
1963 TEST_IMPL(fs_unlink_archive_readonly) {
|
|
|
1964 int r;
|
|
|
1965 uv_fs_t req;
|
|
|
1966 uv_file file;
|
|
|
1967
|
|
|
1968 /* Setup. */
|
|
|
1969 unlink("test_file");
|
|
|
1970
|
|
|
1971 loop = uv_default_loop();
|
|
|
1972
|
|
|
1973 r = uv_fs_open(NULL,
|
|
|
1974 &req, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
1975 S_IWUSR | S_IRUSR,
|
|
|
1976 NULL);
|
|
|
1977 ASSERT_GE(r, 0);
|
|
|
1978 ASSERT_GE(req.result, 0);
|
|
|
1979 file = req.result;
|
|
|
1980 uv_fs_req_cleanup(&req);
|
|
|
1981
|
|
|
1982 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
1983 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
|
|
|
1984 ASSERT_EQ(r, sizeof(test_buf));
|
|
|
1985 ASSERT_EQ(req.result, sizeof(test_buf));
|
|
|
1986 uv_fs_req_cleanup(&req);
|
|
|
1987
|
|
|
1988 uv_fs_close(loop, &req, file, NULL);
|
|
|
1989
|
|
|
1990 /* Make the file read-only and clear archive flag */
|
|
|
1991 r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY);
|
|
|
1992 ASSERT(r);
|
|
|
1993 uv_fs_req_cleanup(&req);
|
|
|
1994
|
|
|
1995 check_permission("test_file", 0400);
|
|
|
1996
|
|
|
1997 /* Try to unlink the file */
|
|
|
1998 r = uv_fs_unlink(NULL, &req, "test_file", NULL);
|
|
|
1999 ASSERT_OK(r);
|
|
|
2000 ASSERT_OK(req.result);
|
|
|
2001 uv_fs_req_cleanup(&req);
|
|
|
2002
|
|
|
2003 /*
|
|
|
2004 * Run the loop just to check we don't have make any extraneous uv_ref()
|
|
|
2005 * calls. This should drop out immediately.
|
|
|
2006 */
|
|
|
2007 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2008
|
|
|
2009 /* Cleanup. */
|
|
|
2010 uv_fs_chmod(NULL, &req, "test_file", 0600, NULL);
|
|
|
2011 uv_fs_req_cleanup(&req);
|
|
|
2012 unlink("test_file");
|
|
|
2013
|
|
|
2014 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2015 return 0;
|
|
|
2016 }
|
|
|
2017 #endif
|
|
|
2018
|
|
|
2019 TEST_IMPL(fs_chown) {
|
|
|
2020 int r;
|
|
|
2021 uv_fs_t req;
|
|
|
2022 uv_file file;
|
|
|
2023
|
|
|
2024 /* Setup. */
|
|
|
2025 unlink("test_file");
|
|
|
2026 unlink("test_file_link");
|
|
|
2027
|
|
|
2028 loop = uv_default_loop();
|
|
|
2029
|
|
|
2030 r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
2031 S_IWUSR | S_IRUSR, NULL);
|
|
|
2032 ASSERT_GE(r, 0);
|
|
|
2033 ASSERT_GE(req.result, 0);
|
|
|
2034 file = req.result;
|
|
|
2035 uv_fs_req_cleanup(&req);
|
|
|
2036
|
|
|
2037 /* sync chown */
|
|
|
2038 r = uv_fs_chown(NULL, &req, "test_file", -1, -1, NULL);
|
|
|
2039 ASSERT_OK(r);
|
|
|
2040 ASSERT_OK(req.result);
|
|
|
2041 uv_fs_req_cleanup(&req);
|
|
|
2042
|
|
|
2043 /* sync fchown */
|
|
|
2044 r = uv_fs_fchown(NULL, &req, file, -1, -1, NULL);
|
|
|
2045 ASSERT_OK(r);
|
|
|
2046 ASSERT_OK(req.result);
|
|
|
2047 uv_fs_req_cleanup(&req);
|
|
|
2048
|
|
|
2049 /* async chown */
|
|
|
2050 r = uv_fs_chown(loop, &req, "test_file", -1, -1, chown_cb);
|
|
|
2051 ASSERT_OK(r);
|
|
|
2052 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2053 ASSERT_EQ(1, chown_cb_count);
|
|
|
2054
|
|
|
2055 #ifndef __MVS__
|
|
|
2056 /* chown to root (fail) */
|
|
|
2057 chown_cb_count = 0;
|
|
|
2058 r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb);
|
|
|
2059 ASSERT_OK(r);
|
|
|
2060 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2061 ASSERT_EQ(1, chown_cb_count);
|
|
|
2062 #endif
|
|
|
2063
|
|
|
2064 /* async fchown */
|
|
|
2065 r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb);
|
|
|
2066 ASSERT_OK(r);
|
|
|
2067 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2068 ASSERT_EQ(1, fchown_cb_count);
|
|
|
2069
|
|
|
2070 #ifndef __HAIKU__
|
|
|
2071 /* Haiku doesn't support hardlink */
|
|
|
2072 /* sync link */
|
|
|
2073 r = uv_fs_link(NULL, &req, "test_file", "test_file_link", NULL);
|
|
|
2074 ASSERT_OK(r);
|
|
|
2075 ASSERT_OK(req.result);
|
|
|
2076 uv_fs_req_cleanup(&req);
|
|
|
2077
|
|
|
2078 /* sync lchown */
|
|
|
2079 r = uv_fs_lchown(NULL, &req, "test_file_link", -1, -1, NULL);
|
|
|
2080 ASSERT_OK(r);
|
|
|
2081 ASSERT_OK(req.result);
|
|
|
2082 uv_fs_req_cleanup(&req);
|
|
|
2083
|
|
|
2084 /* async lchown */
|
|
|
2085 r = uv_fs_lchown(loop, &req, "test_file_link", -1, -1, lchown_cb);
|
|
|
2086 ASSERT_OK(r);
|
|
|
2087 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2088 ASSERT_EQ(1, lchown_cb_count);
|
|
|
2089 #endif
|
|
|
2090
|
|
|
2091 /* Close file */
|
|
|
2092 r = uv_fs_close(NULL, &req, file, NULL);
|
|
|
2093 ASSERT_OK(r);
|
|
|
2094 ASSERT_OK(req.result);
|
|
|
2095 uv_fs_req_cleanup(&req);
|
|
|
2096
|
|
|
2097 /*
|
|
|
2098 * Run the loop just to check we don't have make any extraneous uv_ref()
|
|
|
2099 * calls. This should drop out immediately.
|
|
|
2100 */
|
|
|
2101 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2102
|
|
|
2103 /* Cleanup. */
|
|
|
2104 unlink("test_file");
|
|
|
2105 unlink("test_file_link");
|
|
|
2106
|
|
|
2107 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2108 return 0;
|
|
|
2109 }
|
|
|
2110
|
|
|
2111
|
|
|
2112 TEST_IMPL(fs_link) {
|
|
|
2113 int r;
|
|
|
2114 uv_fs_t req;
|
|
|
2115 uv_file file;
|
|
|
2116 uv_file link;
|
|
|
2117
|
|
|
2118 /* Setup. */
|
|
|
2119 unlink("test_file");
|
|
|
2120 unlink("test_file_link");
|
|
|
2121 unlink("test_file_link2");
|
|
|
2122
|
|
|
2123 loop = uv_default_loop();
|
|
|
2124
|
|
|
2125 r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
2126 S_IWUSR | S_IRUSR, NULL);
|
|
|
2127 ASSERT_GE(r, 0);
|
|
|
2128 ASSERT_GE(req.result, 0);
|
|
|
2129 file = req.result;
|
|
|
2130 uv_fs_req_cleanup(&req);
|
|
|
2131
|
|
|
2132 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
2133 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
|
|
|
2134 ASSERT_EQ(r, sizeof(test_buf));
|
|
|
2135 ASSERT_EQ(req.result, sizeof(test_buf));
|
|
|
2136 uv_fs_req_cleanup(&req);
|
|
|
2137
|
|
|
2138 uv_fs_close(loop, &req, file, NULL);
|
|
|
2139
|
|
|
2140 /* sync link */
|
|
|
2141 r = uv_fs_link(NULL, &req, "test_file", "test_file_link", NULL);
|
|
|
2142 ASSERT_OK(r);
|
|
|
2143 ASSERT_OK(req.result);
|
|
|
2144 uv_fs_req_cleanup(&req);
|
|
|
2145
|
|
|
2146 r = uv_fs_open(NULL, &req, "test_file_link", UV_FS_O_RDWR, 0, NULL);
|
|
|
2147 ASSERT_GE(r, 0);
|
|
|
2148 ASSERT_GE(req.result, 0);
|
|
|
2149 link = req.result;
|
|
|
2150 uv_fs_req_cleanup(&req);
|
|
|
2151
|
|
|
2152 memset(buf, 0, sizeof(buf));
|
|
|
2153 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
2154 r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL);
|
|
|
2155 ASSERT_GE(r, 0);
|
|
|
2156 ASSERT_GE(req.result, 0);
|
|
|
2157 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
2158
|
|
|
2159 close(link);
|
|
|
2160
|
|
|
2161 /* async link */
|
|
|
2162 r = uv_fs_link(loop, &req, "test_file", "test_file_link2", link_cb);
|
|
|
2163 ASSERT_OK(r);
|
|
|
2164 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2165 ASSERT_EQ(1, link_cb_count);
|
|
|
2166
|
|
|
2167 r = uv_fs_open(NULL, &req, "test_file_link2", UV_FS_O_RDWR, 0, NULL);
|
|
|
2168 ASSERT_GE(r, 0);
|
|
|
2169 ASSERT_GE(req.result, 0);
|
|
|
2170 link = req.result;
|
|
|
2171 uv_fs_req_cleanup(&req);
|
|
|
2172
|
|
|
2173 memset(buf, 0, sizeof(buf));
|
|
|
2174 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
2175 r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL);
|
|
|
2176 ASSERT_GE(r, 0);
|
|
|
2177 ASSERT_GE(req.result, 0);
|
|
|
2178 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
2179
|
|
|
2180 uv_fs_close(loop, &req, link, NULL);
|
|
|
2181
|
|
|
2182 /*
|
|
|
2183 * Run the loop just to check we don't have make any extraneous uv_ref()
|
|
|
2184 * calls. This should drop out immediately.
|
|
|
2185 */
|
|
|
2186 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2187
|
|
|
2188 /* Cleanup. */
|
|
|
2189 unlink("test_file");
|
|
|
2190 unlink("test_file_link");
|
|
|
2191 unlink("test_file_link2");
|
|
|
2192
|
|
|
2193 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2194 return 0;
|
|
|
2195 }
|
|
|
2196
|
|
|
2197
|
|
|
2198 TEST_IMPL(fs_readlink) {
|
|
|
2199 /* Must return UV_ENOENT on an inexistent file */
|
|
|
2200 {
|
|
|
2201 uv_fs_t req;
|
|
|
2202
|
|
|
2203 loop = uv_default_loop();
|
|
|
2204 ASSERT_OK(uv_fs_readlink(loop, &req, "no_such_file", dummy_cb));
|
|
|
2205 ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT));
|
|
|
2206 ASSERT_EQ(1, dummy_cb_count);
|
|
|
2207 ASSERT_NULL(req.ptr);
|
|
|
2208 ASSERT_EQ(req.result, UV_ENOENT);
|
|
|
2209 uv_fs_req_cleanup(&req);
|
|
|
2210
|
|
|
2211 ASSERT_EQ(UV_ENOENT, uv_fs_readlink(NULL, &req, "no_such_file", NULL));
|
|
|
2212 ASSERT_NULL(req.ptr);
|
|
|
2213 ASSERT_EQ(req.result, UV_ENOENT);
|
|
|
2214 uv_fs_req_cleanup(&req);
|
|
|
2215 }
|
|
|
2216
|
|
|
2217 /* Must return UV_EINVAL on a non-symlink file */
|
|
|
2218 {
|
|
|
2219 int r;
|
|
|
2220 uv_fs_t req;
|
|
|
2221 uv_file file;
|
|
|
2222
|
|
|
2223 /* Setup */
|
|
|
2224
|
|
|
2225 /* Create a non-symlink file */
|
|
|
2226 r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
2227 S_IWUSR | S_IRUSR, NULL);
|
|
|
2228 ASSERT_GE(r, 0);
|
|
|
2229 ASSERT_GE(req.result, 0);
|
|
|
2230 file = req.result;
|
|
|
2231 uv_fs_req_cleanup(&req);
|
|
|
2232
|
|
|
2233 r = uv_fs_close(NULL, &req, file, NULL);
|
|
|
2234 ASSERT_OK(r);
|
|
|
2235 ASSERT_OK(req.result);
|
|
|
2236 uv_fs_req_cleanup(&req);
|
|
|
2237
|
|
|
2238 /* Test */
|
|
|
2239 r = uv_fs_readlink(NULL, &req, "test_file", NULL);
|
|
|
2240 ASSERT_EQ(r, UV_EINVAL);
|
|
|
2241 uv_fs_req_cleanup(&req);
|
|
|
2242
|
|
|
2243 /* Cleanup */
|
|
|
2244 unlink("test_file");
|
|
|
2245 }
|
|
|
2246
|
|
|
2247 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2248 return 0;
|
|
|
2249 }
|
|
|
2250
|
|
|
2251
|
|
|
2252 TEST_IMPL(fs_realpath) {
|
|
|
2253 uv_fs_t req;
|
|
|
2254
|
|
|
2255 loop = uv_default_loop();
|
|
|
2256 ASSERT_OK(uv_fs_realpath(loop, &req, "no_such_file", dummy_cb));
|
|
|
2257 ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT));
|
|
|
2258 ASSERT_EQ(1, dummy_cb_count);
|
|
|
2259 ASSERT_NULL(req.ptr);
|
|
|
2260 ASSERT_EQ(req.result, UV_ENOENT);
|
|
|
2261 uv_fs_req_cleanup(&req);
|
|
|
2262
|
|
|
2263 ASSERT_EQ(UV_ENOENT, uv_fs_realpath(NULL, &req, "no_such_file", NULL));
|
|
|
2264 ASSERT_NULL(req.ptr);
|
|
|
2265 ASSERT_EQ(req.result, UV_ENOENT);
|
|
|
2266 uv_fs_req_cleanup(&req);
|
|
|
2267
|
|
|
2268 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2269 return 0;
|
|
|
2270 }
|
|
|
2271
|
|
|
2272
|
|
|
2273 TEST_IMPL(fs_symlink) {
|
|
|
2274 int r;
|
|
|
2275 uv_fs_t req;
|
|
|
2276 uv_file file;
|
|
|
2277 uv_file link;
|
|
|
2278 char test_file_abs_buf[PATHMAX];
|
|
|
2279 size_t test_file_abs_size;
|
|
|
2280
|
|
|
2281 /* Setup. */
|
|
|
2282 unlink("test_file");
|
|
|
2283 unlink("test_file_symlink");
|
|
|
2284 unlink("test_file_symlink2");
|
|
|
2285 unlink("test_file_symlink_symlink");
|
|
|
2286 unlink("test_file_symlink2_symlink");
|
|
|
2287 test_file_abs_size = sizeof(test_file_abs_buf);
|
|
|
2288 #ifdef _WIN32
|
|
|
2289 uv_cwd(test_file_abs_buf, &test_file_abs_size);
|
|
|
2290 strcat(test_file_abs_buf, "\\test_file");
|
|
|
2291 #else
|
|
|
2292 uv_cwd(test_file_abs_buf, &test_file_abs_size);
|
|
|
2293 strcat(test_file_abs_buf, "/test_file");
|
|
|
2294 #endif
|
|
|
2295
|
|
|
2296 loop = uv_default_loop();
|
|
|
2297
|
|
|
2298 r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
2299 S_IWUSR | S_IRUSR, NULL);
|
|
|
2300 ASSERT_GE(r, 0);
|
|
|
2301 ASSERT_GE(req.result, 0);
|
|
|
2302 file = req.result;
|
|
|
2303 uv_fs_req_cleanup(&req);
|
|
|
2304
|
|
|
2305 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
2306 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
|
|
|
2307 ASSERT_EQ(r, sizeof(test_buf));
|
|
|
2308 ASSERT_EQ(req.result, sizeof(test_buf));
|
|
|
2309 uv_fs_req_cleanup(&req);
|
|
|
2310
|
|
|
2311 uv_fs_close(loop, &req, file, NULL);
|
|
|
2312
|
|
|
2313 /* sync symlink */
|
|
|
2314 r = uv_fs_symlink(NULL, &req, "test_file", "test_file_symlink", 0, NULL);
|
|
|
2315 #ifdef _WIN32
|
|
|
2316 if (r < 0) {
|
|
|
2317 if (r == UV_ENOTSUP) {
|
|
|
2318 /*
|
|
|
2319 * Windows doesn't support symlinks on older versions.
|
|
|
2320 * We just pass the test and bail out early if we get ENOTSUP.
|
|
|
2321 */
|
|
|
2322 return 0;
|
|
|
2323 } else if (r == UV_EPERM) {
|
|
|
2324 /*
|
|
|
2325 * Creating a symlink is only allowed when running elevated.
|
|
|
2326 * We pass the test and bail out early if we get UV_EPERM.
|
|
|
2327 */
|
|
|
2328 return 0;
|
|
|
2329 }
|
|
|
2330 }
|
|
|
2331 #endif
|
|
|
2332 ASSERT_OK(r);
|
|
|
2333 ASSERT_OK(req.result);
|
|
|
2334 uv_fs_req_cleanup(&req);
|
|
|
2335
|
|
|
2336 r = uv_fs_open(NULL, &req, "test_file_symlink", UV_FS_O_RDWR, 0, NULL);
|
|
|
2337 ASSERT_GE(r, 0);
|
|
|
2338 ASSERT_GE(req.result, 0);
|
|
|
2339 link = req.result;
|
|
|
2340 uv_fs_req_cleanup(&req);
|
|
|
2341
|
|
|
2342 memset(buf, 0, sizeof(buf));
|
|
|
2343 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
2344 r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL);
|
|
|
2345 ASSERT_GE(r, 0);
|
|
|
2346 ASSERT_GE(req.result, 0);
|
|
|
2347 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
2348
|
|
|
2349 uv_fs_close(loop, &req, link, NULL);
|
|
|
2350
|
|
|
2351 r = uv_fs_symlink(NULL,
|
|
|
2352 &req,
|
|
|
2353 "test_file_symlink",
|
|
|
2354 "test_file_symlink_symlink",
|
|
|
2355 0,
|
|
|
2356 NULL);
|
|
|
2357 ASSERT_OK(r);
|
|
|
2358 uv_fs_req_cleanup(&req);
|
|
|
2359
|
|
|
2360 #if defined(__MSYS__)
|
|
|
2361 RETURN_SKIP("symlink reading is not supported on MSYS2");
|
|
|
2362 #endif
|
|
|
2363
|
|
|
2364 r = uv_fs_readlink(NULL, &req, "test_file_symlink_symlink", NULL);
|
|
|
2365 ASSERT_OK(r);
|
|
|
2366 ASSERT_OK(strcmp(req.ptr, "test_file_symlink"));
|
|
|
2367 uv_fs_req_cleanup(&req);
|
|
|
2368
|
|
|
2369 r = uv_fs_realpath(NULL, &req, "test_file_symlink_symlink", NULL);
|
|
|
2370 ASSERT_OK(r);
|
|
|
2371 #ifdef _WIN32
|
|
|
2372 ASSERT_OK(_stricmp(req.ptr, test_file_abs_buf));
|
|
|
2373 #else
|
|
|
2374 ASSERT_OK(strcmp(req.ptr, test_file_abs_buf));
|
|
|
2375 #endif
|
|
|
2376 uv_fs_req_cleanup(&req);
|
|
|
2377
|
|
|
2378 /* async link */
|
|
|
2379 r = uv_fs_symlink(loop,
|
|
|
2380 &req,
|
|
|
2381 "test_file",
|
|
|
2382 "test_file_symlink2",
|
|
|
2383 0,
|
|
|
2384 symlink_cb);
|
|
|
2385 ASSERT_OK(r);
|
|
|
2386 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2387 ASSERT_EQ(1, symlink_cb_count);
|
|
|
2388
|
|
|
2389 r = uv_fs_open(NULL, &req, "test_file_symlink2", UV_FS_O_RDWR, 0, NULL);
|
|
|
2390 ASSERT_GE(r, 0);
|
|
|
2391 ASSERT_GE(req.result, 0);
|
|
|
2392 link = req.result;
|
|
|
2393 uv_fs_req_cleanup(&req);
|
|
|
2394
|
|
|
2395 memset(buf, 0, sizeof(buf));
|
|
|
2396 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
2397 r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL);
|
|
|
2398 ASSERT_GE(r, 0);
|
|
|
2399 ASSERT_GE(req.result, 0);
|
|
|
2400 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
2401
|
|
|
2402 uv_fs_close(loop, &req, link, NULL);
|
|
|
2403
|
|
|
2404 r = uv_fs_symlink(NULL,
|
|
|
2405 &req,
|
|
|
2406 "test_file_symlink2",
|
|
|
2407 "test_file_symlink2_symlink",
|
|
|
2408 0,
|
|
|
2409 NULL);
|
|
|
2410 ASSERT_OK(r);
|
|
|
2411 uv_fs_req_cleanup(&req);
|
|
|
2412
|
|
|
2413 r = uv_fs_readlink(loop, &req, "test_file_symlink2_symlink", readlink_cb);
|
|
|
2414 ASSERT_OK(r);
|
|
|
2415 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2416 ASSERT_EQ(1, readlink_cb_count);
|
|
|
2417
|
|
|
2418 r = uv_fs_realpath(loop, &req, "test_file", realpath_cb);
|
|
|
2419 ASSERT_OK(r);
|
|
|
2420 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2421 ASSERT_EQ(1, realpath_cb_count);
|
|
|
2422
|
|
|
2423 /*
|
|
|
2424 * Run the loop just to check we don't have make any extraneous uv_ref()
|
|
|
2425 * calls. This should drop out immediately.
|
|
|
2426 */
|
|
|
2427 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2428
|
|
|
2429 /* Cleanup. */
|
|
|
2430 unlink("test_file");
|
|
|
2431 unlink("test_file_symlink");
|
|
|
2432 unlink("test_file_symlink_symlink");
|
|
|
2433 unlink("test_file_symlink2");
|
|
|
2434 unlink("test_file_symlink2_symlink");
|
|
|
2435
|
|
|
2436 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2437 return 0;
|
|
|
2438 }
|
|
|
2439
|
|
|
2440
|
|
|
2441 int test_symlink_dir_impl(int type) {
|
|
|
2442 uv_fs_t req;
|
|
|
2443 int r;
|
|
|
2444 char* test_dir;
|
|
|
2445 uv_dirent_t dent;
|
|
|
2446 static char test_dir_abs_buf[PATHMAX];
|
|
|
2447 size_t test_dir_abs_size;
|
|
|
2448
|
|
|
2449 /* set-up */
|
|
|
2450 unlink("test_dir/file1");
|
|
|
2451 unlink("test_dir/file2");
|
|
|
2452 rmdir("test_dir");
|
|
|
2453 rmdir("test_dir_symlink");
|
|
|
2454 test_dir_abs_size = sizeof(test_dir_abs_buf);
|
|
|
2455
|
|
|
2456 loop = uv_default_loop();
|
|
|
2457
|
|
|
2458 uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL);
|
|
|
2459 uv_fs_req_cleanup(&req);
|
|
|
2460
|
|
|
2461 #ifdef _WIN32
|
|
|
2462 strcpy(test_dir_abs_buf, "\\\\?\\");
|
|
|
2463 uv_cwd(test_dir_abs_buf + 4, &test_dir_abs_size);
|
|
|
2464 test_dir_abs_size += 4;
|
|
|
2465 strcat(test_dir_abs_buf, "\\test_dir");
|
|
|
2466 test_dir_abs_size += strlen("\\test_dir");
|
|
|
2467 test_dir = test_dir_abs_buf;
|
|
|
2468 #else
|
|
|
2469 uv_cwd(test_dir_abs_buf, &test_dir_abs_size);
|
|
|
2470 strcat(test_dir_abs_buf, "/test_dir");
|
|
|
2471 test_dir_abs_size += strlen("/test_dir");
|
|
|
2472 test_dir = "test_dir";
|
|
|
2473 #endif
|
|
|
2474
|
|
|
2475 r = uv_fs_symlink(NULL, &req, test_dir, "test_dir_symlink", type, NULL);
|
|
|
2476 if (type == UV_FS_SYMLINK_DIR && (r == UV_ENOTSUP || r == UV_EPERM)) {
|
|
|
2477 uv_fs_req_cleanup(&req);
|
|
|
2478 RETURN_SKIP("this version of Windows doesn't support unprivileged "
|
|
|
2479 "creation of directory symlinks");
|
|
|
2480 }
|
|
|
2481 fprintf(stderr, "r == %i\n", r);
|
|
|
2482 ASSERT_OK(r);
|
|
|
2483 ASSERT_OK(req.result);
|
|
|
2484 uv_fs_req_cleanup(&req);
|
|
|
2485
|
|
|
2486 r = uv_fs_stat(NULL, &req, "test_dir_symlink", NULL);
|
|
|
2487 ASSERT_OK(r);
|
|
|
2488 ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFDIR);
|
|
|
2489 uv_fs_req_cleanup(&req);
|
|
|
2490
|
|
|
2491 r = uv_fs_lstat(NULL, &req, "test_dir_symlink", NULL);
|
|
|
2492 ASSERT_OK(r);
|
|
|
2493 #if defined(__MSYS__)
|
|
|
2494 RETURN_SKIP("symlink reading is not supported on MSYS2");
|
|
|
2495 #endif
|
|
|
2496 ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFLNK);
|
|
|
2497 #ifdef _WIN32
|
|
|
2498 ASSERT_EQ(((uv_stat_t*)req.ptr)->st_size, strlen(test_dir + 4));
|
|
|
2499 #else
|
|
|
2500 # ifdef __PASE__
|
|
|
2501 /* On IBMi PASE, st_size returns the length of the symlink itself. */
|
|
|
2502 ASSERT_EQ(((uv_stat_t*)req.ptr)->st_size, strlen("test_dir_symlink"));
|
|
|
2503 # else
|
|
|
2504 ASSERT_EQ(((uv_stat_t*)req.ptr)->st_size, strlen(test_dir));
|
|
|
2505 # endif
|
|
|
2506 #endif
|
|
|
2507 uv_fs_req_cleanup(&req);
|
|
|
2508
|
|
|
2509 r = uv_fs_readlink(NULL, &req, "test_dir_symlink", NULL);
|
|
|
2510 ASSERT_OK(r);
|
|
|
2511 #ifdef _WIN32
|
|
|
2512 ASSERT_OK(strcmp(req.ptr, test_dir + 4));
|
|
|
2513 #else
|
|
|
2514 ASSERT_OK(strcmp(req.ptr, test_dir));
|
|
|
2515 #endif
|
|
|
2516 uv_fs_req_cleanup(&req);
|
|
|
2517
|
|
|
2518 r = uv_fs_realpath(NULL, &req, "test_dir_symlink", NULL);
|
|
|
2519 ASSERT_OK(r);
|
|
|
2520 #ifdef _WIN32
|
|
|
2521 ASSERT_EQ(strlen(req.ptr), test_dir_abs_size - 4);
|
|
|
2522 ASSERT_OK(_strnicmp(req.ptr, test_dir + 4, test_dir_abs_size - 4));
|
|
|
2523 #else
|
|
|
2524 ASSERT_OK(strcmp(req.ptr, test_dir_abs_buf));
|
|
|
2525 #endif
|
|
|
2526 uv_fs_req_cleanup(&req);
|
|
|
2527
|
|
|
2528 r = uv_fs_open(NULL, &open_req1, "test_dir/file1",
|
|
|
2529 UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
|
|
2530 S_IWUSR | S_IRUSR, NULL);
|
|
|
2531 ASSERT_GE(r, 0);
|
|
|
2532 uv_fs_req_cleanup(&open_req1);
|
|
|
2533 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
2534 ASSERT_OK(r);
|
|
|
2535 uv_fs_req_cleanup(&close_req);
|
|
|
2536
|
|
|
2537 r = uv_fs_open(NULL, &open_req1, "test_dir/file2",
|
|
|
2538 UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
|
|
2539 S_IWUSR | S_IRUSR, NULL);
|
|
|
2540 ASSERT_GE(r, 0);
|
|
|
2541 uv_fs_req_cleanup(&open_req1);
|
|
|
2542 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
2543 ASSERT_OK(r);
|
|
|
2544 uv_fs_req_cleanup(&close_req);
|
|
|
2545
|
|
|
2546 r = uv_fs_scandir(NULL, &scandir_req, "test_dir_symlink", 0, NULL);
|
|
|
2547 ASSERT_EQ(2, r);
|
|
|
2548 ASSERT_EQ(2, scandir_req.result);
|
|
|
2549 ASSERT(scandir_req.ptr);
|
|
|
2550 while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
|
|
|
2551 ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
|
|
2552 assert_is_file_type(dent);
|
|
|
2553 }
|
|
|
2554 uv_fs_req_cleanup(&scandir_req);
|
|
|
2555 ASSERT(!scandir_req.ptr);
|
|
|
2556
|
|
|
2557 /* unlink will remove the directory symlink */
|
|
|
2558 r = uv_fs_unlink(NULL, &req, "test_dir_symlink", NULL);
|
|
|
2559 ASSERT_OK(r);
|
|
|
2560 uv_fs_req_cleanup(&req);
|
|
|
2561
|
|
|
2562 r = uv_fs_scandir(NULL, &scandir_req, "test_dir_symlink", 0, NULL);
|
|
|
2563 ASSERT_EQ(r, UV_ENOENT);
|
|
|
2564 uv_fs_req_cleanup(&scandir_req);
|
|
|
2565
|
|
|
2566 r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL);
|
|
|
2567 ASSERT_EQ(2, r);
|
|
|
2568 ASSERT_EQ(2, scandir_req.result);
|
|
|
2569 ASSERT(scandir_req.ptr);
|
|
|
2570 while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
|
|
|
2571 ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
|
|
2572 assert_is_file_type(dent);
|
|
|
2573 }
|
|
|
2574 uv_fs_req_cleanup(&scandir_req);
|
|
|
2575 ASSERT(!scandir_req.ptr);
|
|
|
2576
|
|
|
2577 /* clean-up */
|
|
|
2578 unlink("test_dir/file1");
|
|
|
2579 unlink("test_dir/file2");
|
|
|
2580 rmdir("test_dir");
|
|
|
2581 rmdir("test_dir_symlink");
|
|
|
2582
|
|
|
2583 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2584 return 0;
|
|
|
2585 }
|
|
|
2586
|
|
|
2587 TEST_IMPL(fs_symlink_dir) {
|
|
|
2588 return test_symlink_dir_impl(UV_FS_SYMLINK_DIR);
|
|
|
2589 }
|
|
|
2590
|
|
|
2591 TEST_IMPL(fs_symlink_junction) {
|
|
|
2592 return test_symlink_dir_impl(UV_FS_SYMLINK_JUNCTION);
|
|
|
2593 }
|
|
|
2594
|
|
|
2595 #ifdef _WIN32
|
|
|
2596 TEST_IMPL(fs_non_symlink_reparse_point) {
|
|
|
2597 uv_fs_t req;
|
|
|
2598 int r;
|
|
|
2599 HANDLE file_handle;
|
|
|
2600 REPARSE_GUID_DATA_BUFFER reparse_buffer;
|
|
|
2601 DWORD bytes_returned;
|
|
|
2602 uv_dirent_t dent;
|
|
|
2603
|
|
|
2604 /* set-up */
|
|
|
2605 unlink("test_dir/test_file");
|
|
|
2606 rmdir("test_dir");
|
|
|
2607
|
|
|
2608 loop = uv_default_loop();
|
|
|
2609
|
|
|
2610 uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL);
|
|
|
2611 uv_fs_req_cleanup(&req);
|
|
|
2612
|
|
|
2613 file_handle = CreateFile("test_dir/test_file",
|
|
|
2614 GENERIC_WRITE | FILE_WRITE_ATTRIBUTES,
|
|
|
2615 0,
|
|
|
2616 NULL,
|
|
|
2617 CREATE_ALWAYS,
|
|
|
2618 FILE_FLAG_OPEN_REPARSE_POINT |
|
|
|
2619 FILE_FLAG_BACKUP_SEMANTICS,
|
|
|
2620 NULL);
|
|
|
2621 ASSERT_PTR_NE(file_handle, INVALID_HANDLE_VALUE);
|
|
|
2622
|
|
|
2623 memset(&reparse_buffer, 0, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE);
|
|
|
2624 reparse_buffer.ReparseTag = REPARSE_TAG;
|
|
|
2625 reparse_buffer.ReparseDataLength = 0;
|
|
|
2626 reparse_buffer.ReparseGuid = REPARSE_GUID;
|
|
|
2627
|
|
|
2628 r = DeviceIoControl(file_handle,
|
|
|
2629 FSCTL_SET_REPARSE_POINT,
|
|
|
2630 &reparse_buffer,
|
|
|
2631 REPARSE_GUID_DATA_BUFFER_HEADER_SIZE,
|
|
|
2632 NULL,
|
|
|
2633 0,
|
|
|
2634 &bytes_returned,
|
|
|
2635 NULL);
|
|
|
2636 ASSERT(r);
|
|
|
2637
|
|
|
2638 CloseHandle(file_handle);
|
|
|
2639
|
|
|
2640 r = uv_fs_readlink(NULL, &req, "test_dir/test_file", NULL);
|
|
|
2641 ASSERT(r == UV_EINVAL && GetLastError() == ERROR_SYMLINK_NOT_SUPPORTED);
|
|
|
2642 uv_fs_req_cleanup(&req);
|
|
|
2643
|
|
|
2644 /*
|
|
|
2645 Placeholder tests for exercising the behavior fixed in issue #995.
|
|
|
2646 To run, update the path with the IP address of a Mac with the hard drive
|
|
|
2647 shared via SMB as "Macintosh HD".
|
|
|
2648
|
|
|
2649 r = uv_fs_stat(NULL, &req, "\\\\<mac_ip>\\Macintosh HD\\.DS_Store", NULL);
|
|
|
2650 ASSERT_OK(r);
|
|
|
2651 uv_fs_req_cleanup(&req);
|
|
|
2652
|
|
|
2653 r = uv_fs_lstat(NULL, &req, "\\\\<mac_ip>\\Macintosh HD\\.DS_Store", NULL);
|
|
|
2654 ASSERT_OK(r);
|
|
|
2655 uv_fs_req_cleanup(&req);
|
|
|
2656 */
|
|
|
2657
|
|
|
2658 /*
|
|
|
2659 uv_fs_stat and uv_fs_lstat can only work on non-symlink reparse
|
|
|
2660 points when a minifilter driver is registered which intercepts
|
|
|
2661 associated filesystem requests. Installing a driver is beyond
|
|
|
2662 the scope of this test.
|
|
|
2663
|
|
|
2664 r = uv_fs_stat(NULL, &req, "test_dir/test_file", NULL);
|
|
|
2665 ASSERT_OK(r);
|
|
|
2666 uv_fs_req_cleanup(&req);
|
|
|
2667
|
|
|
2668 r = uv_fs_lstat(NULL, &req, "test_dir/test_file", NULL);
|
|
|
2669 ASSERT_OK(r);
|
|
|
2670 uv_fs_req_cleanup(&req);
|
|
|
2671 */
|
|
|
2672
|
|
|
2673 r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL);
|
|
|
2674 ASSERT_EQ(1, r);
|
|
|
2675 ASSERT_EQ(1, scandir_req.result);
|
|
|
2676 ASSERT(scandir_req.ptr);
|
|
|
2677 while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
|
|
|
2678 ASSERT_OK(strcmp(dent.name, "test_file"));
|
|
|
2679 /* uv_fs_scandir incorrectly identifies non-symlink reparse points
|
|
|
2680 as links because it doesn't open the file and verify the reparse
|
|
|
2681 point tag. The PowerShell Get-ChildItem command shares this
|
|
|
2682 behavior, so it's reasonable to leave it as is. */
|
|
|
2683 ASSERT_EQ(dent.type, UV_DIRENT_LINK);
|
|
|
2684 }
|
|
|
2685 uv_fs_req_cleanup(&scandir_req);
|
|
|
2686 ASSERT(!scandir_req.ptr);
|
|
|
2687
|
|
|
2688 /* clean-up */
|
|
|
2689 unlink("test_dir/test_file");
|
|
|
2690 rmdir("test_dir");
|
|
|
2691
|
|
|
2692 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2693 return 0;
|
|
|
2694 }
|
|
|
2695
|
|
|
2696 TEST_IMPL(fs_lstat_windows_store_apps) {
|
|
|
2697 uv_loop_t* loop;
|
|
|
2698 char localappdata[MAX_PATH];
|
|
|
2699 char windowsapps_path[MAX_PATH];
|
|
|
2700 char file_path[MAX_PATH];
|
|
|
2701 size_t len;
|
|
|
2702 int r;
|
|
|
2703 uv_fs_t req;
|
|
|
2704 uv_fs_t stat_req;
|
|
|
2705 uv_dirent_t dirent;
|
|
|
2706
|
|
|
2707 loop = uv_default_loop();
|
|
|
2708 ASSERT_NOT_NULL(loop);
|
|
|
2709 len = sizeof(localappdata);
|
|
|
2710 r = uv_os_getenv("LOCALAPPDATA", localappdata, &len);
|
|
|
2711 if (r == UV_ENOENT) {
|
|
|
2712 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2713 return TEST_SKIP;
|
|
|
2714 }
|
|
|
2715 ASSERT_OK(r);
|
|
|
2716 r = snprintf(windowsapps_path,
|
|
|
2717 sizeof(localappdata),
|
|
|
2718 "%s\\Microsoft\\WindowsApps",
|
|
|
2719 localappdata);
|
|
|
2720 ASSERT_GT(r, 0);
|
|
|
2721 if (uv_fs_opendir(loop, &req, windowsapps_path, NULL) != 0) {
|
|
|
2722 /* If we cannot read the directory, skip the test. */
|
|
|
2723 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2724 return TEST_SKIP;
|
|
|
2725 }
|
|
|
2726 if (uv_fs_scandir(loop, &req, windowsapps_path, 0, NULL) <= 0) {
|
|
|
2727 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2728 return TEST_SKIP;
|
|
|
2729 }
|
|
|
2730 while (uv_fs_scandir_next(&req, &dirent) != UV_EOF) {
|
|
|
2731 if (dirent.type != UV_DIRENT_LINK) {
|
|
|
2732 continue;
|
|
|
2733 }
|
|
|
2734 if (snprintf(file_path,
|
|
|
2735 sizeof(file_path),
|
|
|
2736 "%s\\%s",
|
|
|
2737 windowsapps_path,
|
|
|
2738 dirent.name) < 0) {
|
|
|
2739 continue;
|
|
|
2740 }
|
|
|
2741 ASSERT_OK(uv_fs_lstat(loop, &stat_req, file_path, NULL));
|
|
|
2742 }
|
|
|
2743 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2744 return 0;
|
|
|
2745 }
|
|
|
2746 #endif
|
|
|
2747
|
|
|
2748
|
|
|
2749 TEST_IMPL(fs_utime) {
|
|
|
2750 utime_check_t checkme;
|
|
|
2751 const char* path = "test_file";
|
|
|
2752 double atime;
|
|
|
2753 double mtime;
|
|
|
2754 uv_fs_t req;
|
|
|
2755 int r;
|
|
|
2756
|
|
|
2757 /* Setup. */
|
|
|
2758 loop = uv_default_loop();
|
|
|
2759 unlink(path);
|
|
|
2760 r = uv_fs_open(NULL, &req, path, UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
2761 S_IWUSR | S_IRUSR,
|
|
|
2762 NULL);
|
|
|
2763 ASSERT_GE(r, 0);
|
|
|
2764 ASSERT_GE(req.result, 0);
|
|
|
2765 uv_fs_req_cleanup(&req);
|
|
|
2766 uv_fs_close(loop, &req, r, NULL);
|
|
|
2767
|
|
|
2768 atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */
|
|
|
2769
|
|
|
2770 ASSERT_OK(uv_fs_utime(NULL, &req, path, atime, mtime, NULL));
|
|
|
2771 ASSERT_OK(req.result);
|
|
|
2772 uv_fs_req_cleanup(&req);
|
|
|
2773 check_utime(path, atime, mtime, /* test_lutime */ 0);
|
|
|
2774
|
|
|
2775 ASSERT_OK(uv_fs_utime(NULL,
|
|
|
2776 &req,
|
|
|
2777 path,
|
|
|
2778 UV_FS_UTIME_OMIT,
|
|
|
2779 UV_FS_UTIME_OMIT,
|
|
|
2780 NULL));
|
|
|
2781 ASSERT_OK(req.result);
|
|
|
2782 uv_fs_req_cleanup(&req);
|
|
|
2783 check_utime(path, atime, mtime, /* test_lutime */ 0);
|
|
|
2784
|
|
|
2785 ASSERT_OK(uv_fs_utime(NULL,
|
|
|
2786 &req,
|
|
|
2787 path,
|
|
|
2788 UV_FS_UTIME_NOW,
|
|
|
2789 UV_FS_UTIME_OMIT,
|
|
|
2790 NULL));
|
|
|
2791 ASSERT_OK(req.result);
|
|
|
2792 uv_fs_req_cleanup(&req);
|
|
|
2793 check_utime(path, UV_FS_UTIME_NOW, mtime, /* test_lutime */ 0);
|
|
|
2794
|
|
|
2795 ASSERT_OK(uv_fs_utime(NULL, &req, path, atime, mtime, NULL));
|
|
|
2796 ASSERT_OK(req.result);
|
|
|
2797 uv_fs_req_cleanup(&req);
|
|
|
2798 check_utime(path, atime, mtime, /* test_lutime */ 0);
|
|
|
2799
|
|
|
2800 ASSERT_OK(uv_fs_utime(NULL,
|
|
|
2801 &req,
|
|
|
2802 path,
|
|
|
2803 UV_FS_UTIME_OMIT,
|
|
|
2804 UV_FS_UTIME_NOW,
|
|
|
2805 NULL));
|
|
|
2806 ASSERT_OK(req.result);
|
|
|
2807 uv_fs_req_cleanup(&req);
|
|
|
2808 check_utime(path, atime, UV_FS_UTIME_NOW, /* test_lutime */ 0);
|
|
|
2809
|
|
|
2810 atime = mtime = 1291404900.25; /* 2010-12-03 20:35:00.25 - mees <3 */
|
|
|
2811 checkme.path = path;
|
|
|
2812 checkme.atime = atime;
|
|
|
2813 checkme.mtime = mtime;
|
|
|
2814
|
|
|
2815 /* async utime */
|
|
|
2816 utime_req.data = &checkme;
|
|
|
2817 r = uv_fs_utime(loop, &utime_req, path, atime, mtime, utime_cb);
|
|
|
2818 ASSERT_OK(r);
|
|
|
2819 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2820 ASSERT_EQ(1, utime_cb_count);
|
|
|
2821
|
|
|
2822 /* Cleanup. */
|
|
|
2823 unlink(path);
|
|
|
2824
|
|
|
2825 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2826 return 0;
|
|
|
2827 }
|
|
|
2828
|
|
|
2829
|
|
|
2830 TEST_IMPL(fs_utime_round) {
|
|
|
2831 const char path[] = "test_file";
|
|
|
2832 double atime;
|
|
|
2833 double mtime;
|
|
|
2834 uv_fs_t req;
|
|
|
2835 int r;
|
|
|
2836
|
|
|
2837 loop = uv_default_loop();
|
|
|
2838 unlink(path);
|
|
|
2839 r = uv_fs_open(NULL, &req, path, UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
2840 S_IWUSR | S_IRUSR,
|
|
|
2841 NULL);
|
|
|
2842 ASSERT_GE(r, 0);
|
|
|
2843 ASSERT_GE(req.result, 0);
|
|
|
2844 uv_fs_req_cleanup(&req);
|
|
|
2845 ASSERT_OK(uv_fs_close(loop, &req, r, NULL));
|
|
|
2846
|
|
|
2847 atime = mtime = -14245440.25; /* 1969-07-20T02:56:00.25Z */
|
|
|
2848
|
|
|
2849 r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL);
|
|
|
2850 #if !defined(__linux__) && \
|
|
|
2851 !defined(_WIN32) && \
|
|
|
2852 !defined(__APPLE__) && \
|
|
|
2853 !defined(__FreeBSD__) && \
|
|
|
2854 !defined(__sun)
|
|
|
2855 if (r != 0) {
|
|
|
2856 ASSERT_EQ(r, UV_EINVAL);
|
|
|
2857 RETURN_SKIP("utime on some OS (z/OS, IBM i PASE, AIX) or filesystems may reject pre-epoch timestamps");
|
|
|
2858 }
|
|
|
2859 #endif
|
|
|
2860 ASSERT_OK(r);
|
|
|
2861 ASSERT_OK(req.result);
|
|
|
2862 uv_fs_req_cleanup(&req);
|
|
|
2863 check_utime(path, atime, mtime, /* test_lutime */ 0);
|
|
|
2864 unlink(path);
|
|
|
2865
|
|
|
2866 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2867 return 0;
|
|
|
2868 }
|
|
|
2869
|
|
|
2870
|
|
|
2871 #ifdef _WIN32
|
|
|
2872 TEST_IMPL(fs_stat_root) {
|
|
|
2873 int r;
|
|
|
2874
|
|
|
2875 r = uv_fs_stat(NULL, &stat_req, "\\", NULL);
|
|
|
2876 ASSERT_OK(r);
|
|
|
2877
|
|
|
2878 r = uv_fs_stat(NULL, &stat_req, "..\\..\\..\\..\\..\\..\\..", NULL);
|
|
|
2879 ASSERT_OK(r);
|
|
|
2880
|
|
|
2881 r = uv_fs_stat(NULL, &stat_req, "..", NULL);
|
|
|
2882 ASSERT_OK(r);
|
|
|
2883
|
|
|
2884 r = uv_fs_stat(NULL, &stat_req, "..\\", NULL);
|
|
|
2885 ASSERT_OK(r);
|
|
|
2886
|
|
|
2887 /* stats the current directory on c: */
|
|
|
2888 r = uv_fs_stat(NULL, &stat_req, "c:", NULL);
|
|
|
2889 ASSERT_OK(r);
|
|
|
2890
|
|
|
2891 r = uv_fs_stat(NULL, &stat_req, "c:\\", NULL);
|
|
|
2892 ASSERT_OK(r);
|
|
|
2893
|
|
|
2894 r = uv_fs_stat(NULL, &stat_req, "\\\\?\\C:\\", NULL);
|
|
|
2895 ASSERT_OK(r);
|
|
|
2896
|
|
|
2897 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
2898 return 0;
|
|
|
2899 }
|
|
|
2900 #endif
|
|
|
2901
|
|
|
2902
|
|
|
2903 TEST_IMPL(fs_futime) {
|
|
|
2904 utime_check_t checkme;
|
|
|
2905 const char* path = "test_file";
|
|
|
2906 double atime;
|
|
|
2907 double mtime;
|
|
|
2908 uv_file file;
|
|
|
2909 uv_fs_t req;
|
|
|
2910 int r;
|
|
|
2911 #if defined(_AIX) && !defined(_AIX71)
|
|
|
2912 RETURN_SKIP("futime is not implemented for AIX versions below 7.1");
|
|
|
2913 #endif
|
|
|
2914
|
|
|
2915 /* Setup. */
|
|
|
2916 loop = uv_default_loop();
|
|
|
2917 unlink(path);
|
|
|
2918 r = uv_fs_open(NULL, &req, path, UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
2919 S_IWUSR | S_IRUSR,
|
|
|
2920 NULL);
|
|
|
2921 ASSERT_GE(r, 0);
|
|
|
2922 ASSERT_GE(req.result, 0);
|
|
|
2923 uv_fs_req_cleanup(&req);
|
|
|
2924 uv_fs_close(loop, &req, r, NULL);
|
|
|
2925
|
|
|
2926 atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */
|
|
|
2927
|
|
|
2928 r = uv_fs_open(NULL, &req, path, UV_FS_O_RDWR, 0, NULL);
|
|
|
2929 ASSERT_GE(r, 0);
|
|
|
2930 ASSERT_GE(req.result, 0);
|
|
|
2931 file = req.result; /* FIXME probably not how it's supposed to be used */
|
|
|
2932 uv_fs_req_cleanup(&req);
|
|
|
2933
|
|
|
2934 r = uv_fs_futime(NULL, &req, file, atime, mtime, NULL);
|
|
|
2935 #if defined(__CYGWIN__) || defined(__MSYS__)
|
|
|
2936 ASSERT_EQ(r, UV_ENOSYS);
|
|
|
2937 RETURN_SKIP("futime not supported on Cygwin");
|
|
|
2938 #else
|
|
|
2939 ASSERT_OK(r);
|
|
|
2940 ASSERT_OK(req.result);
|
|
|
2941 #endif
|
|
|
2942 uv_fs_req_cleanup(&req);
|
|
|
2943 check_utime(path, atime, mtime, /* test_lutime */ 0);
|
|
|
2944
|
|
|
2945 ASSERT_OK(uv_fs_futime(NULL,
|
|
|
2946 &req,
|
|
|
2947 file,
|
|
|
2948 UV_FS_UTIME_OMIT,
|
|
|
2949 UV_FS_UTIME_OMIT,
|
|
|
2950 NULL));
|
|
|
2951 ASSERT_OK(req.result);
|
|
|
2952 uv_fs_req_cleanup(&req);
|
|
|
2953 check_utime(path, atime, mtime, /* test_lutime */ 0);
|
|
|
2954
|
|
|
2955 ASSERT_OK(uv_fs_futime(NULL,
|
|
|
2956 &req,
|
|
|
2957 file,
|
|
|
2958 UV_FS_UTIME_NOW,
|
|
|
2959 UV_FS_UTIME_OMIT,
|
|
|
2960 NULL));
|
|
|
2961 ASSERT_OK(req.result);
|
|
|
2962 uv_fs_req_cleanup(&req);
|
|
|
2963 check_utime(path, UV_FS_UTIME_NOW, mtime, /* test_lutime */ 0);
|
|
|
2964
|
|
|
2965 ASSERT_OK(uv_fs_futime(NULL, &req, file, atime, mtime, NULL));
|
|
|
2966 ASSERT_OK(req.result);
|
|
|
2967 uv_fs_req_cleanup(&req);
|
|
|
2968 check_utime(path, atime, mtime, /* test_lutime */ 0);
|
|
|
2969
|
|
|
2970 ASSERT_OK(uv_fs_futime(NULL,
|
|
|
2971 &req,
|
|
|
2972 file,
|
|
|
2973 UV_FS_UTIME_OMIT,
|
|
|
2974 UV_FS_UTIME_NOW,
|
|
|
2975 NULL));
|
|
|
2976 ASSERT_OK(req.result);
|
|
|
2977 uv_fs_req_cleanup(&req);
|
|
|
2978 check_utime(path, atime, UV_FS_UTIME_NOW, /* test_lutime */ 0);
|
|
|
2979
|
|
|
2980 atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
|
|
|
2981
|
|
|
2982 checkme.atime = atime;
|
|
|
2983 checkme.mtime = mtime;
|
|
|
2984 checkme.path = path;
|
|
|
2985
|
|
|
2986 /* async futime */
|
|
|
2987 futime_req.data = &checkme;
|
|
|
2988 r = uv_fs_futime(loop, &futime_req, file, atime, mtime, futime_cb);
|
|
|
2989 ASSERT_OK(r);
|
|
|
2990 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
2991 ASSERT_EQ(1, futime_cb_count);
|
|
|
2992
|
|
|
2993 /* Cleanup. */
|
|
|
2994 unlink(path);
|
|
|
2995
|
|
|
2996 MAKE_VALGRIND_HAPPY(loop);
|
|
|
2997 return 0;
|
|
|
2998 }
|
|
|
2999
|
|
|
3000
|
|
|
3001 TEST_IMPL(fs_lutime) {
|
|
|
3002 utime_check_t checkme;
|
|
|
3003 const char* path = "test_file";
|
|
|
3004 const char* symlink_path = "test_file_symlink";
|
|
|
3005 double atime;
|
|
|
3006 double mtime;
|
|
|
3007 uv_fs_t req;
|
|
|
3008 int r, s;
|
|
|
3009
|
|
|
3010
|
|
|
3011 /* Setup */
|
|
|
3012 loop = uv_default_loop();
|
|
|
3013 unlink(path);
|
|
|
3014 r = uv_fs_open(NULL, &req, path, UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
3015 S_IWUSR | S_IRUSR,
|
|
|
3016 NULL);
|
|
|
3017 ASSERT_GE(r, 0);
|
|
|
3018 ASSERT_GE(req.result, 0);
|
|
|
3019 uv_fs_req_cleanup(&req);
|
|
|
3020 uv_fs_close(loop, &req, r, NULL);
|
|
|
3021
|
|
|
3022 unlink(symlink_path);
|
|
|
3023 s = uv_fs_symlink(NULL, &req, path, symlink_path, 0, NULL);
|
|
|
3024 #ifdef _WIN32
|
|
|
3025 if (s == UV_EPERM) {
|
|
|
3026 /*
|
|
|
3027 * Creating a symlink before Windows 10 Creators Update was only allowed
|
|
|
3028 * when running elevated console (with admin rights)
|
|
|
3029 */
|
|
|
3030 RETURN_SKIP(
|
|
|
3031 "Symlink creation requires elevated console (with admin rights)");
|
|
|
3032 }
|
|
|
3033 #endif
|
|
|
3034 ASSERT_OK(s);
|
|
|
3035 ASSERT_OK(req.result);
|
|
|
3036 uv_fs_req_cleanup(&req);
|
|
|
3037
|
|
|
3038 /* Test the synchronous version. */
|
|
|
3039 atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */
|
|
|
3040
|
|
|
3041 r = uv_fs_lutime(NULL, &req, symlink_path, atime, mtime, NULL);
|
|
|
3042 #if (defined(_AIX) && !defined(_AIX71)) || defined(__MVS__)
|
|
|
3043 ASSERT_EQ(r, UV_ENOSYS);
|
|
|
3044 RETURN_SKIP("lutime is not implemented for z/OS and AIX versions below 7.1");
|
|
|
3045 #endif
|
|
|
3046 ASSERT_OK(r);
|
|
|
3047 ASSERT_OK(req.result);
|
|
|
3048 uv_fs_req_cleanup(&req);
|
|
|
3049 check_utime(symlink_path, atime, mtime, /* test_lutime */ 1);
|
|
|
3050
|
|
|
3051 ASSERT_OK(uv_fs_lutime(NULL,
|
|
|
3052 &req,
|
|
|
3053 symlink_path,
|
|
|
3054 UV_FS_UTIME_OMIT,
|
|
|
3055 UV_FS_UTIME_OMIT,
|
|
|
3056 NULL));
|
|
|
3057 ASSERT_OK(req.result);
|
|
|
3058 uv_fs_req_cleanup(&req);
|
|
|
3059 check_utime(symlink_path, atime, mtime, /* test_lutime */ 1);
|
|
|
3060
|
|
|
3061 ASSERT_OK(uv_fs_lutime(NULL,
|
|
|
3062 &req,
|
|
|
3063 symlink_path,
|
|
|
3064 UV_FS_UTIME_NOW,
|
|
|
3065 UV_FS_UTIME_OMIT,
|
|
|
3066 NULL));
|
|
|
3067 ASSERT_OK(req.result);
|
|
|
3068 uv_fs_req_cleanup(&req);
|
|
|
3069 check_utime(symlink_path, UV_FS_UTIME_NOW, mtime, /* test_lutime */ 1);
|
|
|
3070
|
|
|
3071 ASSERT_OK(uv_fs_lutime(NULL, &req, symlink_path, atime, mtime, NULL));
|
|
|
3072 ASSERT_OK(req.result);
|
|
|
3073 uv_fs_req_cleanup(&req);
|
|
|
3074 check_utime(symlink_path, atime, mtime, /* test_lutime */ 1);
|
|
|
3075
|
|
|
3076 ASSERT_OK(uv_fs_lutime(NULL,
|
|
|
3077 &req,
|
|
|
3078 symlink_path,
|
|
|
3079 UV_FS_UTIME_OMIT,
|
|
|
3080 UV_FS_UTIME_NOW,
|
|
|
3081 NULL));
|
|
|
3082 ASSERT_OK(req.result);
|
|
|
3083 uv_fs_req_cleanup(&req);
|
|
|
3084 check_utime(symlink_path, atime, UV_FS_UTIME_NOW, /* test_lutime */ 1);
|
|
|
3085
|
|
|
3086 /* Test the asynchronous version. */
|
|
|
3087 atime = mtime = 1291404900; /* 2010-12-03 20:35:00 */
|
|
|
3088
|
|
|
3089 checkme.atime = atime;
|
|
|
3090 checkme.mtime = mtime;
|
|
|
3091 checkme.path = symlink_path;
|
|
|
3092 req.data = &checkme;
|
|
|
3093
|
|
|
3094 r = uv_fs_lutime(loop, &req, symlink_path, atime, mtime, lutime_cb);
|
|
|
3095 ASSERT_OK(r);
|
|
|
3096 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
3097 ASSERT_EQ(1, lutime_cb_count);
|
|
|
3098
|
|
|
3099 /* Cleanup. */
|
|
|
3100 unlink(path);
|
|
|
3101 unlink(symlink_path);
|
|
|
3102
|
|
|
3103 MAKE_VALGRIND_HAPPY(loop);
|
|
|
3104 return 0;
|
|
|
3105 }
|
|
|
3106
|
|
|
3107
|
|
|
3108 TEST_IMPL(fs_stat_missing_path) {
|
|
|
3109 uv_fs_t req;
|
|
|
3110 int r;
|
|
|
3111
|
|
|
3112 loop = uv_default_loop();
|
|
|
3113
|
|
|
3114 r = uv_fs_stat(NULL, &req, "non_existent_file", NULL);
|
|
|
3115 ASSERT_EQ(r, UV_ENOENT);
|
|
|
3116 ASSERT_EQ(req.result, UV_ENOENT);
|
|
|
3117 uv_fs_req_cleanup(&req);
|
|
|
3118
|
|
|
3119 MAKE_VALGRIND_HAPPY(loop);
|
|
|
3120 return 0;
|
|
|
3121 }
|
|
|
3122
|
|
|
3123
|
|
|
3124 TEST_IMPL(fs_scandir_empty_dir) {
|
|
|
3125 const char* path;
|
|
|
3126 uv_fs_t req;
|
|
|
3127 uv_dirent_t dent;
|
|
|
3128 int r;
|
|
|
3129
|
|
|
3130 path = "./empty_dir/";
|
|
|
3131 loop = uv_default_loop();
|
|
|
3132
|
|
|
3133 uv_fs_mkdir(NULL, &req, path, 0777, NULL);
|
|
|
3134 uv_fs_req_cleanup(&req);
|
|
|
3135
|
|
|
3136 /* Fill the req to ensure that required fields are cleaned up */
|
|
|
3137 memset(&req, 0xdb, sizeof(req));
|
|
|
3138
|
|
|
3139 r = uv_fs_scandir(NULL, &req, path, 0, NULL);
|
|
|
3140 ASSERT_OK(r);
|
|
|
3141 ASSERT_OK(req.result);
|
|
|
3142 ASSERT_NULL(req.ptr);
|
|
|
3143 ASSERT_EQ(UV_EOF, uv_fs_scandir_next(&req, &dent));
|
|
|
3144 uv_fs_req_cleanup(&req);
|
|
|
3145
|
|
|
3146 r = uv_fs_scandir(loop, &scandir_req, path, 0, empty_scandir_cb);
|
|
|
3147 ASSERT_OK(r);
|
|
|
3148
|
|
|
3149 ASSERT_OK(scandir_cb_count);
|
|
|
3150 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
3151 ASSERT_EQ(1, scandir_cb_count);
|
|
|
3152
|
|
|
3153 uv_fs_rmdir(NULL, &req, path, NULL);
|
|
|
3154 uv_fs_req_cleanup(&req);
|
|
|
3155
|
|
|
3156 MAKE_VALGRIND_HAPPY(loop);
|
|
|
3157 return 0;
|
|
|
3158 }
|
|
|
3159
|
|
|
3160
|
|
|
3161 TEST_IMPL(fs_scandir_non_existent_dir) {
|
|
|
3162 const char* path;
|
|
|
3163 uv_fs_t req;
|
|
|
3164 uv_dirent_t dent;
|
|
|
3165 int r;
|
|
|
3166
|
|
|
3167 path = "./non_existent_dir/";
|
|
|
3168 loop = uv_default_loop();
|
|
|
3169
|
|
|
3170 uv_fs_rmdir(NULL, &req, path, NULL);
|
|
|
3171 uv_fs_req_cleanup(&req);
|
|
|
3172
|
|
|
3173 /* Fill the req to ensure that required fields are cleaned up */
|
|
|
3174 memset(&req, 0xdb, sizeof(req));
|
|
|
3175
|
|
|
3176 r = uv_fs_scandir(NULL, &req, path, 0, NULL);
|
|
|
3177 ASSERT_EQ(r, UV_ENOENT);
|
|
|
3178 ASSERT_EQ(req.result, UV_ENOENT);
|
|
|
3179 ASSERT_NULL(req.ptr);
|
|
|
3180 ASSERT_EQ(UV_ENOENT, uv_fs_scandir_next(&req, &dent));
|
|
|
3181 uv_fs_req_cleanup(&req);
|
|
|
3182
|
|
|
3183 r = uv_fs_scandir(loop, &scandir_req, path, 0, non_existent_scandir_cb);
|
|
|
3184 ASSERT_OK(r);
|
|
|
3185
|
|
|
3186 ASSERT_OK(scandir_cb_count);
|
|
|
3187 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
3188 ASSERT_EQ(1, scandir_cb_count);
|
|
|
3189
|
|
|
3190 MAKE_VALGRIND_HAPPY(loop);
|
|
|
3191 return 0;
|
|
|
3192 }
|
|
|
3193
|
|
|
3194 TEST_IMPL(fs_scandir_file) {
|
|
|
3195 const char* path;
|
|
|
3196 int r;
|
|
|
3197
|
|
|
3198 path = "test/fixtures/empty_file";
|
|
|
3199 loop = uv_default_loop();
|
|
|
3200
|
|
|
3201 r = uv_fs_scandir(NULL, &scandir_req, path, 0, NULL);
|
|
|
3202 ASSERT_EQ(r, UV_ENOTDIR);
|
|
|
3203 uv_fs_req_cleanup(&scandir_req);
|
|
|
3204
|
|
|
3205 r = uv_fs_scandir(loop, &scandir_req, path, 0, file_scandir_cb);
|
|
|
3206 ASSERT_OK(r);
|
|
|
3207
|
|
|
3208 ASSERT_OK(scandir_cb_count);
|
|
|
3209 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
3210 ASSERT_EQ(1, scandir_cb_count);
|
|
|
3211
|
|
|
3212 MAKE_VALGRIND_HAPPY(loop);
|
|
|
3213 return 0;
|
|
|
3214 }
|
|
|
3215
|
|
|
3216
|
|
|
3217 /* Run in Valgrind. Should not leak when the iterator isn't exhausted. */
|
|
|
3218 TEST_IMPL(fs_scandir_early_exit) {
|
|
|
3219 uv_dirent_t d;
|
|
|
3220 uv_fs_t req;
|
|
|
3221
|
|
|
3222 ASSERT_LT(0, uv_fs_scandir(NULL, &req, "test/fixtures/one_file", 0, NULL));
|
|
|
3223 ASSERT_NE(UV_EOF, uv_fs_scandir_next(&req, &d));
|
|
|
3224 uv_fs_req_cleanup(&req);
|
|
|
3225
|
|
|
3226 ASSERT_LT(0, uv_fs_scandir(NULL, &req, "test/fixtures", 0, NULL));
|
|
|
3227 ASSERT_NE(UV_EOF, uv_fs_scandir_next(&req, &d));
|
|
|
3228 uv_fs_req_cleanup(&req);
|
|
|
3229
|
|
|
3230 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
3231 return 0;
|
|
|
3232 }
|
|
|
3233
|
|
|
3234
|
|
|
3235 TEST_IMPL(fs_open_dir) {
|
|
|
3236 const char* path;
|
|
|
3237 uv_fs_t req;
|
|
|
3238 int r, file;
|
|
|
3239
|
|
|
3240 path = ".";
|
|
|
3241 loop = uv_default_loop();
|
|
|
3242
|
|
|
3243 r = uv_fs_open(NULL, &req, path, UV_FS_O_RDONLY, 0, NULL);
|
|
|
3244 ASSERT_GE(r, 0);
|
|
|
3245 ASSERT_GE(req.result, 0);
|
|
|
3246 ASSERT_NULL(req.ptr);
|
|
|
3247 file = r;
|
|
|
3248 uv_fs_req_cleanup(&req);
|
|
|
3249
|
|
|
3250 r = uv_fs_close(NULL, &req, file, NULL);
|
|
|
3251 ASSERT_OK(r);
|
|
|
3252
|
|
|
3253 r = uv_fs_open(loop, &req, path, UV_FS_O_RDONLY, 0, open_cb_simple);
|
|
|
3254 ASSERT_OK(r);
|
|
|
3255
|
|
|
3256 ASSERT_OK(open_cb_count);
|
|
|
3257 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
3258 ASSERT_EQ(1, open_cb_count);
|
|
|
3259
|
|
|
3260 MAKE_VALGRIND_HAPPY(loop);
|
|
|
3261 return 0;
|
|
|
3262 }
|
|
|
3263
|
|
|
3264
|
|
|
3265 static void fs_file_open_append(int add_flags) {
|
|
|
3266 int r;
|
|
|
3267
|
|
|
3268 /* Setup. */
|
|
|
3269 unlink("test_file");
|
|
|
3270
|
|
|
3271 loop = uv_default_loop();
|
|
|
3272
|
|
|
3273 r = uv_fs_open(NULL, &open_req1, "test_file",
|
|
|
3274 UV_FS_O_WRONLY | UV_FS_O_CREAT | add_flags, S_IWUSR | S_IRUSR,
|
|
|
3275 NULL);
|
|
|
3276 ASSERT_GE(r, 0);
|
|
|
3277 ASSERT_GE(open_req1.result, 0);
|
|
|
3278 uv_fs_req_cleanup(&open_req1);
|
|
|
3279
|
|
|
3280 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
3281 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
3282 ASSERT_GE(r, 0);
|
|
|
3283 ASSERT_GE(write_req.result, 0);
|
|
|
3284 uv_fs_req_cleanup(&write_req);
|
|
|
3285
|
|
|
3286 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3287 ASSERT_OK(r);
|
|
|
3288 ASSERT_OK(close_req.result);
|
|
|
3289 uv_fs_req_cleanup(&close_req);
|
|
|
3290
|
|
|
3291 r = uv_fs_open(NULL, &open_req1, "test_file",
|
|
|
3292 UV_FS_O_RDWR | UV_FS_O_APPEND | add_flags, 0, NULL);
|
|
|
3293 ASSERT_GE(r, 0);
|
|
|
3294 ASSERT_GE(open_req1.result, 0);
|
|
|
3295 uv_fs_req_cleanup(&open_req1);
|
|
|
3296
|
|
|
3297 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
3298 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
3299 ASSERT_GE(r, 0);
|
|
|
3300 ASSERT_GE(write_req.result, 0);
|
|
|
3301 uv_fs_req_cleanup(&write_req);
|
|
|
3302
|
|
|
3303 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3304 ASSERT_OK(r);
|
|
|
3305 ASSERT_OK(close_req.result);
|
|
|
3306 uv_fs_req_cleanup(&close_req);
|
|
|
3307
|
|
|
3308 r = uv_fs_open(NULL, &open_req1, "test_file", UV_FS_O_RDONLY | add_flags,
|
|
|
3309 S_IRUSR, NULL);
|
|
|
3310 ASSERT_GE(r, 0);
|
|
|
3311 ASSERT_GE(open_req1.result, 0);
|
|
|
3312 uv_fs_req_cleanup(&open_req1);
|
|
|
3313
|
|
|
3314 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
3315 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
3316 printf("read = %d\n", r);
|
|
|
3317 ASSERT_EQ(26, r);
|
|
|
3318 ASSERT_EQ(26, read_req.result);
|
|
|
3319 ASSERT_OK(memcmp(buf,
|
|
|
3320 "test-buffer\n\0test-buffer\n\0",
|
|
|
3321 sizeof("test-buffer\n\0test-buffer\n\0") - 1));
|
|
|
3322 uv_fs_req_cleanup(&read_req);
|
|
|
3323
|
|
|
3324 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3325 ASSERT_OK(r);
|
|
|
3326 ASSERT_OK(close_req.result);
|
|
|
3327 uv_fs_req_cleanup(&close_req);
|
|
|
3328
|
|
|
3329 /* Cleanup */
|
|
|
3330 unlink("test_file");
|
|
|
3331 }
|
|
|
3332 TEST_IMPL(fs_file_open_append) {
|
|
|
3333 fs_file_open_append(0);
|
|
|
3334 fs_file_open_append(UV_FS_O_FILEMAP);
|
|
|
3335
|
|
|
3336 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
3337 return 0;
|
|
|
3338 }
|
|
|
3339
|
|
|
3340
|
|
|
3341 TEST_IMPL(fs_rename_to_existing_file) {
|
|
|
3342 int r;
|
|
|
3343
|
|
|
3344 /* Setup. */
|
|
|
3345 unlink("test_file");
|
|
|
3346 unlink("test_file2");
|
|
|
3347
|
|
|
3348 loop = uv_default_loop();
|
|
|
3349
|
|
|
3350 r = uv_fs_open(NULL, &open_req1, "test_file", UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
|
|
3351 S_IWUSR | S_IRUSR, NULL);
|
|
|
3352 ASSERT_GE(r, 0);
|
|
|
3353 ASSERT_GE(open_req1.result, 0);
|
|
|
3354 uv_fs_req_cleanup(&open_req1);
|
|
|
3355
|
|
|
3356 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
3357 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
3358 ASSERT_GE(r, 0);
|
|
|
3359 ASSERT_GE(write_req.result, 0);
|
|
|
3360 uv_fs_req_cleanup(&write_req);
|
|
|
3361
|
|
|
3362 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3363 ASSERT_OK(r);
|
|
|
3364 ASSERT_OK(close_req.result);
|
|
|
3365 uv_fs_req_cleanup(&close_req);
|
|
|
3366
|
|
|
3367 r = uv_fs_open(NULL, &open_req1, "test_file2", UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
|
|
3368 S_IWUSR | S_IRUSR, NULL);
|
|
|
3369 ASSERT_GE(r, 0);
|
|
|
3370 ASSERT_GE(open_req1.result, 0);
|
|
|
3371 uv_fs_req_cleanup(&open_req1);
|
|
|
3372
|
|
|
3373 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3374 ASSERT_OK(r);
|
|
|
3375 ASSERT_OK(close_req.result);
|
|
|
3376 uv_fs_req_cleanup(&close_req);
|
|
|
3377
|
|
|
3378 r = uv_fs_rename(NULL, &rename_req, "test_file", "test_file2", NULL);
|
|
|
3379 ASSERT_OK(r);
|
|
|
3380 ASSERT_OK(rename_req.result);
|
|
|
3381 uv_fs_req_cleanup(&rename_req);
|
|
|
3382
|
|
|
3383 r = uv_fs_open(NULL, &open_req1, "test_file2", UV_FS_O_RDONLY, 0, NULL);
|
|
|
3384 ASSERT_GE(r, 0);
|
|
|
3385 ASSERT_GE(open_req1.result, 0);
|
|
|
3386 uv_fs_req_cleanup(&open_req1);
|
|
|
3387
|
|
|
3388 memset(buf, 0, sizeof(buf));
|
|
|
3389 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
3390 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
3391 ASSERT_GE(r, 0);
|
|
|
3392 ASSERT_GE(read_req.result, 0);
|
|
|
3393 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
3394 uv_fs_req_cleanup(&read_req);
|
|
|
3395
|
|
|
3396 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3397 ASSERT_OK(r);
|
|
|
3398 ASSERT_OK(close_req.result);
|
|
|
3399 uv_fs_req_cleanup(&close_req);
|
|
|
3400
|
|
|
3401 /* Cleanup */
|
|
|
3402 unlink("test_file");
|
|
|
3403 unlink("test_file2");
|
|
|
3404
|
|
|
3405 MAKE_VALGRIND_HAPPY(loop);
|
|
|
3406 return 0;
|
|
|
3407 }
|
|
|
3408
|
|
|
3409
|
|
|
3410 static void fs_read_bufs(int add_flags) {
|
|
|
3411 char scratch[768];
|
|
|
3412 uv_buf_t bufs[4];
|
|
|
3413
|
|
|
3414 ASSERT_LE(0, uv_fs_open(NULL, &open_req1,
|
|
|
3415 "test/fixtures/lorem_ipsum.txt",
|
|
|
3416 UV_FS_O_RDONLY | add_flags, 0, NULL));
|
|
|
3417 ASSERT_GE(open_req1.result, 0);
|
|
|
3418 uv_fs_req_cleanup(&open_req1);
|
|
|
3419
|
|
|
3420 ASSERT_EQ(UV_EINVAL, uv_fs_read(NULL, &read_req, open_req1.result,
|
|
|
3421 NULL, 0, 0, NULL));
|
|
|
3422 ASSERT_EQ(UV_EINVAL, uv_fs_read(NULL, &read_req, open_req1.result,
|
|
|
3423 NULL, 1, 0, NULL));
|
|
|
3424 ASSERT_EQ(UV_EINVAL, uv_fs_read(NULL, &read_req, open_req1.result,
|
|
|
3425 bufs, 0, 0, NULL));
|
|
|
3426
|
|
|
3427 bufs[0] = uv_buf_init(scratch + 0, 256);
|
|
|
3428 bufs[1] = uv_buf_init(scratch + 256, 256);
|
|
|
3429 bufs[2] = uv_buf_init(scratch + 512, 128);
|
|
|
3430 bufs[3] = uv_buf_init(scratch + 640, 128);
|
|
|
3431
|
|
|
3432 ASSERT_EQ(446, uv_fs_read(NULL,
|
|
|
3433 &read_req,
|
|
|
3434 open_req1.result,
|
|
|
3435 bufs + 0,
|
|
|
3436 2, /* 2x 256 bytes. */
|
|
|
3437 0, /* Positional read. */
|
|
|
3438 NULL));
|
|
|
3439 ASSERT_EQ(446, read_req.result);
|
|
|
3440 uv_fs_req_cleanup(&read_req);
|
|
|
3441
|
|
|
3442 ASSERT_EQ(190, uv_fs_read(NULL,
|
|
|
3443 &read_req,
|
|
|
3444 open_req1.result,
|
|
|
3445 bufs + 2,
|
|
|
3446 2, /* 2x 128 bytes. */
|
|
|
3447 256, /* Positional read. */
|
|
|
3448 NULL));
|
|
|
3449 ASSERT_EQ(read_req.result, /* 446 - 256 */ 190);
|
|
|
3450 uv_fs_req_cleanup(&read_req);
|
|
|
3451
|
|
|
3452 ASSERT_OK(memcmp(bufs[1].base + 0, bufs[2].base, 128));
|
|
|
3453 ASSERT_OK(memcmp(bufs[1].base + 128, bufs[3].base, 190 - 128));
|
|
|
3454
|
|
|
3455 ASSERT_OK(uv_fs_close(NULL, &close_req, open_req1.result, NULL));
|
|
|
3456 ASSERT_OK(close_req.result);
|
|
|
3457 uv_fs_req_cleanup(&close_req);
|
|
|
3458 }
|
|
|
3459 TEST_IMPL(fs_read_bufs) {
|
|
|
3460 fs_read_bufs(0);
|
|
|
3461 fs_read_bufs(UV_FS_O_FILEMAP);
|
|
|
3462
|
|
|
3463 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
3464 return 0;
|
|
|
3465 }
|
|
|
3466
|
|
|
3467
|
|
|
3468 static void fs_read_file_eof(int add_flags) {
|
|
|
3469 #if defined(__CYGWIN__) || defined(__MSYS__)
|
|
|
3470 RETURN_SKIP("Cygwin pread at EOF may (incorrectly) return data!");
|
|
|
3471 #endif
|
|
|
3472 int r;
|
|
|
3473
|
|
|
3474 /* Setup. */
|
|
|
3475 unlink("test_file");
|
|
|
3476
|
|
|
3477 loop = uv_default_loop();
|
|
|
3478
|
|
|
3479 r = uv_fs_open(NULL, &open_req1, "test_file",
|
|
|
3480 UV_FS_O_WRONLY | UV_FS_O_CREAT | add_flags, S_IWUSR | S_IRUSR,
|
|
|
3481 NULL);
|
|
|
3482 ASSERT_GE(r, 0);
|
|
|
3483 ASSERT_GE(open_req1.result, 0);
|
|
|
3484 uv_fs_req_cleanup(&open_req1);
|
|
|
3485
|
|
|
3486 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
3487 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
3488 ASSERT_GE(r, 0);
|
|
|
3489 ASSERT_GE(write_req.result, 0);
|
|
|
3490 uv_fs_req_cleanup(&write_req);
|
|
|
3491
|
|
|
3492 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3493 ASSERT_OK(r);
|
|
|
3494 ASSERT_OK(close_req.result);
|
|
|
3495 uv_fs_req_cleanup(&close_req);
|
|
|
3496
|
|
|
3497 r = uv_fs_open(NULL, &open_req1, "test_file", UV_FS_O_RDONLY | add_flags, 0,
|
|
|
3498 NULL);
|
|
|
3499 ASSERT_GE(r, 0);
|
|
|
3500 ASSERT_GE(open_req1.result, 0);
|
|
|
3501 uv_fs_req_cleanup(&open_req1);
|
|
|
3502
|
|
|
3503 memset(buf, 0, sizeof(buf));
|
|
|
3504 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
3505 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
3506 ASSERT_GE(r, 0);
|
|
|
3507 ASSERT_GE(read_req.result, 0);
|
|
|
3508 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
3509 uv_fs_req_cleanup(&read_req);
|
|
|
3510
|
|
|
3511 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
3512 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1,
|
|
|
3513 read_req.result, NULL);
|
|
|
3514 ASSERT_OK(r);
|
|
|
3515 ASSERT_OK(read_req.result);
|
|
|
3516 uv_fs_req_cleanup(&read_req);
|
|
|
3517
|
|
|
3518 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3519 ASSERT_OK(r);
|
|
|
3520 ASSERT_OK(close_req.result);
|
|
|
3521 uv_fs_req_cleanup(&close_req);
|
|
|
3522
|
|
|
3523 /* Cleanup */
|
|
|
3524 unlink("test_file");
|
|
|
3525 }
|
|
|
3526 TEST_IMPL(fs_read_file_eof) {
|
|
|
3527 fs_read_file_eof(0);
|
|
|
3528 fs_read_file_eof(UV_FS_O_FILEMAP);
|
|
|
3529
|
|
|
3530 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
3531 return 0;
|
|
|
3532 }
|
|
|
3533
|
|
|
3534
|
|
|
3535 static void fs_write_multiple_bufs(int add_flags) {
|
|
|
3536 uv_buf_t iovs[2];
|
|
|
3537 int r;
|
|
|
3538
|
|
|
3539 /* Setup. */
|
|
|
3540 unlink("test_file");
|
|
|
3541
|
|
|
3542 loop = uv_default_loop();
|
|
|
3543
|
|
|
3544 r = uv_fs_open(NULL, &open_req1, "test_file",
|
|
|
3545 UV_FS_O_WRONLY | UV_FS_O_CREAT | add_flags, S_IWUSR | S_IRUSR,
|
|
|
3546 NULL);
|
|
|
3547 ASSERT_GE(r, 0);
|
|
|
3548 ASSERT_GE(open_req1.result, 0);
|
|
|
3549 uv_fs_req_cleanup(&open_req1);
|
|
|
3550
|
|
|
3551 iovs[0] = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
3552 iovs[1] = uv_buf_init(test_buf2, sizeof(test_buf2));
|
|
|
3553 r = uv_fs_write(NULL, &write_req, open_req1.result, iovs, 2, 0, NULL);
|
|
|
3554 ASSERT_GE(r, 0);
|
|
|
3555 ASSERT_GE(write_req.result, 0);
|
|
|
3556 uv_fs_req_cleanup(&write_req);
|
|
|
3557
|
|
|
3558 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3559 ASSERT_OK(r);
|
|
|
3560 ASSERT_OK(close_req.result);
|
|
|
3561 uv_fs_req_cleanup(&close_req);
|
|
|
3562
|
|
|
3563 r = uv_fs_open(NULL, &open_req1, "test_file", UV_FS_O_RDONLY | add_flags, 0,
|
|
|
3564 NULL);
|
|
|
3565 ASSERT_GE(r, 0);
|
|
|
3566 ASSERT_GE(open_req1.result, 0);
|
|
|
3567 uv_fs_req_cleanup(&open_req1);
|
|
|
3568
|
|
|
3569 memset(buf, 0, sizeof(buf));
|
|
|
3570 memset(buf2, 0, sizeof(buf2));
|
|
|
3571 /* Read the strings back to separate buffers. */
|
|
|
3572 iovs[0] = uv_buf_init(buf, sizeof(test_buf));
|
|
|
3573 iovs[1] = uv_buf_init(buf2, sizeof(test_buf2));
|
|
|
3574 ASSERT_OK(lseek(open_req1.result, 0, SEEK_CUR));
|
|
|
3575 r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, 2, -1, NULL);
|
|
|
3576 ASSERT_GE(r, 0);
|
|
|
3577 ASSERT_EQ(read_req.result, sizeof(test_buf) + sizeof(test_buf2));
|
|
|
3578 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
3579 ASSERT_OK(strcmp(buf2, test_buf2));
|
|
|
3580 uv_fs_req_cleanup(&read_req);
|
|
|
3581
|
|
|
3582 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
3583 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
3584 ASSERT_OK(r);
|
|
|
3585 ASSERT_OK(read_req.result);
|
|
|
3586 uv_fs_req_cleanup(&read_req);
|
|
|
3587
|
|
|
3588 /* Read the strings back to separate buffers. */
|
|
|
3589 iovs[0] = uv_buf_init(buf, sizeof(test_buf));
|
|
|
3590 iovs[1] = uv_buf_init(buf2, sizeof(test_buf2));
|
|
|
3591 r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, 2, 0, NULL);
|
|
|
3592 ASSERT_GE(r, 0);
|
|
|
3593 if (read_req.result == sizeof(test_buf)) {
|
|
|
3594 /* Infer that preadv is not available. */
|
|
|
3595 uv_fs_req_cleanup(&read_req);
|
|
|
3596 r = uv_fs_read(NULL, &read_req, open_req1.result, &iovs[1], 1, read_req.result, NULL);
|
|
|
3597 ASSERT_GE(r, 0);
|
|
|
3598 ASSERT_EQ(read_req.result, sizeof(test_buf2));
|
|
|
3599 } else {
|
|
|
3600 ASSERT_EQ(read_req.result, sizeof(test_buf) + sizeof(test_buf2));
|
|
|
3601 }
|
|
|
3602 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
3603 ASSERT_OK(strcmp(buf2, test_buf2));
|
|
|
3604 uv_fs_req_cleanup(&read_req);
|
|
|
3605
|
|
|
3606 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
3607 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1,
|
|
|
3608 sizeof(test_buf) + sizeof(test_buf2), NULL);
|
|
|
3609 ASSERT_OK(r);
|
|
|
3610 ASSERT_OK(read_req.result);
|
|
|
3611 uv_fs_req_cleanup(&read_req);
|
|
|
3612
|
|
|
3613 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3614 ASSERT_OK(r);
|
|
|
3615 ASSERT_OK(close_req.result);
|
|
|
3616 uv_fs_req_cleanup(&close_req);
|
|
|
3617
|
|
|
3618 /* Cleanup */
|
|
|
3619 unlink("test_file");
|
|
|
3620 }
|
|
|
3621 TEST_IMPL(fs_write_multiple_bufs) {
|
|
|
3622 fs_write_multiple_bufs(0);
|
|
|
3623 fs_write_multiple_bufs(UV_FS_O_FILEMAP);
|
|
|
3624
|
|
|
3625 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
3626 return 0;
|
|
|
3627 }
|
|
|
3628
|
|
|
3629
|
|
|
3630 static void fs_write_alotof_bufs(int add_flags) {
|
|
|
3631 size_t iovcount;
|
|
|
3632 size_t iovmax;
|
|
|
3633 uv_buf_t* iovs;
|
|
|
3634 char* buffer;
|
|
|
3635 size_t index;
|
|
|
3636 int r;
|
|
|
3637
|
|
|
3638 iovcount = 54321;
|
|
|
3639
|
|
|
3640 /* Setup. */
|
|
|
3641 unlink("test_file");
|
|
|
3642
|
|
|
3643 loop = uv_default_loop();
|
|
|
3644
|
|
|
3645 iovs = malloc(sizeof(*iovs) * iovcount);
|
|
|
3646 ASSERT_NOT_NULL(iovs);
|
|
|
3647 iovmax = uv_test_getiovmax();
|
|
|
3648
|
|
|
3649 r = uv_fs_open(NULL,
|
|
|
3650 &open_req1,
|
|
|
3651 "test_file",
|
|
|
3652 UV_FS_O_RDWR | UV_FS_O_CREAT | add_flags,
|
|
|
3653 S_IWUSR | S_IRUSR,
|
|
|
3654 NULL);
|
|
|
3655 ASSERT_GE(r, 0);
|
|
|
3656 ASSERT_GE(open_req1.result, 0);
|
|
|
3657 uv_fs_req_cleanup(&open_req1);
|
|
|
3658
|
|
|
3659 for (index = 0; index < iovcount; ++index)
|
|
|
3660 iovs[index] = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
3661
|
|
|
3662 r = uv_fs_write(NULL,
|
|
|
3663 &write_req,
|
|
|
3664 open_req1.result,
|
|
|
3665 iovs,
|
|
|
3666 iovcount,
|
|
|
3667 -1,
|
|
|
3668 NULL);
|
|
|
3669 ASSERT_GE(r, 0);
|
|
|
3670 ASSERT_EQ((size_t)write_req.result, sizeof(test_buf) * iovcount);
|
|
|
3671 uv_fs_req_cleanup(&write_req);
|
|
|
3672
|
|
|
3673 /* Read the strings back to separate buffers. */
|
|
|
3674 buffer = malloc(sizeof(test_buf) * iovcount);
|
|
|
3675 ASSERT_NOT_NULL(buffer);
|
|
|
3676
|
|
|
3677 for (index = 0; index < iovcount; ++index)
|
|
|
3678 iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf),
|
|
|
3679 sizeof(test_buf));
|
|
|
3680
|
|
|
3681 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3682 ASSERT_OK(r);
|
|
|
3683 ASSERT_OK(close_req.result);
|
|
|
3684 uv_fs_req_cleanup(&close_req);
|
|
|
3685
|
|
|
3686 r = uv_fs_open(NULL, &open_req1, "test_file", UV_FS_O_RDONLY | add_flags, 0,
|
|
|
3687 NULL);
|
|
|
3688 ASSERT_GE(r, 0);
|
|
|
3689 ASSERT_GE(open_req1.result, 0);
|
|
|
3690 uv_fs_req_cleanup(&open_req1);
|
|
|
3691
|
|
|
3692 r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, iovcount, -1, NULL);
|
|
|
3693 if (iovcount > iovmax)
|
|
|
3694 iovcount = iovmax;
|
|
|
3695 ASSERT_GE(r, 0);
|
|
|
3696 ASSERT_EQ((size_t)read_req.result, sizeof(test_buf) * iovcount);
|
|
|
3697
|
|
|
3698 for (index = 0; index < iovcount; ++index)
|
|
|
3699 ASSERT_OK(strncmp(buffer + index * sizeof(test_buf),
|
|
|
3700 test_buf,
|
|
|
3701 sizeof(test_buf)));
|
|
|
3702
|
|
|
3703 uv_fs_req_cleanup(&read_req);
|
|
|
3704 free(buffer);
|
|
|
3705
|
|
|
3706 ASSERT_EQ(lseek(open_req1.result, write_req.result, SEEK_SET),
|
|
|
3707 write_req.result);
|
|
|
3708 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
3709 r = uv_fs_read(NULL,
|
|
|
3710 &read_req,
|
|
|
3711 open_req1.result,
|
|
|
3712 &iov,
|
|
|
3713 1,
|
|
|
3714 -1,
|
|
|
3715 NULL);
|
|
|
3716 ASSERT_OK(r);
|
|
|
3717 ASSERT_OK(read_req.result);
|
|
|
3718 uv_fs_req_cleanup(&read_req);
|
|
|
3719
|
|
|
3720 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3721 ASSERT_OK(r);
|
|
|
3722 ASSERT_OK(close_req.result);
|
|
|
3723 uv_fs_req_cleanup(&close_req);
|
|
|
3724
|
|
|
3725 /* Cleanup */
|
|
|
3726 unlink("test_file");
|
|
|
3727 free(iovs);
|
|
|
3728 }
|
|
|
3729 TEST_IMPL(fs_write_alotof_bufs) {
|
|
|
3730 fs_write_alotof_bufs(0);
|
|
|
3731 fs_write_alotof_bufs(UV_FS_O_FILEMAP);
|
|
|
3732
|
|
|
3733 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
3734 return 0;
|
|
|
3735 }
|
|
|
3736
|
|
|
3737
|
|
|
3738 static void fs_write_alotof_bufs_with_offset(int add_flags) {
|
|
|
3739 size_t iovcount;
|
|
|
3740 size_t iovmax;
|
|
|
3741 uv_buf_t* iovs;
|
|
|
3742 char* buffer;
|
|
|
3743 size_t index;
|
|
|
3744 int r;
|
|
|
3745 int64_t offset;
|
|
|
3746 char* filler;
|
|
|
3747 int filler_len;
|
|
|
3748
|
|
|
3749 filler = "0123456789";
|
|
|
3750 filler_len = strlen(filler);
|
|
|
3751 iovcount = 54321;
|
|
|
3752
|
|
|
3753 /* Setup. */
|
|
|
3754 unlink("test_file");
|
|
|
3755
|
|
|
3756 loop = uv_default_loop();
|
|
|
3757
|
|
|
3758 iovs = malloc(sizeof(*iovs) * iovcount);
|
|
|
3759 ASSERT_NOT_NULL(iovs);
|
|
|
3760 iovmax = uv_test_getiovmax();
|
|
|
3761
|
|
|
3762 r = uv_fs_open(NULL,
|
|
|
3763 &open_req1,
|
|
|
3764 "test_file",
|
|
|
3765 UV_FS_O_RDWR | UV_FS_O_CREAT | add_flags,
|
|
|
3766 S_IWUSR | S_IRUSR,
|
|
|
3767 NULL);
|
|
|
3768 ASSERT_GE(r, 0);
|
|
|
3769 ASSERT_GE(open_req1.result, 0);
|
|
|
3770 uv_fs_req_cleanup(&open_req1);
|
|
|
3771
|
|
|
3772 iov = uv_buf_init(filler, filler_len);
|
|
|
3773 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
3774 ASSERT_EQ(r, filler_len);
|
|
|
3775 ASSERT_EQ(write_req.result, filler_len);
|
|
|
3776 uv_fs_req_cleanup(&write_req);
|
|
|
3777 offset = (int64_t)r;
|
|
|
3778
|
|
|
3779 for (index = 0; index < iovcount; ++index)
|
|
|
3780 iovs[index] = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
3781
|
|
|
3782 r = uv_fs_write(NULL,
|
|
|
3783 &write_req,
|
|
|
3784 open_req1.result,
|
|
|
3785 iovs,
|
|
|
3786 iovcount,
|
|
|
3787 offset,
|
|
|
3788 NULL);
|
|
|
3789 ASSERT_GE(r, 0);
|
|
|
3790 ASSERT_EQ((size_t)write_req.result, sizeof(test_buf) * iovcount);
|
|
|
3791 uv_fs_req_cleanup(&write_req);
|
|
|
3792
|
|
|
3793 /* Read the strings back to separate buffers. */
|
|
|
3794 buffer = malloc(sizeof(test_buf) * iovcount);
|
|
|
3795 ASSERT_NOT_NULL(buffer);
|
|
|
3796
|
|
|
3797 for (index = 0; index < iovcount; ++index)
|
|
|
3798 iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf),
|
|
|
3799 sizeof(test_buf));
|
|
|
3800
|
|
|
3801 r = uv_fs_read(NULL, &read_req, open_req1.result,
|
|
|
3802 iovs, iovcount, offset, NULL);
|
|
|
3803 ASSERT_GE(r, 0);
|
|
|
3804 if (r == sizeof(test_buf))
|
|
|
3805 iovcount = 1; /* Infer that preadv is not available. */
|
|
|
3806 else if (iovcount > iovmax)
|
|
|
3807 iovcount = iovmax;
|
|
|
3808 ASSERT_EQ((size_t)read_req.result, sizeof(test_buf) * iovcount);
|
|
|
3809
|
|
|
3810 for (index = 0; index < iovcount; ++index)
|
|
|
3811 ASSERT_OK(strncmp(buffer + index * sizeof(test_buf),
|
|
|
3812 test_buf,
|
|
|
3813 sizeof(test_buf)));
|
|
|
3814
|
|
|
3815 uv_fs_req_cleanup(&read_req);
|
|
|
3816 free(buffer);
|
|
|
3817
|
|
|
3818 r = uv_fs_stat(NULL, &stat_req, "test_file", NULL);
|
|
|
3819 ASSERT_OK(r);
|
|
|
3820 ASSERT_EQ((int64_t)((uv_stat_t*)stat_req.ptr)->st_size,
|
|
|
3821 offset + (int64_t)write_req.result);
|
|
|
3822 uv_fs_req_cleanup(&stat_req);
|
|
|
3823
|
|
|
3824 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
3825 r = uv_fs_read(NULL,
|
|
|
3826 &read_req,
|
|
|
3827 open_req1.result,
|
|
|
3828 &iov,
|
|
|
3829 1,
|
|
|
3830 offset + write_req.result,
|
|
|
3831 NULL);
|
|
|
3832 ASSERT_OK(r);
|
|
|
3833 ASSERT_OK(read_req.result);
|
|
|
3834 uv_fs_req_cleanup(&read_req);
|
|
|
3835
|
|
|
3836 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3837 ASSERT_OK(r);
|
|
|
3838 ASSERT_OK(close_req.result);
|
|
|
3839 uv_fs_req_cleanup(&close_req);
|
|
|
3840
|
|
|
3841 /* Cleanup */
|
|
|
3842 unlink("test_file");
|
|
|
3843 free(iovs);
|
|
|
3844 }
|
|
|
3845 TEST_IMPL(fs_write_alotof_bufs_with_offset) {
|
|
|
3846 fs_write_alotof_bufs_with_offset(0);
|
|
|
3847 fs_write_alotof_bufs_with_offset(UV_FS_O_FILEMAP);
|
|
|
3848
|
|
|
3849 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
3850 return 0;
|
|
|
3851 }
|
|
|
3852
|
|
|
3853 TEST_IMPL(fs_read_dir) {
|
|
|
3854 int r;
|
|
|
3855 char buf[2];
|
|
|
3856 loop = uv_default_loop();
|
|
|
3857
|
|
|
3858 /* Setup */
|
|
|
3859 rmdir("test_dir");
|
|
|
3860 r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb);
|
|
|
3861 ASSERT_OK(r);
|
|
|
3862 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
3863 ASSERT_EQ(1, mkdir_cb_count);
|
|
|
3864 /* Setup Done Here */
|
|
|
3865
|
|
|
3866 /* Get a file descriptor for the directory */
|
|
|
3867 r = uv_fs_open(loop,
|
|
|
3868 &open_req1,
|
|
|
3869 "test_dir",
|
|
|
3870 UV_FS_O_RDONLY | UV_FS_O_DIRECTORY,
|
|
|
3871 S_IWUSR | S_IRUSR,
|
|
|
3872 NULL);
|
|
|
3873 ASSERT_GE(r, 0);
|
|
|
3874 uv_fs_req_cleanup(&open_req1);
|
|
|
3875
|
|
|
3876 /* Try to read data from the directory */
|
|
|
3877 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
3878 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 0, NULL);
|
|
|
3879 #if defined(__FreeBSD__) || \
|
|
|
3880 defined(__OpenBSD__) || \
|
|
|
3881 defined(__NetBSD__) || \
|
|
|
3882 defined(__DragonFly__) || \
|
|
|
3883 defined(_AIX) || \
|
|
|
3884 defined(__sun) || \
|
|
|
3885 defined(__MVS__)
|
|
|
3886 /*
|
|
|
3887 * As of now, these operating systems support reading from a directory,
|
|
|
3888 * that too depends on the filesystem this temporary test directory is
|
|
|
3889 * created on. That is why this assertion is a bit lenient.
|
|
|
3890 */
|
|
|
3891 ASSERT((r >= 0) || (r == UV_EISDIR));
|
|
|
3892 #else
|
|
|
3893 ASSERT_EQ(r, UV_EISDIR);
|
|
|
3894 #endif
|
|
|
3895 uv_fs_req_cleanup(&read_req);
|
|
|
3896
|
|
|
3897 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
3898 ASSERT_OK(r);
|
|
|
3899 uv_fs_req_cleanup(&close_req);
|
|
|
3900
|
|
|
3901 /* Cleanup */
|
|
|
3902 rmdir("test_dir");
|
|
|
3903
|
|
|
3904 MAKE_VALGRIND_HAPPY(loop);
|
|
|
3905 return 0;
|
|
|
3906 }
|
|
|
3907
|
|
|
3908 #ifdef _WIN32
|
|
|
3909
|
|
|
3910 TEST_IMPL(fs_partial_read) {
|
|
|
3911 RETURN_SKIP("Test not implemented on Windows.");
|
|
|
3912 }
|
|
|
3913
|
|
|
3914 TEST_IMPL(fs_partial_write) {
|
|
|
3915 RETURN_SKIP("Test not implemented on Windows.");
|
|
|
3916 }
|
|
|
3917
|
|
|
3918 #else /* !_WIN32 */
|
|
|
3919
|
|
|
3920 struct thread_ctx {
|
|
|
3921 pthread_t pid;
|
|
|
3922 int fd;
|
|
|
3923 char* data;
|
|
|
3924 int size;
|
|
|
3925 int interval;
|
|
|
3926 int doread;
|
|
|
3927 };
|
|
|
3928
|
|
|
3929 static void thread_main(void* arg) {
|
|
|
3930 const struct thread_ctx* ctx;
|
|
|
3931 int size;
|
|
|
3932 char* data;
|
|
|
3933
|
|
|
3934 ctx = (struct thread_ctx*)arg;
|
|
|
3935 size = ctx->size;
|
|
|
3936 data = ctx->data;
|
|
|
3937
|
|
|
3938 while (size > 0) {
|
|
|
3939 ssize_t result;
|
|
|
3940 int nbytes;
|
|
|
3941 nbytes = size < ctx->interval ? size : ctx->interval;
|
|
|
3942 if (ctx->doread) {
|
|
|
3943 result = write(ctx->fd, data, nbytes);
|
|
|
3944 /* Should not see EINTR (or other errors) */
|
|
|
3945 ASSERT_EQ(result, nbytes);
|
|
|
3946 } else {
|
|
|
3947 result = read(ctx->fd, data, nbytes);
|
|
|
3948 /* Should not see EINTR (or other errors),
|
|
|
3949 * but might get a partial read if we are faster than the writer
|
|
|
3950 */
|
|
|
3951 ASSERT(result > 0 && result <= nbytes);
|
|
|
3952 }
|
|
|
3953
|
|
|
3954 pthread_kill(ctx->pid, SIGUSR1);
|
|
|
3955 size -= result;
|
|
|
3956 data += result;
|
|
|
3957 }
|
|
|
3958 }
|
|
|
3959
|
|
|
3960 static void sig_func(uv_signal_t* handle, int signum) {
|
|
|
3961 uv_signal_stop(handle);
|
|
|
3962 }
|
|
|
3963
|
|
|
3964 static size_t uv_test_fs_buf_offset(uv_buf_t* bufs, size_t size) {
|
|
|
3965 size_t offset;
|
|
|
3966 /* Figure out which bufs are done */
|
|
|
3967 for (offset = 0; size > 0 && bufs[offset].len <= size; ++offset)
|
|
|
3968 size -= bufs[offset].len;
|
|
|
3969
|
|
|
3970 /* Fix a partial read/write */
|
|
|
3971 if (size > 0) {
|
|
|
3972 bufs[offset].base += size;
|
|
|
3973 bufs[offset].len -= size;
|
|
|
3974 }
|
|
|
3975 return offset;
|
|
|
3976 }
|
|
|
3977
|
|
|
3978 static void test_fs_partial(int doread) {
|
|
|
3979 struct thread_ctx ctx;
|
|
|
3980 uv_thread_t thread;
|
|
|
3981 uv_signal_t signal;
|
|
|
3982 int pipe_fds[2];
|
|
|
3983 size_t iovcount;
|
|
|
3984 uv_buf_t* iovs;
|
|
|
3985 char* buffer;
|
|
|
3986 size_t index;
|
|
|
3987
|
|
|
3988 iovcount = 54321;
|
|
|
3989
|
|
|
3990 iovs = malloc(sizeof(*iovs) * iovcount);
|
|
|
3991 ASSERT_NOT_NULL(iovs);
|
|
|
3992
|
|
|
3993 ctx.pid = pthread_self();
|
|
|
3994 ctx.doread = doread;
|
|
|
3995 ctx.interval = 1000;
|
|
|
3996 ctx.size = sizeof(test_buf) * iovcount;
|
|
|
3997 ctx.data = calloc(ctx.size, 1);
|
|
|
3998 ASSERT_NOT_NULL(ctx.data);
|
|
|
3999 buffer = calloc(ctx.size, 1);
|
|
|
4000 ASSERT_NOT_NULL(buffer);
|
|
|
4001
|
|
|
4002 for (index = 0; index < iovcount; ++index)
|
|
|
4003 iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), sizeof(test_buf));
|
|
|
4004
|
|
|
4005 loop = uv_default_loop();
|
|
|
4006
|
|
|
4007 ASSERT_OK(uv_signal_init(loop, &signal));
|
|
|
4008 ASSERT_OK(uv_signal_start(&signal, sig_func, SIGUSR1));
|
|
|
4009
|
|
|
4010 ASSERT_OK(pipe(pipe_fds));
|
|
|
4011
|
|
|
4012 ctx.fd = pipe_fds[doread];
|
|
|
4013 ASSERT_OK(uv_thread_create(&thread, thread_main, &ctx));
|
|
|
4014
|
|
|
4015 if (doread) {
|
|
|
4016 uv_buf_t* read_iovs;
|
|
|
4017 int nread;
|
|
|
4018 read_iovs = iovs;
|
|
|
4019 nread = 0;
|
|
|
4020 while (nread < ctx.size) {
|
|
|
4021 int result;
|
|
|
4022 result = uv_fs_read(loop, &read_req, pipe_fds[0], read_iovs, iovcount, -1, NULL);
|
|
|
4023 if (result > 0) {
|
|
|
4024 size_t read_iovcount;
|
|
|
4025 read_iovcount = uv_test_fs_buf_offset(read_iovs, result);
|
|
|
4026 read_iovs += read_iovcount;
|
|
|
4027 iovcount -= read_iovcount;
|
|
|
4028 nread += result;
|
|
|
4029 } else {
|
|
|
4030 ASSERT_EQ(result, UV_EINTR);
|
|
|
4031 }
|
|
|
4032 uv_fs_req_cleanup(&read_req);
|
|
|
4033 }
|
|
|
4034 } else {
|
|
|
4035 int result;
|
|
|
4036 result = uv_fs_write(loop, &write_req, pipe_fds[1], iovs, iovcount, -1, NULL);
|
|
|
4037 ASSERT_EQ(write_req.result, result);
|
|
|
4038 ASSERT_EQ(result, ctx.size);
|
|
|
4039 uv_fs_req_cleanup(&write_req);
|
|
|
4040 }
|
|
|
4041
|
|
|
4042 ASSERT_OK(uv_thread_join(&thread));
|
|
|
4043
|
|
|
4044 ASSERT_MEM_EQ(buffer, ctx.data, ctx.size);
|
|
|
4045
|
|
|
4046 ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT));
|
|
|
4047
|
|
|
4048 ASSERT_OK(close(pipe_fds[1]));
|
|
|
4049 uv_close((uv_handle_t*) &signal, NULL);
|
|
|
4050
|
|
|
4051 { /* Make sure we read everything that we wrote. */
|
|
|
4052 int result;
|
|
|
4053 result = uv_fs_read(loop, &read_req, pipe_fds[0], iovs, 1, -1, NULL);
|
|
|
4054 ASSERT_OK(result);
|
|
|
4055 uv_fs_req_cleanup(&read_req);
|
|
|
4056 }
|
|
|
4057 ASSERT_OK(close(pipe_fds[0]));
|
|
|
4058
|
|
|
4059 free(iovs);
|
|
|
4060 free(buffer);
|
|
|
4061 free(ctx.data);
|
|
|
4062
|
|
|
4063 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4064 }
|
|
|
4065
|
|
|
4066 TEST_IMPL(fs_partial_read) {
|
|
|
4067 test_fs_partial(1);
|
|
|
4068 return 0;
|
|
|
4069 }
|
|
|
4070
|
|
|
4071 TEST_IMPL(fs_partial_write) {
|
|
|
4072 test_fs_partial(0);
|
|
|
4073 return 0;
|
|
|
4074 }
|
|
|
4075
|
|
|
4076 #endif/* _WIN32 */
|
|
|
4077
|
|
|
4078 TEST_IMPL(fs_read_write_null_arguments) {
|
|
|
4079 int r;
|
|
|
4080
|
|
|
4081 r = uv_fs_read(NULL, &read_req, 0, NULL, 0, -1, NULL);
|
|
|
4082 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4083 uv_fs_req_cleanup(&read_req);
|
|
|
4084
|
|
|
4085 r = uv_fs_write(NULL, &write_req, 0, NULL, 0, -1, NULL);
|
|
|
4086 /* Validate some memory management on failed input validation before sending
|
|
|
4087 fs work to the thread pool. */
|
|
|
4088 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4089 ASSERT_NULL(write_req.path);
|
|
|
4090 ASSERT_NULL(write_req.ptr);
|
|
|
4091 #ifdef _WIN32
|
|
|
4092 ASSERT_NULL(write_req.file.pathw);
|
|
|
4093 ASSERT_NULL(write_req.fs.info.new_pathw);
|
|
|
4094 ASSERT_NULL(write_req.fs.info.bufs);
|
|
|
4095 #else
|
|
|
4096 ASSERT_NULL(write_req.new_path);
|
|
|
4097 ASSERT_NULL(write_req.bufs);
|
|
|
4098 #endif
|
|
|
4099 uv_fs_req_cleanup(&write_req);
|
|
|
4100
|
|
|
4101 iov = uv_buf_init(NULL, 0);
|
|
|
4102 r = uv_fs_read(NULL, &read_req, 0, &iov, 0, -1, NULL);
|
|
|
4103 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4104 uv_fs_req_cleanup(&read_req);
|
|
|
4105
|
|
|
4106 iov = uv_buf_init(NULL, 0);
|
|
|
4107 r = uv_fs_write(NULL, &write_req, 0, &iov, 0, -1, NULL);
|
|
|
4108 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4109 uv_fs_req_cleanup(&write_req);
|
|
|
4110
|
|
|
4111 /* If the arguments are invalid, the loop should not be kept open */
|
|
|
4112 loop = uv_default_loop();
|
|
|
4113
|
|
|
4114 r = uv_fs_read(loop, &read_req, 0, NULL, 0, -1, fail_cb);
|
|
|
4115 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4116 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
4117 uv_fs_req_cleanup(&read_req);
|
|
|
4118
|
|
|
4119 r = uv_fs_write(loop, &write_req, 0, NULL, 0, -1, fail_cb);
|
|
|
4120 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4121 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
4122 uv_fs_req_cleanup(&write_req);
|
|
|
4123
|
|
|
4124 iov = uv_buf_init(NULL, 0);
|
|
|
4125 r = uv_fs_read(loop, &read_req, 0, &iov, 0, -1, fail_cb);
|
|
|
4126 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4127 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
4128 uv_fs_req_cleanup(&read_req);
|
|
|
4129
|
|
|
4130 iov = uv_buf_init(NULL, 0);
|
|
|
4131 r = uv_fs_write(loop, &write_req, 0, &iov, 0, -1, fail_cb);
|
|
|
4132 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4133 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
4134 uv_fs_req_cleanup(&write_req);
|
|
|
4135
|
|
|
4136 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4137 return 0;
|
|
|
4138 }
|
|
|
4139
|
|
|
4140
|
|
|
4141 TEST_IMPL(get_osfhandle_valid_handle) {
|
|
|
4142 int r;
|
|
|
4143 uv_os_fd_t fd;
|
|
|
4144
|
|
|
4145 /* Setup. */
|
|
|
4146 unlink("test_file");
|
|
|
4147
|
|
|
4148 loop = uv_default_loop();
|
|
|
4149
|
|
|
4150 r = uv_fs_open(NULL,
|
|
|
4151 &open_req1, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
4152 S_IWUSR | S_IRUSR,
|
|
|
4153 NULL);
|
|
|
4154 ASSERT_GE(r, 0);
|
|
|
4155 ASSERT_GE(open_req1.result, 0);
|
|
|
4156 uv_fs_req_cleanup(&open_req1);
|
|
|
4157
|
|
|
4158 fd = uv_get_osfhandle(open_req1.result);
|
|
|
4159 #ifdef _WIN32
|
|
|
4160 ASSERT_PTR_NE(fd, INVALID_HANDLE_VALUE);
|
|
|
4161 #else
|
|
|
4162 ASSERT_GE(fd, 0);
|
|
|
4163 #endif
|
|
|
4164
|
|
|
4165 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4166 ASSERT_OK(r);
|
|
|
4167 ASSERT_OK(close_req.result);
|
|
|
4168 uv_fs_req_cleanup(&close_req);
|
|
|
4169
|
|
|
4170 /* Cleanup. */
|
|
|
4171 unlink("test_file");
|
|
|
4172
|
|
|
4173 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4174 return 0;
|
|
|
4175 }
|
|
|
4176
|
|
|
4177 TEST_IMPL(open_osfhandle_valid_handle) {
|
|
|
4178 int r;
|
|
|
4179 uv_os_fd_t handle;
|
|
|
4180 int fd;
|
|
|
4181
|
|
|
4182 /* Setup. */
|
|
|
4183 unlink("test_file");
|
|
|
4184
|
|
|
4185 loop = uv_default_loop();
|
|
|
4186
|
|
|
4187 r = uv_fs_open(NULL,
|
|
|
4188 &open_req1,
|
|
|
4189 "test_file",
|
|
|
4190 UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
4191 S_IWUSR | S_IRUSR,
|
|
|
4192 NULL);
|
|
|
4193 ASSERT_GE(r, 0);
|
|
|
4194 ASSERT_GE(open_req1.result, 0);
|
|
|
4195 uv_fs_req_cleanup(&open_req1);
|
|
|
4196
|
|
|
4197 handle = uv_get_osfhandle(open_req1.result);
|
|
|
4198 #ifdef _WIN32
|
|
|
4199 ASSERT_PTR_NE(handle, INVALID_HANDLE_VALUE);
|
|
|
4200 #else
|
|
|
4201 ASSERT_GE(handle, 0);
|
|
|
4202 #endif
|
|
|
4203
|
|
|
4204 fd = uv_open_osfhandle(handle);
|
|
|
4205 #ifdef _WIN32
|
|
|
4206 ASSERT_GT(fd, 0);
|
|
|
4207 #else
|
|
|
4208 ASSERT_EQ(fd, open_req1.result);
|
|
|
4209 #endif
|
|
|
4210
|
|
|
4211 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4212 ASSERT_OK(r);
|
|
|
4213 ASSERT_OK(close_req.result);
|
|
|
4214 uv_fs_req_cleanup(&close_req);
|
|
|
4215
|
|
|
4216 /* Cleanup. */
|
|
|
4217 unlink("test_file");
|
|
|
4218
|
|
|
4219 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4220 return 0;
|
|
|
4221 }
|
|
|
4222
|
|
|
4223 TEST_IMPL(fs_file_pos_after_op_with_offset) {
|
|
|
4224 int r;
|
|
|
4225
|
|
|
4226 /* Setup. */
|
|
|
4227 unlink("test_file");
|
|
|
4228 loop = uv_default_loop();
|
|
|
4229
|
|
|
4230 r = uv_fs_open(loop,
|
|
|
4231 &open_req1, "test_file", UV_FS_O_RDWR | UV_FS_O_CREAT,
|
|
|
4232 S_IWUSR | S_IRUSR,
|
|
|
4233 NULL);
|
|
|
4234 ASSERT_GT(r, 0);
|
|
|
4235 uv_fs_req_cleanup(&open_req1);
|
|
|
4236
|
|
|
4237 iov = uv_buf_init(test_buf, sizeof(test_buf));
|
|
|
4238 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 0, NULL);
|
|
|
4239 ASSERT_EQ(r, sizeof(test_buf));
|
|
|
4240 ASSERT_OK(lseek(open_req1.result, 0, SEEK_CUR));
|
|
|
4241 uv_fs_req_cleanup(&write_req);
|
|
|
4242
|
|
|
4243 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
4244 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 0, NULL);
|
|
|
4245 ASSERT_EQ(r, sizeof(test_buf));
|
|
|
4246 ASSERT_OK(strcmp(buf, test_buf));
|
|
|
4247 ASSERT_OK(lseek(open_req1.result, 0, SEEK_CUR));
|
|
|
4248 uv_fs_req_cleanup(&read_req);
|
|
|
4249
|
|
|
4250 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4251 ASSERT_OK(r);
|
|
|
4252 uv_fs_req_cleanup(&close_req);
|
|
|
4253
|
|
|
4254 /* Cleanup */
|
|
|
4255 unlink("test_file");
|
|
|
4256
|
|
|
4257 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4258 return 0;
|
|
|
4259 }
|
|
|
4260
|
|
|
4261 #ifdef _WIN32
|
|
|
4262 static void fs_file_pos_common(void) {
|
|
|
4263 int r;
|
|
|
4264
|
|
|
4265 iov = uv_buf_init("abc", 3);
|
|
|
4266 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
4267 ASSERT_EQ(3, r);
|
|
|
4268 uv_fs_req_cleanup(&write_req);
|
|
|
4269
|
|
|
4270 /* Read with offset should not change the position */
|
|
|
4271 iov = uv_buf_init(buf, 1);
|
|
|
4272 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 1, NULL);
|
|
|
4273 ASSERT_EQ(1, r);
|
|
|
4274 ASSERT_EQ(buf[0], 'b');
|
|
|
4275 uv_fs_req_cleanup(&read_req);
|
|
|
4276
|
|
|
4277 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
4278 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
4279 ASSERT_OK(r);
|
|
|
4280 uv_fs_req_cleanup(&read_req);
|
|
|
4281
|
|
|
4282 /* Write without offset should change the position */
|
|
|
4283 iov = uv_buf_init("d", 1);
|
|
|
4284 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
4285 ASSERT_EQ(1, r);
|
|
|
4286 uv_fs_req_cleanup(&write_req);
|
|
|
4287
|
|
|
4288 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
4289 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
4290 ASSERT_OK(r);
|
|
|
4291 uv_fs_req_cleanup(&read_req);
|
|
|
4292 }
|
|
|
4293
|
|
|
4294 static void fs_file_pos_close_check(const char *contents, int size) {
|
|
|
4295 int r;
|
|
|
4296
|
|
|
4297 /* Close */
|
|
|
4298 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4299 ASSERT_OK(r);
|
|
|
4300 uv_fs_req_cleanup(&close_req);
|
|
|
4301
|
|
|
4302 /* Confirm file contents */
|
|
|
4303 r = uv_fs_open(NULL, &open_req1, "test_file", UV_FS_O_RDONLY, 0, NULL);
|
|
|
4304 ASSERT_GE(r, 0);
|
|
|
4305 ASSERT_GE(open_req1.result, 0);
|
|
|
4306 uv_fs_req_cleanup(&open_req1);
|
|
|
4307
|
|
|
4308 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
4309 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
4310 ASSERT_EQ(r, size);
|
|
|
4311 ASSERT_OK(strncmp(buf, contents, size));
|
|
|
4312 uv_fs_req_cleanup(&read_req);
|
|
|
4313
|
|
|
4314 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4315 ASSERT_OK(r);
|
|
|
4316 uv_fs_req_cleanup(&close_req);
|
|
|
4317
|
|
|
4318 /* Cleanup */
|
|
|
4319 unlink("test_file");
|
|
|
4320 }
|
|
|
4321
|
|
|
4322 static void fs_file_pos_write(int add_flags) {
|
|
|
4323 int r;
|
|
|
4324
|
|
|
4325 /* Setup. */
|
|
|
4326 unlink("test_file");
|
|
|
4327
|
|
|
4328 r = uv_fs_open(NULL,
|
|
|
4329 &open_req1,
|
|
|
4330 "test_file",
|
|
|
4331 UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_RDWR | add_flags,
|
|
|
4332 S_IWUSR | S_IRUSR,
|
|
|
4333 NULL);
|
|
|
4334 ASSERT_GT(r, 0);
|
|
|
4335 uv_fs_req_cleanup(&open_req1);
|
|
|
4336
|
|
|
4337 fs_file_pos_common();
|
|
|
4338
|
|
|
4339 /* Write with offset should not change the position */
|
|
|
4340 iov = uv_buf_init("e", 1);
|
|
|
4341 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 1, NULL);
|
|
|
4342 ASSERT_EQ(1, r);
|
|
|
4343 uv_fs_req_cleanup(&write_req);
|
|
|
4344
|
|
|
4345 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
4346 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
4347 ASSERT_OK(r);
|
|
|
4348 uv_fs_req_cleanup(&read_req);
|
|
|
4349
|
|
|
4350 fs_file_pos_close_check("aecd", 4);
|
|
|
4351 }
|
|
|
4352 TEST_IMPL(fs_file_pos_write) {
|
|
|
4353 fs_file_pos_write(0);
|
|
|
4354 fs_file_pos_write(UV_FS_O_FILEMAP);
|
|
|
4355
|
|
|
4356 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
4357 return 0;
|
|
|
4358 }
|
|
|
4359
|
|
|
4360 static void fs_file_pos_append(int add_flags) {
|
|
|
4361 int r;
|
|
|
4362
|
|
|
4363 /* Setup. */
|
|
|
4364 unlink("test_file");
|
|
|
4365
|
|
|
4366 r = uv_fs_open(NULL,
|
|
|
4367 &open_req1,
|
|
|
4368 "test_file",
|
|
|
4369 UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR | add_flags,
|
|
|
4370 S_IWUSR | S_IRUSR,
|
|
|
4371 NULL);
|
|
|
4372 ASSERT_GT(r, 0);
|
|
|
4373 uv_fs_req_cleanup(&open_req1);
|
|
|
4374
|
|
|
4375 fs_file_pos_common();
|
|
|
4376
|
|
|
4377 /* Write with offset appends (ignoring offset)
|
|
|
4378 * but does not change the position */
|
|
|
4379 iov = uv_buf_init("e", 1);
|
|
|
4380 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 1, NULL);
|
|
|
4381 ASSERT_EQ(1, r);
|
|
|
4382 uv_fs_req_cleanup(&write_req);
|
|
|
4383
|
|
|
4384 iov = uv_buf_init(buf, sizeof(buf));
|
|
|
4385 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
|
|
4386 ASSERT_EQ(1, r);
|
|
|
4387 ASSERT_EQ(buf[0], 'e');
|
|
|
4388 uv_fs_req_cleanup(&read_req);
|
|
|
4389
|
|
|
4390 fs_file_pos_close_check("abcde", 5);
|
|
|
4391 }
|
|
|
4392 TEST_IMPL(fs_file_pos_append) {
|
|
|
4393 fs_file_pos_append(0);
|
|
|
4394 fs_file_pos_append(UV_FS_O_FILEMAP);
|
|
|
4395
|
|
|
4396 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
4397 return 0;
|
|
|
4398 }
|
|
|
4399 #endif
|
|
|
4400
|
|
|
4401 TEST_IMPL(fs_null_req) {
|
|
|
4402 /* Verify that all fs functions return UV_EINVAL when the request is NULL. */
|
|
|
4403 int r;
|
|
|
4404
|
|
|
4405 r = uv_fs_open(NULL, NULL, NULL, 0, 0, NULL);
|
|
|
4406 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4407
|
|
|
4408 r = uv_fs_close(NULL, NULL, 0, NULL);
|
|
|
4409 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4410
|
|
|
4411 r = uv_fs_read(NULL, NULL, 0, NULL, 0, -1, NULL);
|
|
|
4412 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4413
|
|
|
4414 r = uv_fs_write(NULL, NULL, 0, NULL, 0, -1, NULL);
|
|
|
4415 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4416
|
|
|
4417 r = uv_fs_unlink(NULL, NULL, NULL, NULL);
|
|
|
4418 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4419
|
|
|
4420 r = uv_fs_mkdir(NULL, NULL, NULL, 0, NULL);
|
|
|
4421 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4422
|
|
|
4423 r = uv_fs_mkdtemp(NULL, NULL, NULL, NULL);
|
|
|
4424 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4425
|
|
|
4426 r = uv_fs_mkstemp(NULL, NULL, NULL, NULL);
|
|
|
4427 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4428
|
|
|
4429 r = uv_fs_rmdir(NULL, NULL, NULL, NULL);
|
|
|
4430 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4431
|
|
|
4432 r = uv_fs_scandir(NULL, NULL, NULL, 0, NULL);
|
|
|
4433 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4434
|
|
|
4435 r = uv_fs_link(NULL, NULL, NULL, NULL, NULL);
|
|
|
4436 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4437
|
|
|
4438 r = uv_fs_symlink(NULL, NULL, NULL, NULL, 0, NULL);
|
|
|
4439 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4440
|
|
|
4441 r = uv_fs_readlink(NULL, NULL, NULL, NULL);
|
|
|
4442 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4443
|
|
|
4444 r = uv_fs_realpath(NULL, NULL, NULL, NULL);
|
|
|
4445 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4446
|
|
|
4447 r = uv_fs_chown(NULL, NULL, NULL, 0, 0, NULL);
|
|
|
4448 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4449
|
|
|
4450 r = uv_fs_fchown(NULL, NULL, 0, 0, 0, NULL);
|
|
|
4451 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4452
|
|
|
4453 r = uv_fs_stat(NULL, NULL, NULL, NULL);
|
|
|
4454 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4455
|
|
|
4456 r = uv_fs_lstat(NULL, NULL, NULL, NULL);
|
|
|
4457 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4458
|
|
|
4459 r = uv_fs_fstat(NULL, NULL, 0, NULL);
|
|
|
4460 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4461
|
|
|
4462 r = uv_fs_rename(NULL, NULL, NULL, NULL, NULL);
|
|
|
4463 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4464
|
|
|
4465 r = uv_fs_fsync(NULL, NULL, 0, NULL);
|
|
|
4466 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4467
|
|
|
4468 r = uv_fs_fdatasync(NULL, NULL, 0, NULL);
|
|
|
4469 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4470
|
|
|
4471 r = uv_fs_ftruncate(NULL, NULL, 0, 0, NULL);
|
|
|
4472 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4473
|
|
|
4474 r = uv_fs_copyfile(NULL, NULL, NULL, NULL, 0, NULL);
|
|
|
4475 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4476
|
|
|
4477 r = uv_fs_sendfile(NULL, NULL, 0, 0, 0, 0, NULL);
|
|
|
4478 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4479
|
|
|
4480 r = uv_fs_access(NULL, NULL, NULL, 0, NULL);
|
|
|
4481 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4482
|
|
|
4483 r = uv_fs_chmod(NULL, NULL, NULL, 0, NULL);
|
|
|
4484 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4485
|
|
|
4486 r = uv_fs_fchmod(NULL, NULL, 0, 0, NULL);
|
|
|
4487 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4488
|
|
|
4489 r = uv_fs_utime(NULL, NULL, NULL, 0.0, 0.0, NULL);
|
|
|
4490 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4491
|
|
|
4492 r = uv_fs_futime(NULL, NULL, 0, 0.0, 0.0, NULL);
|
|
|
4493 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4494
|
|
|
4495 r = uv_fs_statfs(NULL, NULL, NULL, NULL);
|
|
|
4496 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4497
|
|
|
4498 /* This should be a no-op. */
|
|
|
4499 uv_fs_req_cleanup(NULL);
|
|
|
4500
|
|
|
4501 return 0;
|
|
|
4502 }
|
|
|
4503
|
|
|
4504 #ifdef _WIN32
|
|
|
4505 TEST_IMPL(fs_exclusive_sharing_mode) {
|
|
|
4506 int r;
|
|
|
4507
|
|
|
4508 /* Setup. */
|
|
|
4509 unlink("test_file");
|
|
|
4510
|
|
|
4511 ASSERT_GT(UV_FS_O_EXLOCK, 0);
|
|
|
4512
|
|
|
4513 r = uv_fs_open(NULL,
|
|
|
4514 &open_req1,
|
|
|
4515 "test_file",
|
|
|
4516 UV_FS_O_RDWR | UV_FS_O_CREAT | UV_FS_O_EXLOCK,
|
|
|
4517 S_IWUSR | S_IRUSR,
|
|
|
4518 NULL);
|
|
|
4519 ASSERT_GE(r, 0);
|
|
|
4520 ASSERT_GE(open_req1.result, 0);
|
|
|
4521 uv_fs_req_cleanup(&open_req1);
|
|
|
4522
|
|
|
4523 r = uv_fs_open(NULL,
|
|
|
4524 &open_req2,
|
|
|
4525 "test_file", UV_FS_O_RDONLY | UV_FS_O_EXLOCK,
|
|
|
4526 S_IWUSR | S_IRUSR,
|
|
|
4527 NULL);
|
|
|
4528 ASSERT_LT(r, 0);
|
|
|
4529 ASSERT_LT(open_req2.result, 0);
|
|
|
4530 uv_fs_req_cleanup(&open_req2);
|
|
|
4531
|
|
|
4532 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4533 ASSERT_OK(r);
|
|
|
4534 ASSERT_OK(close_req.result);
|
|
|
4535 uv_fs_req_cleanup(&close_req);
|
|
|
4536
|
|
|
4537 r = uv_fs_open(NULL,
|
|
|
4538 &open_req2,
|
|
|
4539 "test_file", UV_FS_O_RDONLY | UV_FS_O_EXLOCK,
|
|
|
4540 S_IWUSR | S_IRUSR,
|
|
|
4541 NULL);
|
|
|
4542 ASSERT_GE(r, 0);
|
|
|
4543 ASSERT_GE(open_req2.result, 0);
|
|
|
4544 uv_fs_req_cleanup(&open_req2);
|
|
|
4545
|
|
|
4546 r = uv_fs_close(NULL, &close_req, open_req2.result, NULL);
|
|
|
4547 ASSERT_OK(r);
|
|
|
4548 ASSERT_OK(close_req.result);
|
|
|
4549 uv_fs_req_cleanup(&close_req);
|
|
|
4550
|
|
|
4551 /* Cleanup */
|
|
|
4552 unlink("test_file");
|
|
|
4553
|
|
|
4554 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
4555 return 0;
|
|
|
4556 }
|
|
|
4557 #endif
|
|
|
4558
|
|
|
4559 #ifdef _WIN32
|
|
|
4560 TEST_IMPL(fs_file_flag_no_buffering) {
|
|
|
4561 int r;
|
|
|
4562
|
|
|
4563 /* Setup. */
|
|
|
4564 unlink("test_file");
|
|
|
4565
|
|
|
4566 ASSERT_GT(UV_FS_O_APPEND, 0);
|
|
|
4567 ASSERT_GT(UV_FS_O_CREAT, 0);
|
|
|
4568 ASSERT_GT(UV_FS_O_DIRECT, 0);
|
|
|
4569 ASSERT_GT(UV_FS_O_RDWR, 0);
|
|
|
4570
|
|
|
4571 /* FILE_APPEND_DATA must be excluded from FILE_GENERIC_WRITE: */
|
|
|
4572 r = uv_fs_open(NULL,
|
|
|
4573 &open_req1,
|
|
|
4574 "test_file",
|
|
|
4575 UV_FS_O_RDWR | UV_FS_O_CREAT | UV_FS_O_DIRECT,
|
|
|
4576 S_IWUSR | S_IRUSR,
|
|
|
4577 NULL);
|
|
|
4578 ASSERT_GE(r, 0);
|
|
|
4579 ASSERT_GE(open_req1.result, 0);
|
|
|
4580 uv_fs_req_cleanup(&open_req1);
|
|
|
4581
|
|
|
4582 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4583 ASSERT_OK(r);
|
|
|
4584 ASSERT_OK(close_req.result);
|
|
|
4585 uv_fs_req_cleanup(&close_req);
|
|
|
4586
|
|
|
4587 /* FILE_APPEND_DATA and FILE_FLAG_NO_BUFFERING are mutually exclusive: */
|
|
|
4588 r = uv_fs_open(NULL,
|
|
|
4589 &open_req2,
|
|
|
4590 "test_file",
|
|
|
4591 UV_FS_O_APPEND | UV_FS_O_DIRECT,
|
|
|
4592 S_IWUSR | S_IRUSR,
|
|
|
4593 NULL);
|
|
|
4594 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4595 ASSERT_EQ(open_req2.result, UV_EINVAL);
|
|
|
4596 uv_fs_req_cleanup(&open_req2);
|
|
|
4597
|
|
|
4598 /* Cleanup */
|
|
|
4599 unlink("test_file");
|
|
|
4600
|
|
|
4601 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
4602 return 0;
|
|
|
4603 }
|
|
|
4604 #endif
|
|
|
4605
|
|
|
4606 #ifdef _WIN32
|
|
|
4607 int call_icacls(const char* command, ...) {
|
|
|
4608 char icacls_command[1024];
|
|
|
4609 va_list args;
|
|
|
4610
|
|
|
4611 va_start(args, command);
|
|
|
4612 vsnprintf(icacls_command, ARRAYSIZE(icacls_command), command, args);
|
|
|
4613 va_end(args);
|
|
|
4614 return system(icacls_command);
|
|
|
4615 }
|
|
|
4616
|
|
|
4617 TEST_IMPL(fs_open_readonly_acl) {
|
|
|
4618 uv_passwd_t pwd;
|
|
|
4619 uv_fs_t req;
|
|
|
4620 int r;
|
|
|
4621
|
|
|
4622 /*
|
|
|
4623 Based on Node.js test from
|
|
|
4624 https://github.com/nodejs/node/commit/3ba81e34e86a5c32658e218cb6e65b13e8326bc5
|
|
|
4625
|
|
|
4626 If anything goes wrong, you can delte the test_fle_icacls with:
|
|
|
4627
|
|
|
4628 icacls test_file_icacls /remove "%USERNAME%" /inheritance:e
|
|
|
4629 attrib -r test_file_icacls
|
|
|
4630 del test_file_icacls
|
|
|
4631 */
|
|
|
4632
|
|
|
4633 /* Setup - clear the ACL and remove the file */
|
|
|
4634 loop = uv_default_loop();
|
|
|
4635 r = uv_os_get_passwd(&pwd);
|
|
|
4636 ASSERT_OK(r);
|
|
|
4637 call_icacls("icacls test_file_icacls /remove \"%s\" /inheritance:e",
|
|
|
4638 pwd.username);
|
|
|
4639 uv_fs_chmod(loop, &req, "test_file_icacls", S_IWUSR, NULL);
|
|
|
4640 unlink("test_file_icacls");
|
|
|
4641
|
|
|
4642 /* Create the file */
|
|
|
4643 r = uv_fs_open(loop,
|
|
|
4644 &open_req1,
|
|
|
4645 "test_file_icacls",
|
|
|
4646 UV_FS_O_RDONLY | UV_FS_O_CREAT,
|
|
|
4647 S_IRUSR,
|
|
|
4648 NULL);
|
|
|
4649 ASSERT_GE(r, 0);
|
|
|
4650 ASSERT_GE(open_req1.result, 0);
|
|
|
4651 uv_fs_req_cleanup(&open_req1);
|
|
|
4652 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4653 ASSERT_OK(r);
|
|
|
4654 ASSERT_OK(close_req.result);
|
|
|
4655 uv_fs_req_cleanup(&close_req);
|
|
|
4656
|
|
|
4657 /* Set up ACL */
|
|
|
4658 r = call_icacls("icacls test_file_icacls /inheritance:r /remove \"%s\"",
|
|
|
4659 pwd.username);
|
|
|
4660 if (r != 0) {
|
|
|
4661 goto acl_cleanup;
|
|
|
4662 }
|
|
|
4663 r = call_icacls("icacls test_file_icacls /grant \"%s\":RX", pwd.username);
|
|
|
4664 if (r != 0) {
|
|
|
4665 goto acl_cleanup;
|
|
|
4666 }
|
|
|
4667
|
|
|
4668 /* Try opening the file */
|
|
|
4669 r = uv_fs_open(NULL, &open_req1, "test_file_icacls", UV_FS_O_RDONLY, 0,
|
|
|
4670 NULL);
|
|
|
4671 if (r < 0) {
|
|
|
4672 goto acl_cleanup;
|
|
|
4673 }
|
|
|
4674 uv_fs_req_cleanup(&open_req1);
|
|
|
4675 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4676 if (r != 0) {
|
|
|
4677 goto acl_cleanup;
|
|
|
4678 }
|
|
|
4679 uv_fs_req_cleanup(&close_req);
|
|
|
4680
|
|
|
4681 acl_cleanup:
|
|
|
4682 /* Cleanup */
|
|
|
4683 call_icacls("icacls test_file_icacls /remove \"%s\" /inheritance:e",
|
|
|
4684 pwd.username);
|
|
|
4685 unlink("test_file_icacls");
|
|
|
4686 uv_os_free_passwd(&pwd);
|
|
|
4687 ASSERT_OK(r);
|
|
|
4688 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4689 return 0;
|
|
|
4690 }
|
|
|
4691
|
|
|
4692 TEST_IMPL(fs_stat_no_permission) {
|
|
|
4693 uv_passwd_t pwd;
|
|
|
4694 uv_fs_t req;
|
|
|
4695 int r;
|
|
|
4696 char* filename = "test_file_no_permission.txt";
|
|
|
4697
|
|
|
4698 /* Setup - clear the ACL and remove the file */
|
|
|
4699 loop = uv_default_loop();
|
|
|
4700 r = uv_os_get_passwd(&pwd);
|
|
|
4701 ASSERT_OK(r);
|
|
|
4702 call_icacls("icacls %s /remove *S-1-1-0:(F)", filename);
|
|
|
4703 unlink(filename);
|
|
|
4704
|
|
|
4705 /* Create the file */
|
|
|
4706 r = uv_fs_open(loop,
|
|
|
4707 &open_req1,
|
|
|
4708 filename,
|
|
|
4709 UV_FS_O_RDONLY | UV_FS_O_CREAT,
|
|
|
4710 S_IRUSR,
|
|
|
4711 NULL);
|
|
|
4712 ASSERT_GE(r, 0);
|
|
|
4713 ASSERT_GE(open_req1.result, 0);
|
|
|
4714 uv_fs_req_cleanup(&open_req1);
|
|
|
4715 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
|
|
4716 ASSERT_OK(r);
|
|
|
4717 ASSERT_OK(close_req.result);
|
|
|
4718 uv_fs_req_cleanup(&close_req);
|
|
|
4719
|
|
|
4720 /* Set up ACL */
|
|
|
4721 r = call_icacls("icacls %s /deny *S-1-1-0:(F)", filename);
|
|
|
4722 if (r != 0) {
|
|
|
4723 goto acl_cleanup;
|
|
|
4724 }
|
|
|
4725
|
|
|
4726 /* Read file stats */
|
|
|
4727 r = uv_fs_stat(NULL, &req, filename, NULL);
|
|
|
4728 if (r != 0) {
|
|
|
4729 goto acl_cleanup;
|
|
|
4730 }
|
|
|
4731
|
|
|
4732 uv_fs_req_cleanup(&req);
|
|
|
4733
|
|
|
4734 acl_cleanup:
|
|
|
4735 /* Cleanup */
|
|
|
4736 call_icacls("icacls %s /reset", filename);
|
|
|
4737 uv_fs_unlink(NULL, &unlink_req, filename, NULL);
|
|
|
4738 uv_fs_req_cleanup(&unlink_req);
|
|
|
4739 unlink(filename);
|
|
|
4740 uv_os_free_passwd(&pwd);
|
|
|
4741 ASSERT_OK(r);
|
|
|
4742 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4743 return 0;
|
|
|
4744 }
|
|
|
4745 #endif
|
|
|
4746
|
|
|
4747 #ifdef _WIN32
|
|
|
4748 TEST_IMPL(fs_fchmod_archive_readonly) {
|
|
|
4749 uv_fs_t req;
|
|
|
4750 uv_file file;
|
|
|
4751 int r;
|
|
|
4752 /* Test clearing read-only flag from files with Archive flag cleared */
|
|
|
4753
|
|
|
4754 /* Setup*/
|
|
|
4755 unlink("test_file");
|
|
|
4756 r = uv_fs_open(NULL,
|
|
|
4757 &req, "test_file", UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
|
|
4758 S_IWUSR | S_IRUSR,
|
|
|
4759 NULL);
|
|
|
4760 ASSERT_GE(r, 0);
|
|
|
4761 ASSERT_GE(req.result, 0);
|
|
|
4762 file = req.result;
|
|
|
4763 uv_fs_req_cleanup(&req);
|
|
|
4764 r = uv_fs_close(NULL, &req, file, NULL);
|
|
|
4765 ASSERT_OK(r);
|
|
|
4766 uv_fs_req_cleanup(&req);
|
|
|
4767 /* Make the file read-only and clear archive flag */
|
|
|
4768 r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY);
|
|
|
4769 ASSERT(r);
|
|
|
4770 check_permission("test_file", 0400);
|
|
|
4771 /* Try fchmod */
|
|
|
4772 r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_RDONLY, 0, NULL);
|
|
|
4773 ASSERT_GE(r, 0);
|
|
|
4774 ASSERT_GE(req.result, 0);
|
|
|
4775 file = req.result;
|
|
|
4776 uv_fs_req_cleanup(&req);
|
|
|
4777 r = uv_fs_fchmod(NULL, &req, file, S_IWUSR, NULL);
|
|
|
4778 ASSERT_OK(r);
|
|
|
4779 ASSERT_OK(req.result);
|
|
|
4780 uv_fs_req_cleanup(&req);
|
|
|
4781 r = uv_fs_close(NULL, &req, file, NULL);
|
|
|
4782 ASSERT_OK(r);
|
|
|
4783 uv_fs_req_cleanup(&req);
|
|
|
4784 check_permission("test_file", S_IWUSR);
|
|
|
4785
|
|
|
4786 /* Restore Archive flag for rest of the tests */
|
|
|
4787 r = SetFileAttributes("test_file", FILE_ATTRIBUTE_ARCHIVE);
|
|
|
4788 ASSERT(r);
|
|
|
4789
|
|
|
4790 return 0;
|
|
|
4791 }
|
|
|
4792
|
|
|
4793 TEST_IMPL(fs_invalid_mkdir_name) {
|
|
|
4794 uv_loop_t* loop;
|
|
|
4795 uv_fs_t req;
|
|
|
4796 int r;
|
|
|
4797
|
|
|
4798 loop = uv_default_loop();
|
|
|
4799 r = uv_fs_mkdir(loop, &req, "invalid>", 0, NULL);
|
|
|
4800 ASSERT_EQ(r, UV_EINVAL);
|
|
|
4801 ASSERT_EQ(UV_EINVAL, uv_fs_mkdir(loop, &req, "test:lol", 0, NULL));
|
|
|
4802
|
|
|
4803 return 0;
|
|
|
4804 }
|
|
|
4805 #endif
|
|
|
4806
|
|
|
4807 TEST_IMPL(fs_statfs) {
|
|
|
4808 uv_fs_t req;
|
|
|
4809 int r;
|
|
|
4810
|
|
|
4811 loop = uv_default_loop();
|
|
|
4812
|
|
|
4813 /* Test the synchronous version. */
|
|
|
4814 r = uv_fs_statfs(NULL, &req, ".", NULL);
|
|
|
4815 ASSERT_OK(r);
|
|
|
4816 statfs_cb(&req);
|
|
|
4817 ASSERT_EQ(1, statfs_cb_count);
|
|
|
4818
|
|
|
4819 /* Test the asynchronous version. */
|
|
|
4820 r = uv_fs_statfs(loop, &req, ".", statfs_cb);
|
|
|
4821 ASSERT_OK(r);
|
|
|
4822 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
4823 ASSERT_EQ(2, statfs_cb_count);
|
|
|
4824
|
|
|
4825 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4826 return 0;
|
|
|
4827 }
|
|
|
4828
|
|
|
4829 TEST_IMPL(fs_get_system_error) {
|
|
|
4830 uv_fs_t req;
|
|
|
4831 int r;
|
|
|
4832 int system_error;
|
|
|
4833
|
|
|
4834 r = uv_fs_statfs(NULL, &req, "non_existing_file", NULL);
|
|
|
4835 ASSERT(r);
|
|
|
4836
|
|
|
4837 system_error = uv_fs_get_system_error(&req);
|
|
|
4838 #ifdef _WIN32
|
|
|
4839 ASSERT_EQ(system_error, ERROR_FILE_NOT_FOUND);
|
|
|
4840 #else
|
|
|
4841 ASSERT_EQ(system_error, ENOENT);
|
|
|
4842 #endif
|
|
|
4843
|
|
|
4844 return 0;
|
|
|
4845 }
|
|
|
4846
|
|
|
4847
|
|
|
4848 TEST_IMPL(fs_stat_batch_multiple) {
|
|
|
4849 uv_fs_t req[300];
|
|
|
4850 int r;
|
|
|
4851 int i;
|
|
|
4852
|
|
|
4853 rmdir("test_dir");
|
|
|
4854
|
|
|
4855 r = uv_fs_mkdir(NULL, &mkdir_req, "test_dir", 0755, NULL);
|
|
|
4856 ASSERT_OK(r);
|
|
|
4857
|
|
|
4858 loop = uv_default_loop();
|
|
|
4859
|
|
|
4860 for (i = 0; i < (int) ARRAY_SIZE(req); ++i) {
|
|
|
4861 r = uv_fs_stat(loop, &req[i], "test_dir", stat_batch_cb);
|
|
|
4862 ASSERT_OK(r);
|
|
|
4863 }
|
|
|
4864
|
|
|
4865 uv_run(loop, UV_RUN_DEFAULT);
|
|
|
4866 ASSERT_EQ(stat_cb_count, ARRAY_SIZE(req));
|
|
|
4867
|
|
|
4868 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4869 return 0;
|
|
|
4870 }
|
|
|
4871
|
|
|
4872
|
|
|
4873 #ifdef _WIN32
|
|
|
4874 TEST_IMPL(fs_wtf) {
|
|
|
4875 int r;
|
|
|
4876 HANDLE file_handle;
|
|
|
4877 uv_dirent_t dent;
|
|
|
4878 static char test_file_buf[PATHMAX];
|
|
|
4879
|
|
|
4880 /* set-up */
|
|
|
4881 _wunlink(L"test_dir/hi\xD801\x0037");
|
|
|
4882 rmdir("test_dir");
|
|
|
4883
|
|
|
4884 loop = uv_default_loop();
|
|
|
4885
|
|
|
4886 r = uv_fs_mkdir(NULL, &mkdir_req, "test_dir", 0777, NULL);
|
|
|
4887 ASSERT_OK(r);
|
|
|
4888 uv_fs_req_cleanup(&mkdir_req);
|
|
|
4889
|
|
|
4890 file_handle = CreateFileW(L"test_dir/hi\xD801\x0037",
|
|
|
4891 GENERIC_WRITE | FILE_WRITE_ATTRIBUTES,
|
|
|
4892 0,
|
|
|
4893 NULL,
|
|
|
4894 CREATE_ALWAYS,
|
|
|
4895 FILE_FLAG_OPEN_REPARSE_POINT |
|
|
|
4896 FILE_FLAG_BACKUP_SEMANTICS,
|
|
|
4897 NULL);
|
|
|
4898 ASSERT_PTR_NE(file_handle, INVALID_HANDLE_VALUE);
|
|
|
4899
|
|
|
4900 CloseHandle(file_handle);
|
|
|
4901
|
|
|
4902 r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL);
|
|
|
4903 ASSERT_EQ(1, r);
|
|
|
4904 ASSERT_EQ(1, scandir_req.result);
|
|
|
4905 ASSERT_NOT_NULL(scandir_req.ptr);
|
|
|
4906 while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
|
|
|
4907 snprintf(test_file_buf, sizeof(test_file_buf), "test_dir\\%s", dent.name);
|
|
|
4908 printf("stat %s\n", test_file_buf);
|
|
|
4909 r = uv_fs_stat(NULL, &stat_req, test_file_buf, NULL);
|
|
|
4910 ASSERT_OK(r);
|
|
|
4911 }
|
|
|
4912 uv_fs_req_cleanup(&scandir_req);
|
|
|
4913 ASSERT_NULL(scandir_req.ptr);
|
|
|
4914
|
|
|
4915 /* clean-up */
|
|
|
4916 _wunlink(L"test_dir/hi\xD801\x0037");
|
|
|
4917 rmdir("test_dir");
|
|
|
4918
|
|
|
4919 MAKE_VALGRIND_HAPPY(loop);
|
|
|
4920 return 0;
|
|
|
4921 }
|
|
|
4922 #endif
|