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
30 /* FIXME we shouldn't need to branch in this file */
31 #if defined(__unix__) || defined(__POSIX__) || \
32 defined(__APPLE__) || defined(_AIX) || defined(__MVS__)
33 #include <unistd.h> /* unlink, rmdir, etc. */
34 #else
35 # include <winioctl.h>
36 # include <direct.h>
37 # include <io.h>
38 # ifndef ERROR_SYMLINK_NOT_SUPPORTED
39 # define ERROR_SYMLINK_NOT_SUPPORTED 1464
40 # endif
41 # define unlink _unlink
42 # define rmdir _rmdir
43 # define open _open
44 # define write _write
45 # define close _close
46 # ifndef stat
47 # define stat _stati64
48 # endif
49 # ifndef lseek
50 # define lseek _lseek
51 # endif
52 #endif
53
54 #define TOO_LONG_NAME_LENGTH 65536
55 #define PATHMAX 1024
56
57 typedef struct {
58 const char* path;
59 double atime;
60 double mtime;
61 } utime_check_t;
62
63
64 static int dummy_cb_count;
65 static int close_cb_count;
66 static int create_cb_count;
67 static int open_cb_count;
68 static int read_cb_count;
69 static int write_cb_count;
70 static int unlink_cb_count;
71 static int mkdir_cb_count;
72 static int mkdtemp_cb_count;
73 static int rmdir_cb_count;
74 static int scandir_cb_count;
75 static int stat_cb_count;
76 static int rename_cb_count;
77 static int fsync_cb_count;
78 static int fdatasync_cb_count;
79 static int ftruncate_cb_count;
80 static int sendfile_cb_count;
81 static int fstat_cb_count;
82 static int access_cb_count;
83 static int chmod_cb_count;
84 static int fchmod_cb_count;
85 static int chown_cb_count;
86 static int fchown_cb_count;
87 static int link_cb_count;
88 static int symlink_cb_count;
89 static int readlink_cb_count;
90 static int realpath_cb_count;
91 static int utime_cb_count;
92 static int futime_cb_count;
93
94 static uv_loop_t* loop;
95
96 static uv_fs_t open_req1;
97 static uv_fs_t open_req2;
98 static uv_fs_t read_req;
99 static uv_fs_t write_req;
100 static uv_fs_t unlink_req;
101 static uv_fs_t close_req;
102 static uv_fs_t mkdir_req;
103 static uv_fs_t mkdtemp_req1;
104 static uv_fs_t mkdtemp_req2;
105 static uv_fs_t rmdir_req;
106 static uv_fs_t scandir_req;
107 static uv_fs_t stat_req;
108 static uv_fs_t rename_req;
109 static uv_fs_t fsync_req;
110 static uv_fs_t fdatasync_req;
111 static uv_fs_t ftruncate_req;
112 static uv_fs_t sendfile_req;
113 static uv_fs_t utime_req;
114 static uv_fs_t futime_req;
115
116 static char buf[32];
117 static char buf2[32];
118 static char test_buf[] = "test-buffer\n";
119 static char test_buf2[] = "second-buffer\n";
120 static uv_buf_t iov;
121
122 #ifdef _WIN32
123 /*
124 * This tag and guid have no special meaning, and don't conflict with
125 * reserved ids.
126 */
127 static unsigned REPARSE_TAG = 0x9913;
128 static GUID REPARSE_GUID = {
129 0x1bf6205f, 0x46ae, 0x4527,
130 0xb1, 0x0c, 0xc5, 0x09, 0xb7, 0x55, 0x22, 0x80 };
131 #endif
132
check_permission(const char * filename,unsigned int mode)133 static void check_permission(const char* filename, unsigned int mode) {
134 int r;
135 uv_fs_t req;
136 uv_stat_t* s;
137
138 r = uv_fs_stat(NULL, &req, filename, NULL);
139 ASSERT(r == 0);
140 ASSERT(req.result == 0);
141
142 s = &req.statbuf;
143 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__)
144 /*
145 * On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit,
146 * so only testing for the specified flags.
147 */
148 ASSERT((s->st_mode & 0777) & mode);
149 #else
150 ASSERT((s->st_mode & 0777) == mode);
151 #endif
152
153 uv_fs_req_cleanup(&req);
154 }
155
156
dummy_cb(uv_fs_t * req)157 static void dummy_cb(uv_fs_t* req) {
158 (void) req;
159 dummy_cb_count++;
160 }
161
162
link_cb(uv_fs_t * req)163 static void link_cb(uv_fs_t* req) {
164 ASSERT(req->fs_type == UV_FS_LINK);
165 ASSERT(req->result == 0);
166 link_cb_count++;
167 uv_fs_req_cleanup(req);
168 }
169
170
symlink_cb(uv_fs_t * req)171 static void symlink_cb(uv_fs_t* req) {
172 ASSERT(req->fs_type == UV_FS_SYMLINK);
173 ASSERT(req->result == 0);
174 symlink_cb_count++;
175 uv_fs_req_cleanup(req);
176 }
177
readlink_cb(uv_fs_t * req)178 static void readlink_cb(uv_fs_t* req) {
179 ASSERT(req->fs_type == UV_FS_READLINK);
180 ASSERT(req->result == 0);
181 ASSERT(strcmp(req->ptr, "test_file_symlink2") == 0);
182 readlink_cb_count++;
183 uv_fs_req_cleanup(req);
184 }
185
186
realpath_cb(uv_fs_t * req)187 static void realpath_cb(uv_fs_t* req) {
188 char test_file_abs_buf[PATHMAX];
189 size_t test_file_abs_size = sizeof(test_file_abs_buf);
190 ASSERT(req->fs_type == UV_FS_REALPATH);
191 #ifdef _WIN32
192 /*
193 * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
194 */
195 if (req->result == UV_ENOSYS) {
196 realpath_cb_count++;
197 uv_fs_req_cleanup(req);
198 return;
199 }
200 #endif
201 ASSERT(req->result == 0);
202
203 uv_cwd(test_file_abs_buf, &test_file_abs_size);
204 #ifdef _WIN32
205 strcat(test_file_abs_buf, "\\test_file");
206 ASSERT(stricmp(req->ptr, test_file_abs_buf) == 0);
207 #else
208 strcat(test_file_abs_buf, "/test_file");
209 ASSERT(strcmp(req->ptr, test_file_abs_buf) == 0);
210 #endif
211 realpath_cb_count++;
212 uv_fs_req_cleanup(req);
213 }
214
215
access_cb(uv_fs_t * req)216 static void access_cb(uv_fs_t* req) {
217 ASSERT(req->fs_type == UV_FS_ACCESS);
218 access_cb_count++;
219 uv_fs_req_cleanup(req);
220 }
221
222
fchmod_cb(uv_fs_t * req)223 static void fchmod_cb(uv_fs_t* req) {
224 ASSERT(req->fs_type == UV_FS_FCHMOD);
225 ASSERT(req->result == 0);
226 fchmod_cb_count++;
227 uv_fs_req_cleanup(req);
228 check_permission("test_file", *(int*)req->data);
229 }
230
231
chmod_cb(uv_fs_t * req)232 static void chmod_cb(uv_fs_t* req) {
233 ASSERT(req->fs_type == UV_FS_CHMOD);
234 ASSERT(req->result == 0);
235 chmod_cb_count++;
236 uv_fs_req_cleanup(req);
237 check_permission("test_file", *(int*)req->data);
238 }
239
240
fchown_cb(uv_fs_t * req)241 static void fchown_cb(uv_fs_t* req) {
242 ASSERT(req->fs_type == UV_FS_FCHOWN);
243 ASSERT(req->result == 0);
244 fchown_cb_count++;
245 uv_fs_req_cleanup(req);
246 }
247
248
chown_cb(uv_fs_t * req)249 static void chown_cb(uv_fs_t* req) {
250 ASSERT(req->fs_type == UV_FS_CHOWN);
251 ASSERT(req->result == 0);
252 chown_cb_count++;
253 uv_fs_req_cleanup(req);
254 }
255
chown_root_cb(uv_fs_t * req)256 static void chown_root_cb(uv_fs_t* req) {
257 ASSERT(req->fs_type == UV_FS_CHOWN);
258 #if defined(_WIN32) || defined(__MSYS__)
259 /* On windows, chown is a no-op and always succeeds. */
260 ASSERT(req->result == 0);
261 #else
262 /* On unix, chown'ing the root directory is not allowed -
263 * unless you're root, of course.
264 */
265 if (geteuid() == 0)
266 ASSERT(req->result == 0);
267 else
268 # if defined(__CYGWIN__)
269 /* On Cygwin, uid 0 is invalid (no root). */
270 ASSERT(req->result == UV_EINVAL);
271 # else
272 ASSERT(req->result == UV_EPERM);
273 # endif
274 #endif
275 chown_cb_count++;
276 uv_fs_req_cleanup(req);
277 }
278
unlink_cb(uv_fs_t * req)279 static void unlink_cb(uv_fs_t* req) {
280 ASSERT(req == &unlink_req);
281 ASSERT(req->fs_type == UV_FS_UNLINK);
282 ASSERT(req->result == 0);
283 unlink_cb_count++;
284 uv_fs_req_cleanup(req);
285 }
286
fstat_cb(uv_fs_t * req)287 static void fstat_cb(uv_fs_t* req) {
288 uv_stat_t* s = req->ptr;
289 ASSERT(req->fs_type == UV_FS_FSTAT);
290 ASSERT(req->result == 0);
291 ASSERT(s->st_size == sizeof(test_buf));
292 uv_fs_req_cleanup(req);
293 fstat_cb_count++;
294 }
295
296
close_cb(uv_fs_t * req)297 static void close_cb(uv_fs_t* req) {
298 int r;
299 ASSERT(req == &close_req);
300 ASSERT(req->fs_type == UV_FS_CLOSE);
301 ASSERT(req->result == 0);
302 close_cb_count++;
303 uv_fs_req_cleanup(req);
304 if (close_cb_count == 3) {
305 r = uv_fs_unlink(loop, &unlink_req, "test_file2", unlink_cb);
306 ASSERT(r == 0);
307 }
308 }
309
310
ftruncate_cb(uv_fs_t * req)311 static void ftruncate_cb(uv_fs_t* req) {
312 int r;
313 ASSERT(req == &ftruncate_req);
314 ASSERT(req->fs_type == UV_FS_FTRUNCATE);
315 ASSERT(req->result == 0);
316 ftruncate_cb_count++;
317 uv_fs_req_cleanup(req);
318 r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
319 ASSERT(r == 0);
320 }
321
fail_cb(uv_fs_t * req)322 static void fail_cb(uv_fs_t* req) {
323 FATAL("fail_cb should not have been called");
324 }
325
read_cb(uv_fs_t * req)326 static void read_cb(uv_fs_t* req) {
327 int r;
328 ASSERT(req == &read_req);
329 ASSERT(req->fs_type == UV_FS_READ);
330 ASSERT(req->result >= 0); /* FIXME(bnoordhuis) Check if requested size? */
331 read_cb_count++;
332 uv_fs_req_cleanup(req);
333 if (read_cb_count == 1) {
334 ASSERT(strcmp(buf, test_buf) == 0);
335 r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7,
336 ftruncate_cb);
337 } else {
338 ASSERT(strcmp(buf, "test-bu") == 0);
339 r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
340 }
341 ASSERT(r == 0);
342 }
343
344
open_cb(uv_fs_t * req)345 static void open_cb(uv_fs_t* req) {
346 int r;
347 ASSERT(req == &open_req1);
348 ASSERT(req->fs_type == UV_FS_OPEN);
349 if (req->result < 0) {
350 fprintf(stderr, "async open error: %d\n", (int) req->result);
351 ASSERT(0);
352 }
353 open_cb_count++;
354 ASSERT(req->path);
355 ASSERT(memcmp(req->path, "test_file2\0", 11) == 0);
356 uv_fs_req_cleanup(req);
357 memset(buf, 0, sizeof(buf));
358 iov = uv_buf_init(buf, sizeof(buf));
359 r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1,
360 read_cb);
361 ASSERT(r == 0);
362 }
363
364
open_cb_simple(uv_fs_t * req)365 static void open_cb_simple(uv_fs_t* req) {
366 ASSERT(req->fs_type == UV_FS_OPEN);
367 if (req->result < 0) {
368 fprintf(stderr, "async open error: %d\n", (int) req->result);
369 ASSERT(0);
370 }
371 open_cb_count++;
372 ASSERT(req->path);
373 uv_fs_req_cleanup(req);
374 }
375
376
fsync_cb(uv_fs_t * req)377 static void fsync_cb(uv_fs_t* req) {
378 int r;
379 ASSERT(req == &fsync_req);
380 ASSERT(req->fs_type == UV_FS_FSYNC);
381 ASSERT(req->result == 0);
382 fsync_cb_count++;
383 uv_fs_req_cleanup(req);
384 r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
385 ASSERT(r == 0);
386 }
387
388
fdatasync_cb(uv_fs_t * req)389 static void fdatasync_cb(uv_fs_t* req) {
390 int r;
391 ASSERT(req == &fdatasync_req);
392 ASSERT(req->fs_type == UV_FS_FDATASYNC);
393 ASSERT(req->result == 0);
394 fdatasync_cb_count++;
395 uv_fs_req_cleanup(req);
396 r = uv_fs_fsync(loop, &fsync_req, open_req1.result, fsync_cb);
397 ASSERT(r == 0);
398 }
399
400
write_cb(uv_fs_t * req)401 static void write_cb(uv_fs_t* req) {
402 int r;
403 ASSERT(req == &write_req);
404 ASSERT(req->fs_type == UV_FS_WRITE);
405 ASSERT(req->result >= 0); /* FIXME(bnoordhuis) Check if requested size? */
406 write_cb_count++;
407 uv_fs_req_cleanup(req);
408 r = uv_fs_fdatasync(loop, &fdatasync_req, open_req1.result, fdatasync_cb);
409 ASSERT(r == 0);
410 }
411
412
create_cb(uv_fs_t * req)413 static void create_cb(uv_fs_t* req) {
414 int r;
415 ASSERT(req == &open_req1);
416 ASSERT(req->fs_type == UV_FS_OPEN);
417 ASSERT(req->result >= 0);
418 create_cb_count++;
419 uv_fs_req_cleanup(req);
420 iov = uv_buf_init(test_buf, sizeof(test_buf));
421 r = uv_fs_write(loop, &write_req, req->result, &iov, 1, -1, write_cb);
422 ASSERT(r == 0);
423 }
424
425
rename_cb(uv_fs_t * req)426 static void rename_cb(uv_fs_t* req) {
427 ASSERT(req == &rename_req);
428 ASSERT(req->fs_type == UV_FS_RENAME);
429 ASSERT(req->result == 0);
430 rename_cb_count++;
431 uv_fs_req_cleanup(req);
432 }
433
434
mkdir_cb(uv_fs_t * req)435 static void mkdir_cb(uv_fs_t* req) {
436 ASSERT(req == &mkdir_req);
437 ASSERT(req->fs_type == UV_FS_MKDIR);
438 ASSERT(req->result == 0);
439 mkdir_cb_count++;
440 ASSERT(req->path);
441 ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
442 uv_fs_req_cleanup(req);
443 }
444
445
check_mkdtemp_result(uv_fs_t * req)446 static void check_mkdtemp_result(uv_fs_t* req) {
447 int r;
448
449 ASSERT(req->fs_type == UV_FS_MKDTEMP);
450 ASSERT(req->result == 0);
451 ASSERT(req->path);
452 ASSERT(strlen(req->path) == 15);
453 ASSERT(memcmp(req->path, "test_dir_", 9) == 0);
454 ASSERT(memcmp(req->path + 9, "XXXXXX", 6) != 0);
455 check_permission(req->path, 0700);
456
457 /* Check if req->path is actually a directory */
458 r = uv_fs_stat(NULL, &stat_req, req->path, NULL);
459 ASSERT(r == 0);
460 ASSERT(((uv_stat_t*)stat_req.ptr)->st_mode & S_IFDIR);
461 uv_fs_req_cleanup(&stat_req);
462 }
463
464
mkdtemp_cb(uv_fs_t * req)465 static void mkdtemp_cb(uv_fs_t* req) {
466 ASSERT(req == &mkdtemp_req1);
467 check_mkdtemp_result(req);
468 mkdtemp_cb_count++;
469 }
470
471
rmdir_cb(uv_fs_t * req)472 static void rmdir_cb(uv_fs_t* req) {
473 ASSERT(req == &rmdir_req);
474 ASSERT(req->fs_type == UV_FS_RMDIR);
475 ASSERT(req->result == 0);
476 rmdir_cb_count++;
477 ASSERT(req->path);
478 ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
479 uv_fs_req_cleanup(req);
480 }
481
482
assert_is_file_type(uv_dirent_t dent)483 static void assert_is_file_type(uv_dirent_t dent) {
484 #ifdef HAVE_DIRENT_TYPES
485 /*
486 * For Apple and Windows, we know getdents is expected to work but for other
487 * environments, the filesystem dictates whether or not getdents supports
488 * returning the file type.
489 *
490 * See:
491 * http://man7.org/linux/man-pages/man2/getdents.2.html
492 * https://github.com/libuv/libuv/issues/501
493 */
494 #if defined(__APPLE__) || defined(_WIN32)
495 ASSERT(dent.type == UV_DIRENT_FILE);
496 #else
497 ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
498 #endif
499 #else
500 ASSERT(dent.type == UV_DIRENT_UNKNOWN);
501 #endif
502 }
503
504
scandir_cb(uv_fs_t * req)505 static void scandir_cb(uv_fs_t* req) {
506 uv_dirent_t dent;
507 ASSERT(req == &scandir_req);
508 ASSERT(req->fs_type == UV_FS_SCANDIR);
509 ASSERT(req->result == 2);
510 ASSERT(req->ptr);
511
512 while (UV_EOF != uv_fs_scandir_next(req, &dent)) {
513 ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
514 assert_is_file_type(dent);
515 }
516 scandir_cb_count++;
517 ASSERT(req->path);
518 ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
519 uv_fs_req_cleanup(req);
520 ASSERT(!req->ptr);
521 }
522
523
empty_scandir_cb(uv_fs_t * req)524 static void empty_scandir_cb(uv_fs_t* req) {
525 uv_dirent_t dent;
526
527 ASSERT(req == &scandir_req);
528 ASSERT(req->fs_type == UV_FS_SCANDIR);
529 ASSERT(req->result == 0);
530 ASSERT(req->ptr == NULL);
531 ASSERT(UV_EOF == uv_fs_scandir_next(req, &dent));
532 uv_fs_req_cleanup(req);
533 scandir_cb_count++;
534 }
535
non_existent_scandir_cb(uv_fs_t * req)536 static void non_existent_scandir_cb(uv_fs_t* req) {
537 uv_dirent_t dent;
538
539 ASSERT(req == &scandir_req);
540 ASSERT(req->fs_type == UV_FS_SCANDIR);
541 ASSERT(req->result == UV_ENOENT);
542 ASSERT(req->ptr == NULL);
543 ASSERT(UV_ENOENT == uv_fs_scandir_next(req, &dent));
544 uv_fs_req_cleanup(req);
545 scandir_cb_count++;
546 }
547
548
file_scandir_cb(uv_fs_t * req)549 static void file_scandir_cb(uv_fs_t* req) {
550 ASSERT(req == &scandir_req);
551 ASSERT(req->fs_type == UV_FS_SCANDIR);
552 ASSERT(req->result == UV_ENOTDIR);
553 ASSERT(req->ptr == NULL);
554 uv_fs_req_cleanup(req);
555 scandir_cb_count++;
556 }
557
558
stat_cb(uv_fs_t * req)559 static void stat_cb(uv_fs_t* req) {
560 ASSERT(req == &stat_req);
561 ASSERT(req->fs_type == UV_FS_STAT || req->fs_type == UV_FS_LSTAT);
562 ASSERT(req->result == 0);
563 ASSERT(req->ptr);
564 stat_cb_count++;
565 uv_fs_req_cleanup(req);
566 ASSERT(!req->ptr);
567 }
568
569
sendfile_cb(uv_fs_t * req)570 static void sendfile_cb(uv_fs_t* req) {
571 ASSERT(req == &sendfile_req);
572 ASSERT(req->fs_type == UV_FS_SENDFILE);
573 ASSERT(req->result == 65546);
574 sendfile_cb_count++;
575 uv_fs_req_cleanup(req);
576 }
577
578
open_noent_cb(uv_fs_t * req)579 static void open_noent_cb(uv_fs_t* req) {
580 ASSERT(req->fs_type == UV_FS_OPEN);
581 ASSERT(req->result == UV_ENOENT);
582 open_cb_count++;
583 uv_fs_req_cleanup(req);
584 }
585
open_nametoolong_cb(uv_fs_t * req)586 static void open_nametoolong_cb(uv_fs_t* req) {
587 ASSERT(req->fs_type == UV_FS_OPEN);
588 ASSERT(req->result == UV_ENAMETOOLONG);
589 open_cb_count++;
590 uv_fs_req_cleanup(req);
591 }
592
open_loop_cb(uv_fs_t * req)593 static void open_loop_cb(uv_fs_t* req) {
594 ASSERT(req->fs_type == UV_FS_OPEN);
595 ASSERT(req->result == UV_ELOOP);
596 open_cb_count++;
597 uv_fs_req_cleanup(req);
598 }
599
600
TEST_IMPL(fs_file_noent)601 TEST_IMPL(fs_file_noent) {
602 uv_fs_t req;
603 int r;
604
605 loop = uv_default_loop();
606
607 r = uv_fs_open(NULL, &req, "does_not_exist", O_RDONLY, 0, NULL);
608 ASSERT(r == UV_ENOENT);
609 ASSERT(req.result == UV_ENOENT);
610 uv_fs_req_cleanup(&req);
611
612 r = uv_fs_open(loop, &req, "does_not_exist", O_RDONLY, 0, open_noent_cb);
613 ASSERT(r == 0);
614
615 ASSERT(open_cb_count == 0);
616 uv_run(loop, UV_RUN_DEFAULT);
617 ASSERT(open_cb_count == 1);
618
619 /* TODO add EACCES test */
620
621 MAKE_VALGRIND_HAPPY();
622 return 0;
623 }
624
TEST_IMPL(fs_file_nametoolong)625 TEST_IMPL(fs_file_nametoolong) {
626 uv_fs_t req;
627 int r;
628 char name[TOO_LONG_NAME_LENGTH + 1];
629
630 loop = uv_default_loop();
631
632 memset(name, 'a', TOO_LONG_NAME_LENGTH);
633 name[TOO_LONG_NAME_LENGTH] = 0;
634
635 r = uv_fs_open(NULL, &req, name, O_RDONLY, 0, NULL);
636 ASSERT(r == UV_ENAMETOOLONG);
637 ASSERT(req.result == UV_ENAMETOOLONG);
638 uv_fs_req_cleanup(&req);
639
640 r = uv_fs_open(loop, &req, name, O_RDONLY, 0, open_nametoolong_cb);
641 ASSERT(r == 0);
642
643 ASSERT(open_cb_count == 0);
644 uv_run(loop, UV_RUN_DEFAULT);
645 ASSERT(open_cb_count == 1);
646
647 MAKE_VALGRIND_HAPPY();
648 return 0;
649 }
650
TEST_IMPL(fs_file_loop)651 TEST_IMPL(fs_file_loop) {
652 uv_fs_t req;
653 int r;
654
655 loop = uv_default_loop();
656
657 unlink("test_symlink");
658 r = uv_fs_symlink(NULL, &req, "test_symlink", "test_symlink", 0, NULL);
659 #ifdef _WIN32
660 /*
661 * Windows XP and Server 2003 don't support symlinks; we'll get UV_ENOTSUP.
662 * Starting with vista they are supported, but only when elevated, otherwise
663 * we'll see UV_EPERM.
664 */
665 if (r == UV_ENOTSUP || r == UV_EPERM)
666 return 0;
667 #elif defined(__MSYS__)
668 /* MSYS2's approximation of symlinks with copies does not work for broken
669 links. */
670 if (r == UV_ENOENT)
671 return 0;
672 #endif
673 ASSERT(r == 0);
674 uv_fs_req_cleanup(&req);
675
676 r = uv_fs_open(NULL, &req, "test_symlink", O_RDONLY, 0, NULL);
677 ASSERT(r == UV_ELOOP);
678 ASSERT(req.result == UV_ELOOP);
679 uv_fs_req_cleanup(&req);
680
681 r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, open_loop_cb);
682 ASSERT(r == 0);
683
684 ASSERT(open_cb_count == 0);
685 uv_run(loop, UV_RUN_DEFAULT);
686 ASSERT(open_cb_count == 1);
687
688 unlink("test_symlink");
689
690 MAKE_VALGRIND_HAPPY();
691 return 0;
692 }
693
check_utime(const char * path,double atime,double mtime)694 static void check_utime(const char* path, double atime, double mtime) {
695 uv_stat_t* s;
696 uv_fs_t req;
697 int r;
698
699 r = uv_fs_stat(loop, &req, path, NULL);
700 ASSERT(r == 0);
701
702 ASSERT(req.result == 0);
703 s = &req.statbuf;
704
705 ASSERT(s->st_atim.tv_sec + (s->st_atim.tv_nsec / 1000000000.0) == atime);
706 ASSERT(s->st_mtim.tv_sec + (s->st_mtim.tv_nsec / 1000000000.0) == mtime);
707
708 uv_fs_req_cleanup(&req);
709 }
710
711
utime_cb(uv_fs_t * req)712 static void utime_cb(uv_fs_t* req) {
713 utime_check_t* c;
714
715 ASSERT(req == &utime_req);
716 ASSERT(req->result == 0);
717 ASSERT(req->fs_type == UV_FS_UTIME);
718
719 c = req->data;
720 check_utime(c->path, c->atime, c->mtime);
721
722 uv_fs_req_cleanup(req);
723 utime_cb_count++;
724 }
725
726
futime_cb(uv_fs_t * req)727 static void futime_cb(uv_fs_t* req) {
728 utime_check_t* c;
729
730 ASSERT(req == &futime_req);
731 ASSERT(req->result == 0);
732 ASSERT(req->fs_type == UV_FS_FUTIME);
733
734 c = req->data;
735 check_utime(c->path, c->atime, c->mtime);
736
737 uv_fs_req_cleanup(req);
738 futime_cb_count++;
739 }
740
741
TEST_IMPL(fs_file_async)742 TEST_IMPL(fs_file_async) {
743 int r;
744
745 /* Setup. */
746 unlink("test_file");
747 unlink("test_file2");
748
749 loop = uv_default_loop();
750
751 r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
752 S_IRUSR | S_IWUSR, create_cb);
753 ASSERT(r == 0);
754 uv_run(loop, UV_RUN_DEFAULT);
755
756 ASSERT(create_cb_count == 1);
757 ASSERT(write_cb_count == 1);
758 ASSERT(fsync_cb_count == 1);
759 ASSERT(fdatasync_cb_count == 1);
760 ASSERT(close_cb_count == 1);
761
762 r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", rename_cb);
763 ASSERT(r == 0);
764
765 uv_run(loop, UV_RUN_DEFAULT);
766 ASSERT(create_cb_count == 1);
767 ASSERT(write_cb_count == 1);
768 ASSERT(close_cb_count == 1);
769 ASSERT(rename_cb_count == 1);
770
771 r = uv_fs_open(loop, &open_req1, "test_file2", O_RDWR, 0, open_cb);
772 ASSERT(r == 0);
773
774 uv_run(loop, UV_RUN_DEFAULT);
775 ASSERT(open_cb_count == 1);
776 ASSERT(read_cb_count == 1);
777 ASSERT(close_cb_count == 2);
778 ASSERT(rename_cb_count == 1);
779 ASSERT(create_cb_count == 1);
780 ASSERT(write_cb_count == 1);
781 ASSERT(ftruncate_cb_count == 1);
782
783 r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, open_cb);
784 ASSERT(r == 0);
785
786 uv_run(loop, UV_RUN_DEFAULT);
787 ASSERT(open_cb_count == 2);
788 ASSERT(read_cb_count == 2);
789 ASSERT(close_cb_count == 3);
790 ASSERT(rename_cb_count == 1);
791 ASSERT(unlink_cb_count == 1);
792 ASSERT(create_cb_count == 1);
793 ASSERT(write_cb_count == 1);
794 ASSERT(ftruncate_cb_count == 1);
795
796 /* Cleanup. */
797 unlink("test_file");
798 unlink("test_file2");
799
800 MAKE_VALGRIND_HAPPY();
801 return 0;
802 }
803
804
TEST_IMPL(fs_file_sync)805 TEST_IMPL(fs_file_sync) {
806 int r;
807
808 /* Setup. */
809 unlink("test_file");
810 unlink("test_file2");
811
812 loop = uv_default_loop();
813
814 r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
815 S_IWUSR | S_IRUSR, NULL);
816 ASSERT(r >= 0);
817 ASSERT(open_req1.result >= 0);
818 uv_fs_req_cleanup(&open_req1);
819
820 iov = uv_buf_init(test_buf, sizeof(test_buf));
821 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
822 ASSERT(r >= 0);
823 ASSERT(write_req.result >= 0);
824 uv_fs_req_cleanup(&write_req);
825
826 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
827 ASSERT(r == 0);
828 ASSERT(close_req.result == 0);
829 uv_fs_req_cleanup(&close_req);
830
831 r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR, 0, NULL);
832 ASSERT(r >= 0);
833 ASSERT(open_req1.result >= 0);
834 uv_fs_req_cleanup(&open_req1);
835
836 iov = uv_buf_init(buf, sizeof(buf));
837 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
838 ASSERT(r >= 0);
839 ASSERT(read_req.result >= 0);
840 ASSERT(strcmp(buf, test_buf) == 0);
841 uv_fs_req_cleanup(&read_req);
842
843 r = uv_fs_ftruncate(NULL, &ftruncate_req, open_req1.result, 7, NULL);
844 ASSERT(r == 0);
845 ASSERT(ftruncate_req.result == 0);
846 uv_fs_req_cleanup(&ftruncate_req);
847
848 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
849 ASSERT(r == 0);
850 ASSERT(close_req.result == 0);
851 uv_fs_req_cleanup(&close_req);
852
853 r = uv_fs_rename(NULL, &rename_req, "test_file", "test_file2", NULL);
854 ASSERT(r == 0);
855 ASSERT(rename_req.result == 0);
856 uv_fs_req_cleanup(&rename_req);
857
858 r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDONLY, 0, NULL);
859 ASSERT(r >= 0);
860 ASSERT(open_req1.result >= 0);
861 uv_fs_req_cleanup(&open_req1);
862
863 memset(buf, 0, sizeof(buf));
864 iov = uv_buf_init(buf, sizeof(buf));
865 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
866 ASSERT(r >= 0);
867 ASSERT(read_req.result >= 0);
868 ASSERT(strcmp(buf, "test-bu") == 0);
869 uv_fs_req_cleanup(&read_req);
870
871 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
872 ASSERT(r == 0);
873 ASSERT(close_req.result == 0);
874 uv_fs_req_cleanup(&close_req);
875
876 r = uv_fs_unlink(NULL, &unlink_req, "test_file2", NULL);
877 ASSERT(r == 0);
878 ASSERT(unlink_req.result == 0);
879 uv_fs_req_cleanup(&unlink_req);
880
881 /* Cleanup */
882 unlink("test_file");
883 unlink("test_file2");
884
885 MAKE_VALGRIND_HAPPY();
886 return 0;
887 }
888
889
TEST_IMPL(fs_file_write_null_buffer)890 TEST_IMPL(fs_file_write_null_buffer) {
891 int r;
892
893 /* Setup. */
894 unlink("test_file");
895
896 loop = uv_default_loop();
897
898 r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT,
899 S_IWUSR | S_IRUSR, NULL);
900 ASSERT(r >= 0);
901 ASSERT(open_req1.result >= 0);
902 uv_fs_req_cleanup(&open_req1);
903
904 iov = uv_buf_init(NULL, 0);
905 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
906 ASSERT(r == 0);
907 ASSERT(write_req.result == 0);
908 uv_fs_req_cleanup(&write_req);
909
910 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
911 ASSERT(r == 0);
912 ASSERT(close_req.result == 0);
913 uv_fs_req_cleanup(&close_req);
914
915 unlink("test_file");
916
917 MAKE_VALGRIND_HAPPY();
918 return 0;
919 }
920
921
TEST_IMPL(fs_async_dir)922 TEST_IMPL(fs_async_dir) {
923 int r;
924 uv_dirent_t dent;
925
926 /* Setup */
927 unlink("test_dir/file1");
928 unlink("test_dir/file2");
929 rmdir("test_dir");
930
931 loop = uv_default_loop();
932
933 r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb);
934 ASSERT(r == 0);
935
936 uv_run(loop, UV_RUN_DEFAULT);
937 ASSERT(mkdir_cb_count == 1);
938
939 /* Create 2 files synchronously. */
940 r = uv_fs_open(NULL, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT,
941 S_IWUSR | S_IRUSR, NULL);
942 ASSERT(r >= 0);
943 uv_fs_req_cleanup(&open_req1);
944 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
945 ASSERT(r == 0);
946 uv_fs_req_cleanup(&close_req);
947
948 r = uv_fs_open(NULL, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT,
949 S_IWUSR | S_IRUSR, NULL);
950 ASSERT(r >= 0);
951 uv_fs_req_cleanup(&open_req1);
952 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
953 ASSERT(r == 0);
954 uv_fs_req_cleanup(&close_req);
955
956 r = uv_fs_scandir(loop, &scandir_req, "test_dir", 0, scandir_cb);
957 ASSERT(r == 0);
958
959 uv_run(loop, UV_RUN_DEFAULT);
960 ASSERT(scandir_cb_count == 1);
961
962 /* sync uv_fs_scandir */
963 r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL);
964 ASSERT(r == 2);
965 ASSERT(scandir_req.result == 2);
966 ASSERT(scandir_req.ptr);
967 while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
968 ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
969 assert_is_file_type(dent);
970 }
971 uv_fs_req_cleanup(&scandir_req);
972 ASSERT(!scandir_req.ptr);
973
974 r = uv_fs_stat(loop, &stat_req, "test_dir", stat_cb);
975 ASSERT(r == 0);
976 uv_run(loop, UV_RUN_DEFAULT);
977
978 r = uv_fs_stat(loop, &stat_req, "test_dir/", stat_cb);
979 ASSERT(r == 0);
980 uv_run(loop, UV_RUN_DEFAULT);
981
982 r = uv_fs_lstat(loop, &stat_req, "test_dir", stat_cb);
983 ASSERT(r == 0);
984 uv_run(loop, UV_RUN_DEFAULT);
985
986 r = uv_fs_lstat(loop, &stat_req, "test_dir/", stat_cb);
987 ASSERT(r == 0);
988 uv_run(loop, UV_RUN_DEFAULT);
989
990 ASSERT(stat_cb_count == 4);
991
992 r = uv_fs_unlink(loop, &unlink_req, "test_dir/file1", unlink_cb);
993 ASSERT(r == 0);
994 uv_run(loop, UV_RUN_DEFAULT);
995 ASSERT(unlink_cb_count == 1);
996
997 r = uv_fs_unlink(loop, &unlink_req, "test_dir/file2", unlink_cb);
998 ASSERT(r == 0);
999 uv_run(loop, UV_RUN_DEFAULT);
1000 ASSERT(unlink_cb_count == 2);
1001
1002 r = uv_fs_rmdir(loop, &rmdir_req, "test_dir", rmdir_cb);
1003 ASSERT(r == 0);
1004 uv_run(loop, UV_RUN_DEFAULT);
1005 ASSERT(rmdir_cb_count == 1);
1006
1007 /* Cleanup */
1008 unlink("test_dir/file1");
1009 unlink("test_dir/file2");
1010 rmdir("test_dir");
1011
1012 MAKE_VALGRIND_HAPPY();
1013 return 0;
1014 }
1015
1016
TEST_IMPL(fs_async_sendfile)1017 TEST_IMPL(fs_async_sendfile) {
1018 int f, r;
1019 struct stat s1, s2;
1020
1021 loop = uv_default_loop();
1022
1023 /* Setup. */
1024 unlink("test_file");
1025 unlink("test_file2");
1026
1027 f = open("test_file", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
1028 ASSERT(f != -1);
1029
1030 r = write(f, "begin\n", 6);
1031 ASSERT(r == 6);
1032
1033 r = lseek(f, 65536, SEEK_CUR);
1034 ASSERT(r == 65542);
1035
1036 r = write(f, "end\n", 4);
1037 ASSERT(r != -1);
1038
1039 r = close(f);
1040 ASSERT(r == 0);
1041
1042 /* Test starts here. */
1043 r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR, 0, NULL);
1044 ASSERT(r >= 0);
1045 ASSERT(open_req1.result >= 0);
1046 uv_fs_req_cleanup(&open_req1);
1047
1048 r = uv_fs_open(NULL, &open_req2, "test_file2", O_WRONLY | O_CREAT,
1049 S_IWUSR | S_IRUSR, NULL);
1050 ASSERT(r >= 0);
1051 ASSERT(open_req2.result >= 0);
1052 uv_fs_req_cleanup(&open_req2);
1053
1054 r = uv_fs_sendfile(loop, &sendfile_req, open_req2.result, open_req1.result,
1055 0, 131072, sendfile_cb);
1056 ASSERT(r == 0);
1057 uv_run(loop, UV_RUN_DEFAULT);
1058
1059 ASSERT(sendfile_cb_count == 1);
1060
1061 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
1062 ASSERT(r == 0);
1063 uv_fs_req_cleanup(&close_req);
1064 r = uv_fs_close(NULL, &close_req, open_req2.result, NULL);
1065 ASSERT(r == 0);
1066 uv_fs_req_cleanup(&close_req);
1067
1068 stat("test_file", &s1);
1069 stat("test_file2", &s2);
1070 ASSERT(65546 == s2.st_size && s1.st_size == s2.st_size);
1071
1072 /* Cleanup. */
1073 unlink("test_file");
1074 unlink("test_file2");
1075
1076 MAKE_VALGRIND_HAPPY();
1077 return 0;
1078 }
1079
1080
TEST_IMPL(fs_mkdtemp)1081 TEST_IMPL(fs_mkdtemp) {
1082 int r;
1083 const char* path_template = "test_dir_XXXXXX";
1084
1085 loop = uv_default_loop();
1086
1087 r = uv_fs_mkdtemp(loop, &mkdtemp_req1, path_template, mkdtemp_cb);
1088 ASSERT(r == 0);
1089
1090 uv_run(loop, UV_RUN_DEFAULT);
1091 ASSERT(mkdtemp_cb_count == 1);
1092
1093 /* sync mkdtemp */
1094 r = uv_fs_mkdtemp(NULL, &mkdtemp_req2, path_template, NULL);
1095 ASSERT(r == 0);
1096 check_mkdtemp_result(&mkdtemp_req2);
1097
1098 /* mkdtemp return different values on subsequent calls */
1099 ASSERT(strcmp(mkdtemp_req1.path, mkdtemp_req2.path) != 0);
1100
1101 /* Cleanup */
1102 rmdir(mkdtemp_req1.path);
1103 rmdir(mkdtemp_req2.path);
1104 uv_fs_req_cleanup(&mkdtemp_req1);
1105 uv_fs_req_cleanup(&mkdtemp_req2);
1106
1107 MAKE_VALGRIND_HAPPY();
1108 return 0;
1109 }
1110
1111
TEST_IMPL(fs_fstat)1112 TEST_IMPL(fs_fstat) {
1113 int r;
1114 uv_fs_t req;
1115 uv_file file;
1116 uv_stat_t* s;
1117 #ifndef _WIN32
1118 struct stat t;
1119 #endif
1120
1121 /* Setup. */
1122 unlink("test_file");
1123
1124 loop = uv_default_loop();
1125
1126 r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT,
1127 S_IWUSR | S_IRUSR, NULL);
1128 ASSERT(r >= 0);
1129 ASSERT(req.result >= 0);
1130 file = req.result;
1131 uv_fs_req_cleanup(&req);
1132
1133 iov = uv_buf_init(test_buf, sizeof(test_buf));
1134 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
1135 ASSERT(r == sizeof(test_buf));
1136 ASSERT(req.result == sizeof(test_buf));
1137 uv_fs_req_cleanup(&req);
1138
1139 r = uv_fs_fstat(NULL, &req, file, NULL);
1140 ASSERT(r == 0);
1141 ASSERT(req.result == 0);
1142 s = req.ptr;
1143 ASSERT(s->st_size == sizeof(test_buf));
1144
1145 #ifndef _WIN32
1146 r = fstat(file, &t);
1147 ASSERT(r == 0);
1148
1149 ASSERT(s->st_dev == (uint64_t) t.st_dev);
1150 ASSERT(s->st_mode == (uint64_t) t.st_mode);
1151 ASSERT(s->st_nlink == (uint64_t) t.st_nlink);
1152 ASSERT(s->st_uid == (uint64_t) t.st_uid);
1153 ASSERT(s->st_gid == (uint64_t) t.st_gid);
1154 ASSERT(s->st_rdev == (uint64_t) t.st_rdev);
1155 ASSERT(s->st_ino == (uint64_t) t.st_ino);
1156 ASSERT(s->st_size == (uint64_t) t.st_size);
1157 ASSERT(s->st_blksize == (uint64_t) t.st_blksize);
1158 ASSERT(s->st_blocks == (uint64_t) t.st_blocks);
1159 #if defined(__APPLE__)
1160 ASSERT(s->st_atim.tv_sec == t.st_atimespec.tv_sec);
1161 ASSERT(s->st_atim.tv_nsec == t.st_atimespec.tv_nsec);
1162 ASSERT(s->st_mtim.tv_sec == t.st_mtimespec.tv_sec);
1163 ASSERT(s->st_mtim.tv_nsec == t.st_mtimespec.tv_nsec);
1164 ASSERT(s->st_ctim.tv_sec == t.st_ctimespec.tv_sec);
1165 ASSERT(s->st_ctim.tv_nsec == t.st_ctimespec.tv_nsec);
1166 ASSERT(s->st_birthtim.tv_sec == t.st_birthtimespec.tv_sec);
1167 ASSERT(s->st_birthtim.tv_nsec == t.st_birthtimespec.tv_nsec);
1168 ASSERT(s->st_flags == t.st_flags);
1169 ASSERT(s->st_gen == t.st_gen);
1170 #elif defined(_AIX)
1171 ASSERT(s->st_atim.tv_sec == t.st_atime);
1172 ASSERT(s->st_atim.tv_nsec == 0);
1173 ASSERT(s->st_mtim.tv_sec == t.st_mtime);
1174 ASSERT(s->st_mtim.tv_nsec == 0);
1175 ASSERT(s->st_ctim.tv_sec == t.st_ctime);
1176 ASSERT(s->st_ctim.tv_nsec == 0);
1177 #elif defined(__ANDROID__)
1178 ASSERT(s->st_atim.tv_sec == t.st_atime);
1179 ASSERT(s->st_atim.tv_nsec == t.st_atimensec);
1180 ASSERT(s->st_mtim.tv_sec == t.st_mtime);
1181 ASSERT(s->st_mtim.tv_nsec == t.st_mtimensec);
1182 ASSERT(s->st_ctim.tv_sec == t.st_ctime);
1183 ASSERT(s->st_ctim.tv_nsec == t.st_ctimensec);
1184 #elif defined(__sun) || \
1185 defined(__DragonFly__) || \
1186 defined(__FreeBSD__) || \
1187 defined(__OpenBSD__) || \
1188 defined(__NetBSD__) || \
1189 defined(_GNU_SOURCE) || \
1190 defined(_BSD_SOURCE) || \
1191 defined(_SVID_SOURCE) || \
1192 defined(_XOPEN_SOURCE) || \
1193 defined(_DEFAULT_SOURCE)
1194 ASSERT(s->st_atim.tv_sec == t.st_atim.tv_sec);
1195 ASSERT(s->st_atim.tv_nsec == t.st_atim.tv_nsec);
1196 ASSERT(s->st_mtim.tv_sec == t.st_mtim.tv_sec);
1197 ASSERT(s->st_mtim.tv_nsec == t.st_mtim.tv_nsec);
1198 ASSERT(s->st_ctim.tv_sec == t.st_ctim.tv_sec);
1199 ASSERT(s->st_ctim.tv_nsec == t.st_ctim.tv_nsec);
1200 # if defined(__FreeBSD__) || \
1201 defined(__NetBSD__)
1202 ASSERT(s->st_birthtim.tv_sec == t.st_birthtim.tv_sec);
1203 ASSERT(s->st_birthtim.tv_nsec == t.st_birthtim.tv_nsec);
1204 ASSERT(s->st_flags == t.st_flags);
1205 ASSERT(s->st_gen == t.st_gen);
1206 # endif
1207 #else
1208 ASSERT(s->st_atim.tv_sec == t.st_atime);
1209 ASSERT(s->st_atim.tv_nsec == 0);
1210 ASSERT(s->st_mtim.tv_sec == t.st_mtime);
1211 ASSERT(s->st_mtim.tv_nsec == 0);
1212 ASSERT(s->st_ctim.tv_sec == t.st_ctime);
1213 ASSERT(s->st_ctim.tv_nsec == 0);
1214 #endif
1215 #endif
1216
1217 uv_fs_req_cleanup(&req);
1218
1219 /* Now do the uv_fs_fstat call asynchronously */
1220 r = uv_fs_fstat(loop, &req, file, fstat_cb);
1221 ASSERT(r == 0);
1222 uv_run(loop, UV_RUN_DEFAULT);
1223 ASSERT(fstat_cb_count == 1);
1224
1225
1226 r = uv_fs_close(NULL, &req, file, NULL);
1227 ASSERT(r == 0);
1228 ASSERT(req.result == 0);
1229 uv_fs_req_cleanup(&req);
1230
1231 /*
1232 * Run the loop just to check we don't have make any extraneous uv_ref()
1233 * calls. This should drop out immediately.
1234 */
1235 uv_run(loop, UV_RUN_DEFAULT);
1236
1237 /* Cleanup. */
1238 unlink("test_file");
1239
1240 MAKE_VALGRIND_HAPPY();
1241 return 0;
1242 }
1243
1244
TEST_IMPL(fs_access)1245 TEST_IMPL(fs_access) {
1246 int r;
1247 uv_fs_t req;
1248 uv_file file;
1249
1250 /* Setup. */
1251 unlink("test_file");
1252 rmdir("test_dir");
1253
1254 loop = uv_default_loop();
1255
1256 /* File should not exist */
1257 r = uv_fs_access(NULL, &req, "test_file", F_OK, NULL);
1258 ASSERT(r < 0);
1259 ASSERT(req.result < 0);
1260 uv_fs_req_cleanup(&req);
1261
1262 /* File should not exist */
1263 r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb);
1264 ASSERT(r == 0);
1265 uv_run(loop, UV_RUN_DEFAULT);
1266 ASSERT(access_cb_count == 1);
1267 access_cb_count = 0; /* reset for the next test */
1268
1269 /* Create file */
1270 r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT,
1271 S_IWUSR | S_IRUSR, NULL);
1272 ASSERT(r >= 0);
1273 ASSERT(req.result >= 0);
1274 file = req.result;
1275 uv_fs_req_cleanup(&req);
1276
1277 /* File should exist */
1278 r = uv_fs_access(NULL, &req, "test_file", F_OK, NULL);
1279 ASSERT(r == 0);
1280 ASSERT(req.result == 0);
1281 uv_fs_req_cleanup(&req);
1282
1283 /* File should exist */
1284 r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb);
1285 ASSERT(r == 0);
1286 uv_run(loop, UV_RUN_DEFAULT);
1287 ASSERT(access_cb_count == 1);
1288 access_cb_count = 0; /* reset for the next test */
1289
1290 /* Close file */
1291 r = uv_fs_close(NULL, &req, file, NULL);
1292 ASSERT(r == 0);
1293 ASSERT(req.result == 0);
1294 uv_fs_req_cleanup(&req);
1295
1296 /* Directory access */
1297 r = uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL);
1298 ASSERT(r == 0);
1299 uv_fs_req_cleanup(&req);
1300
1301 r = uv_fs_access(NULL, &req, "test_dir", W_OK, NULL);
1302 ASSERT(r == 0);
1303 ASSERT(req.result == 0);
1304 uv_fs_req_cleanup(&req);
1305
1306 /*
1307 * Run the loop just to check we don't have make any extraneous uv_ref()
1308 * calls. This should drop out immediately.
1309 */
1310 uv_run(loop, UV_RUN_DEFAULT);
1311
1312 /* Cleanup. */
1313 unlink("test_file");
1314 rmdir("test_dir");
1315
1316 MAKE_VALGRIND_HAPPY();
1317 return 0;
1318 }
1319
1320
TEST_IMPL(fs_chmod)1321 TEST_IMPL(fs_chmod) {
1322 int r;
1323 uv_fs_t req;
1324 uv_file file;
1325
1326 /* Setup. */
1327 unlink("test_file");
1328
1329 loop = uv_default_loop();
1330
1331 r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT,
1332 S_IWUSR | S_IRUSR, NULL);
1333 ASSERT(r >= 0);
1334 ASSERT(req.result >= 0);
1335 file = req.result;
1336 uv_fs_req_cleanup(&req);
1337
1338 iov = uv_buf_init(test_buf, sizeof(test_buf));
1339 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
1340 ASSERT(r == sizeof(test_buf));
1341 ASSERT(req.result == sizeof(test_buf));
1342 uv_fs_req_cleanup(&req);
1343
1344 #ifndef _WIN32
1345 /* Make the file write-only */
1346 r = uv_fs_chmod(NULL, &req, "test_file", 0200, NULL);
1347 ASSERT(r == 0);
1348 ASSERT(req.result == 0);
1349 uv_fs_req_cleanup(&req);
1350
1351 check_permission("test_file", 0200);
1352 #endif
1353
1354 /* Make the file read-only */
1355 r = uv_fs_chmod(NULL, &req, "test_file", 0400, NULL);
1356 ASSERT(r == 0);
1357 ASSERT(req.result == 0);
1358 uv_fs_req_cleanup(&req);
1359
1360 check_permission("test_file", 0400);
1361
1362 /* Make the file read+write with sync uv_fs_fchmod */
1363 r = uv_fs_fchmod(NULL, &req, file, 0600, NULL);
1364 ASSERT(r == 0);
1365 ASSERT(req.result == 0);
1366 uv_fs_req_cleanup(&req);
1367
1368 check_permission("test_file", 0600);
1369
1370 #ifndef _WIN32
1371 /* async chmod */
1372 {
1373 static int mode = 0200;
1374 req.data = &mode;
1375 }
1376 r = uv_fs_chmod(loop, &req, "test_file", 0200, chmod_cb);
1377 ASSERT(r == 0);
1378 uv_run(loop, UV_RUN_DEFAULT);
1379 ASSERT(chmod_cb_count == 1);
1380 chmod_cb_count = 0; /* reset for the next test */
1381 #endif
1382
1383 /* async chmod */
1384 {
1385 static int mode = 0400;
1386 req.data = &mode;
1387 }
1388 r = uv_fs_chmod(loop, &req, "test_file", 0400, chmod_cb);
1389 ASSERT(r == 0);
1390 uv_run(loop, UV_RUN_DEFAULT);
1391 ASSERT(chmod_cb_count == 1);
1392
1393 /* async fchmod */
1394 {
1395 static int mode = 0600;
1396 req.data = &mode;
1397 }
1398 r = uv_fs_fchmod(loop, &req, file, 0600, fchmod_cb);
1399 ASSERT(r == 0);
1400 uv_run(loop, UV_RUN_DEFAULT);
1401 ASSERT(fchmod_cb_count == 1);
1402
1403 close(file);
1404
1405 /*
1406 * Run the loop just to check we don't have make any extraneous uv_ref()
1407 * calls. This should drop out immediately.
1408 */
1409 uv_run(loop, UV_RUN_DEFAULT);
1410
1411 /* Cleanup. */
1412 unlink("test_file");
1413
1414 MAKE_VALGRIND_HAPPY();
1415 return 0;
1416 }
1417
1418
TEST_IMPL(fs_unlink_readonly)1419 TEST_IMPL(fs_unlink_readonly) {
1420 int r;
1421 uv_fs_t req;
1422 uv_file file;
1423
1424 /* Setup. */
1425 unlink("test_file");
1426
1427 loop = uv_default_loop();
1428
1429 r = uv_fs_open(NULL,
1430 &req,
1431 "test_file",
1432 O_RDWR | O_CREAT,
1433 S_IWUSR | S_IRUSR,
1434 NULL);
1435 ASSERT(r >= 0);
1436 ASSERT(req.result >= 0);
1437 file = req.result;
1438 uv_fs_req_cleanup(&req);
1439
1440 iov = uv_buf_init(test_buf, sizeof(test_buf));
1441 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
1442 ASSERT(r == sizeof(test_buf));
1443 ASSERT(req.result == sizeof(test_buf));
1444 uv_fs_req_cleanup(&req);
1445
1446 close(file);
1447
1448 /* Make the file read-only */
1449 r = uv_fs_chmod(NULL, &req, "test_file", 0400, NULL);
1450 ASSERT(r == 0);
1451 ASSERT(req.result == 0);
1452 uv_fs_req_cleanup(&req);
1453
1454 check_permission("test_file", 0400);
1455
1456 /* Try to unlink the file */
1457 r = uv_fs_unlink(NULL, &req, "test_file", NULL);
1458 ASSERT(r == 0);
1459 ASSERT(req.result == 0);
1460 uv_fs_req_cleanup(&req);
1461
1462 /*
1463 * Run the loop just to check we don't have make any extraneous uv_ref()
1464 * calls. This should drop out immediately.
1465 */
1466 uv_run(loop, UV_RUN_DEFAULT);
1467
1468 /* Cleanup. */
1469 uv_fs_chmod(NULL, &req, "test_file", 0600, NULL);
1470 uv_fs_req_cleanup(&req);
1471 unlink("test_file");
1472
1473 MAKE_VALGRIND_HAPPY();
1474 return 0;
1475 }
1476
1477
TEST_IMPL(fs_chown)1478 TEST_IMPL(fs_chown) {
1479 int r;
1480 uv_fs_t req;
1481 uv_file file;
1482
1483 /* Setup. */
1484 unlink("test_file");
1485
1486 loop = uv_default_loop();
1487
1488 r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT,
1489 S_IWUSR | S_IRUSR, NULL);
1490 ASSERT(r >= 0);
1491 ASSERT(req.result >= 0);
1492 file = req.result;
1493 uv_fs_req_cleanup(&req);
1494
1495 /* sync chown */
1496 r = uv_fs_chown(NULL, &req, "test_file", -1, -1, NULL);
1497 ASSERT(r == 0);
1498 ASSERT(req.result == 0);
1499 uv_fs_req_cleanup(&req);
1500
1501 /* sync fchown */
1502 r = uv_fs_fchown(NULL, &req, file, -1, -1, NULL);
1503 ASSERT(r == 0);
1504 ASSERT(req.result == 0);
1505 uv_fs_req_cleanup(&req);
1506
1507 /* async chown */
1508 r = uv_fs_chown(loop, &req, "test_file", -1, -1, chown_cb);
1509 ASSERT(r == 0);
1510 uv_run(loop, UV_RUN_DEFAULT);
1511 ASSERT(chown_cb_count == 1);
1512
1513 #ifndef __MVS__
1514 /* chown to root (fail) */
1515 chown_cb_count = 0;
1516 r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb);
1517 ASSERT(r == 0);
1518 uv_run(loop, UV_RUN_DEFAULT);
1519 ASSERT(chown_cb_count == 1);
1520 #endif
1521
1522 /* async fchown */
1523 r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb);
1524 ASSERT(r == 0);
1525 uv_run(loop, UV_RUN_DEFAULT);
1526 ASSERT(fchown_cb_count == 1);
1527
1528 close(file);
1529
1530 /*
1531 * Run the loop just to check we don't have make any extraneous uv_ref()
1532 * calls. This should drop out immediately.
1533 */
1534 uv_run(loop, UV_RUN_DEFAULT);
1535
1536 /* Cleanup. */
1537 unlink("test_file");
1538
1539 MAKE_VALGRIND_HAPPY();
1540 return 0;
1541 }
1542
1543
TEST_IMPL(fs_link)1544 TEST_IMPL(fs_link) {
1545 int r;
1546 uv_fs_t req;
1547 uv_file file;
1548 uv_file link;
1549
1550 /* Setup. */
1551 unlink("test_file");
1552 unlink("test_file_link");
1553 unlink("test_file_link2");
1554
1555 loop = uv_default_loop();
1556
1557 r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT,
1558 S_IWUSR | S_IRUSR, NULL);
1559 ASSERT(r >= 0);
1560 ASSERT(req.result >= 0);
1561 file = req.result;
1562 uv_fs_req_cleanup(&req);
1563
1564 iov = uv_buf_init(test_buf, sizeof(test_buf));
1565 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
1566 ASSERT(r == sizeof(test_buf));
1567 ASSERT(req.result == sizeof(test_buf));
1568 uv_fs_req_cleanup(&req);
1569
1570 close(file);
1571
1572 /* sync link */
1573 r = uv_fs_link(NULL, &req, "test_file", "test_file_link", NULL);
1574 ASSERT(r == 0);
1575 ASSERT(req.result == 0);
1576 uv_fs_req_cleanup(&req);
1577
1578 r = uv_fs_open(NULL, &req, "test_file_link", O_RDWR, 0, NULL);
1579 ASSERT(r >= 0);
1580 ASSERT(req.result >= 0);
1581 link = req.result;
1582 uv_fs_req_cleanup(&req);
1583
1584 memset(buf, 0, sizeof(buf));
1585 iov = uv_buf_init(buf, sizeof(buf));
1586 r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL);
1587 ASSERT(r >= 0);
1588 ASSERT(req.result >= 0);
1589 ASSERT(strcmp(buf, test_buf) == 0);
1590
1591 close(link);
1592
1593 /* async link */
1594 r = uv_fs_link(loop, &req, "test_file", "test_file_link2", link_cb);
1595 ASSERT(r == 0);
1596 uv_run(loop, UV_RUN_DEFAULT);
1597 ASSERT(link_cb_count == 1);
1598
1599 r = uv_fs_open(NULL, &req, "test_file_link2", O_RDWR, 0, NULL);
1600 ASSERT(r >= 0);
1601 ASSERT(req.result >= 0);
1602 link = req.result;
1603 uv_fs_req_cleanup(&req);
1604
1605 memset(buf, 0, sizeof(buf));
1606 iov = uv_buf_init(buf, sizeof(buf));
1607 r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL);
1608 ASSERT(r >= 0);
1609 ASSERT(req.result >= 0);
1610 ASSERT(strcmp(buf, test_buf) == 0);
1611
1612 close(link);
1613
1614 /*
1615 * Run the loop just to check we don't have make any extraneous uv_ref()
1616 * calls. This should drop out immediately.
1617 */
1618 uv_run(loop, UV_RUN_DEFAULT);
1619
1620 /* Cleanup. */
1621 unlink("test_file");
1622 unlink("test_file_link");
1623 unlink("test_file_link2");
1624
1625 MAKE_VALGRIND_HAPPY();
1626 return 0;
1627 }
1628
1629
TEST_IMPL(fs_readlink)1630 TEST_IMPL(fs_readlink) {
1631 uv_fs_t req;
1632
1633 loop = uv_default_loop();
1634 ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb));
1635 ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
1636 ASSERT(dummy_cb_count == 1);
1637 ASSERT(req.ptr == NULL);
1638 ASSERT(req.result == UV_ENOENT);
1639 uv_fs_req_cleanup(&req);
1640
1641 ASSERT(UV_ENOENT == uv_fs_readlink(NULL, &req, "no_such_file", NULL));
1642 ASSERT(req.ptr == NULL);
1643 ASSERT(req.result == UV_ENOENT);
1644 uv_fs_req_cleanup(&req);
1645
1646 MAKE_VALGRIND_HAPPY();
1647 return 0;
1648 }
1649
1650
TEST_IMPL(fs_realpath)1651 TEST_IMPL(fs_realpath) {
1652 uv_fs_t req;
1653
1654 loop = uv_default_loop();
1655 ASSERT(0 == uv_fs_realpath(loop, &req, "no_such_file", dummy_cb));
1656 ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
1657 ASSERT(dummy_cb_count == 1);
1658 ASSERT(req.ptr == NULL);
1659 #ifdef _WIN32
1660 /*
1661 * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
1662 */
1663 if (req.result == UV_ENOSYS) {
1664 uv_fs_req_cleanup(&req);
1665 RETURN_SKIP("realpath is not supported on Windows XP");
1666 }
1667 #endif
1668 ASSERT(req.result == UV_ENOENT);
1669 uv_fs_req_cleanup(&req);
1670
1671 ASSERT(UV_ENOENT == uv_fs_realpath(NULL, &req, "no_such_file", NULL));
1672 ASSERT(req.ptr == NULL);
1673 ASSERT(req.result == UV_ENOENT);
1674 uv_fs_req_cleanup(&req);
1675
1676 MAKE_VALGRIND_HAPPY();
1677 return 0;
1678 }
1679
1680
TEST_IMPL(fs_symlink)1681 TEST_IMPL(fs_symlink) {
1682 int r;
1683 uv_fs_t req;
1684 uv_file file;
1685 uv_file link;
1686 char test_file_abs_buf[PATHMAX];
1687 size_t test_file_abs_size;
1688
1689 /* Setup. */
1690 unlink("test_file");
1691 unlink("test_file_symlink");
1692 unlink("test_file_symlink2");
1693 unlink("test_file_symlink_symlink");
1694 unlink("test_file_symlink2_symlink");
1695 test_file_abs_size = sizeof(test_file_abs_buf);
1696 #ifdef _WIN32
1697 uv_cwd(test_file_abs_buf, &test_file_abs_size);
1698 strcat(test_file_abs_buf, "\\test_file");
1699 #else
1700 uv_cwd(test_file_abs_buf, &test_file_abs_size);
1701 strcat(test_file_abs_buf, "/test_file");
1702 #endif
1703
1704 loop = uv_default_loop();
1705
1706 r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT,
1707 S_IWUSR | S_IRUSR, NULL);
1708 ASSERT(r >= 0);
1709 ASSERT(req.result >= 0);
1710 file = req.result;
1711 uv_fs_req_cleanup(&req);
1712
1713 iov = uv_buf_init(test_buf, sizeof(test_buf));
1714 r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
1715 ASSERT(r == sizeof(test_buf));
1716 ASSERT(req.result == sizeof(test_buf));
1717 uv_fs_req_cleanup(&req);
1718
1719 close(file);
1720
1721 /* sync symlink */
1722 r = uv_fs_symlink(NULL, &req, "test_file", "test_file_symlink", 0, NULL);
1723 #ifdef _WIN32
1724 if (r < 0) {
1725 if (r == UV_ENOTSUP) {
1726 /*
1727 * Windows doesn't support symlinks on older versions.
1728 * We just pass the test and bail out early if we get ENOTSUP.
1729 */
1730 return 0;
1731 } else if (r == UV_EPERM) {
1732 /*
1733 * Creating a symlink is only allowed when running elevated.
1734 * We pass the test and bail out early if we get UV_EPERM.
1735 */
1736 return 0;
1737 }
1738 }
1739 #endif
1740 ASSERT(r == 0);
1741 ASSERT(req.result == 0);
1742 uv_fs_req_cleanup(&req);
1743
1744 r = uv_fs_open(NULL, &req, "test_file_symlink", O_RDWR, 0, NULL);
1745 ASSERT(r >= 0);
1746 ASSERT(req.result >= 0);
1747 link = req.result;
1748 uv_fs_req_cleanup(&req);
1749
1750 memset(buf, 0, sizeof(buf));
1751 iov = uv_buf_init(buf, sizeof(buf));
1752 r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL);
1753 ASSERT(r >= 0);
1754 ASSERT(req.result >= 0);
1755 ASSERT(strcmp(buf, test_buf) == 0);
1756
1757 close(link);
1758
1759 r = uv_fs_symlink(NULL,
1760 &req,
1761 "test_file_symlink",
1762 "test_file_symlink_symlink",
1763 0,
1764 NULL);
1765 ASSERT(r == 0);
1766 uv_fs_req_cleanup(&req);
1767
1768 #if defined(__MSYS__)
1769 RETURN_SKIP("symlink reading is not supported on MSYS2");
1770 #endif
1771
1772 r = uv_fs_readlink(NULL, &req, "test_file_symlink_symlink", NULL);
1773 ASSERT(r == 0);
1774 ASSERT(strcmp(req.ptr, "test_file_symlink") == 0);
1775 uv_fs_req_cleanup(&req);
1776
1777 r = uv_fs_realpath(NULL, &req, "test_file_symlink_symlink", NULL);
1778 #ifdef _WIN32
1779 /*
1780 * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
1781 */
1782 if (r == UV_ENOSYS) {
1783 uv_fs_req_cleanup(&req);
1784 RETURN_SKIP("realpath is not supported on Windows XP");
1785 }
1786 #endif
1787 ASSERT(r == 0);
1788 #ifdef _WIN32
1789 ASSERT(stricmp(req.ptr, test_file_abs_buf) == 0);
1790 #else
1791 ASSERT(strcmp(req.ptr, test_file_abs_buf) == 0);
1792 #endif
1793 uv_fs_req_cleanup(&req);
1794
1795 /* async link */
1796 r = uv_fs_symlink(loop,
1797 &req,
1798 "test_file",
1799 "test_file_symlink2",
1800 0,
1801 symlink_cb);
1802 ASSERT(r == 0);
1803 uv_run(loop, UV_RUN_DEFAULT);
1804 ASSERT(symlink_cb_count == 1);
1805
1806 r = uv_fs_open(NULL, &req, "test_file_symlink2", O_RDWR, 0, NULL);
1807 ASSERT(r >= 0);
1808 ASSERT(req.result >= 0);
1809 link = req.result;
1810 uv_fs_req_cleanup(&req);
1811
1812 memset(buf, 0, sizeof(buf));
1813 iov = uv_buf_init(buf, sizeof(buf));
1814 r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL);
1815 ASSERT(r >= 0);
1816 ASSERT(req.result >= 0);
1817 ASSERT(strcmp(buf, test_buf) == 0);
1818
1819 close(link);
1820
1821 r = uv_fs_symlink(NULL,
1822 &req,
1823 "test_file_symlink2",
1824 "test_file_symlink2_symlink",
1825 0,
1826 NULL);
1827 ASSERT(r == 0);
1828 uv_fs_req_cleanup(&req);
1829
1830 r = uv_fs_readlink(loop, &req, "test_file_symlink2_symlink", readlink_cb);
1831 ASSERT(r == 0);
1832 uv_run(loop, UV_RUN_DEFAULT);
1833 ASSERT(readlink_cb_count == 1);
1834
1835 r = uv_fs_realpath(loop, &req, "test_file", realpath_cb);
1836 #ifdef _WIN32
1837 /*
1838 * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
1839 */
1840 if (r == UV_ENOSYS) {
1841 uv_fs_req_cleanup(&req);
1842 RETURN_SKIP("realpath is not supported on Windows XP");
1843 }
1844 #endif
1845 ASSERT(r == 0);
1846 uv_run(loop, UV_RUN_DEFAULT);
1847 ASSERT(realpath_cb_count == 1);
1848
1849 /*
1850 * Run the loop just to check we don't have make any extraneous uv_ref()
1851 * calls. This should drop out immediately.
1852 */
1853 uv_run(loop, UV_RUN_DEFAULT);
1854
1855 /* Cleanup. */
1856 unlink("test_file");
1857 unlink("test_file_symlink");
1858 unlink("test_file_symlink_symlink");
1859 unlink("test_file_symlink2");
1860 unlink("test_file_symlink2_symlink");
1861
1862 MAKE_VALGRIND_HAPPY();
1863 return 0;
1864 }
1865
1866
test_symlink_dir_impl(int type)1867 int test_symlink_dir_impl(int type) {
1868 uv_fs_t req;
1869 int r;
1870 char* test_dir;
1871 uv_dirent_t dent;
1872 static char test_dir_abs_buf[PATHMAX];
1873 size_t test_dir_abs_size;
1874
1875 /* set-up */
1876 unlink("test_dir/file1");
1877 unlink("test_dir/file2");
1878 rmdir("test_dir");
1879 rmdir("test_dir_symlink");
1880 test_dir_abs_size = sizeof(test_dir_abs_buf);
1881
1882 loop = uv_default_loop();
1883
1884 uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL);
1885 uv_fs_req_cleanup(&req);
1886
1887 #ifdef _WIN32
1888 strcpy(test_dir_abs_buf, "\\\\?\\");
1889 uv_cwd(test_dir_abs_buf + 4, &test_dir_abs_size);
1890 test_dir_abs_size += 4;
1891 strcat(test_dir_abs_buf, "\\test_dir\\");
1892 test_dir_abs_size += strlen("\\test_dir\\");
1893 test_dir = test_dir_abs_buf;
1894 #else
1895 uv_cwd(test_dir_abs_buf, &test_dir_abs_size);
1896 strcat(test_dir_abs_buf, "/test_dir");
1897 test_dir_abs_size += strlen("/test_dir");
1898 test_dir = "test_dir";
1899 #endif
1900
1901 r = uv_fs_symlink(NULL, &req, test_dir, "test_dir_symlink", type, NULL);
1902 if (type == UV_FS_SYMLINK_DIR && (r == UV_ENOTSUP || r == UV_EPERM)) {
1903 uv_fs_req_cleanup(&req);
1904 RETURN_SKIP("this version of Windows doesn't support unprivileged "
1905 "creation of directory symlinks");
1906 }
1907 fprintf(stderr, "r == %i\n", r);
1908 ASSERT(r == 0);
1909 ASSERT(req.result == 0);
1910 uv_fs_req_cleanup(&req);
1911
1912 r = uv_fs_stat(NULL, &req, "test_dir_symlink", NULL);
1913 ASSERT(r == 0);
1914 ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFDIR);
1915 uv_fs_req_cleanup(&req);
1916
1917 r = uv_fs_lstat(NULL, &req, "test_dir_symlink", NULL);
1918 ASSERT(r == 0);
1919 #if defined(__MSYS__)
1920 RETURN_SKIP("symlink reading is not supported on MSYS2");
1921 #endif
1922 ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFLNK);
1923 #ifdef _WIN32
1924 ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir + 4));
1925 #else
1926 ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir));
1927 #endif
1928 uv_fs_req_cleanup(&req);
1929
1930 r = uv_fs_readlink(NULL, &req, "test_dir_symlink", NULL);
1931 ASSERT(r == 0);
1932 #ifdef _WIN32
1933 ASSERT(strcmp(req.ptr, test_dir + 4) == 0);
1934 #else
1935 ASSERT(strcmp(req.ptr, test_dir) == 0);
1936 #endif
1937 uv_fs_req_cleanup(&req);
1938
1939 r = uv_fs_realpath(NULL, &req, "test_dir_symlink", NULL);
1940 #ifdef _WIN32
1941 /*
1942 * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
1943 */
1944 if (r == UV_ENOSYS) {
1945 uv_fs_req_cleanup(&req);
1946 RETURN_SKIP("realpath is not supported on Windows XP");
1947 }
1948 #endif
1949 ASSERT(r == 0);
1950 #ifdef _WIN32
1951 ASSERT(strlen(req.ptr) == test_dir_abs_size - 5);
1952 ASSERT(strnicmp(req.ptr, test_dir + 4, test_dir_abs_size - 5) == 0);
1953 #else
1954 ASSERT(strcmp(req.ptr, test_dir_abs_buf) == 0);
1955 #endif
1956 uv_fs_req_cleanup(&req);
1957
1958 r = uv_fs_open(NULL, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT,
1959 S_IWUSR | S_IRUSR, NULL);
1960 ASSERT(r >= 0);
1961 uv_fs_req_cleanup(&open_req1);
1962 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
1963 ASSERT(r == 0);
1964 uv_fs_req_cleanup(&close_req);
1965
1966 r = uv_fs_open(NULL, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT,
1967 S_IWUSR | S_IRUSR, NULL);
1968 ASSERT(r >= 0);
1969 uv_fs_req_cleanup(&open_req1);
1970 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
1971 ASSERT(r == 0);
1972 uv_fs_req_cleanup(&close_req);
1973
1974 r = uv_fs_scandir(NULL, &scandir_req, "test_dir_symlink", 0, NULL);
1975 ASSERT(r == 2);
1976 ASSERT(scandir_req.result == 2);
1977 ASSERT(scandir_req.ptr);
1978 while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
1979 ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
1980 assert_is_file_type(dent);
1981 }
1982 uv_fs_req_cleanup(&scandir_req);
1983 ASSERT(!scandir_req.ptr);
1984
1985 /* unlink will remove the directory symlink */
1986 r = uv_fs_unlink(NULL, &req, "test_dir_symlink", NULL);
1987 ASSERT(r == 0);
1988 uv_fs_req_cleanup(&req);
1989
1990 r = uv_fs_scandir(NULL, &scandir_req, "test_dir_symlink", 0, NULL);
1991 ASSERT(r == UV_ENOENT);
1992 uv_fs_req_cleanup(&scandir_req);
1993
1994 r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL);
1995 ASSERT(r == 2);
1996 ASSERT(scandir_req.result == 2);
1997 ASSERT(scandir_req.ptr);
1998 while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
1999 ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
2000 assert_is_file_type(dent);
2001 }
2002 uv_fs_req_cleanup(&scandir_req);
2003 ASSERT(!scandir_req.ptr);
2004
2005 /* clean-up */
2006 unlink("test_dir/file1");
2007 unlink("test_dir/file2");
2008 rmdir("test_dir");
2009 rmdir("test_dir_symlink");
2010
2011 MAKE_VALGRIND_HAPPY();
2012 return 0;
2013 }
2014
TEST_IMPL(fs_symlink_dir)2015 TEST_IMPL(fs_symlink_dir) {
2016 return test_symlink_dir_impl(UV_FS_SYMLINK_DIR);
2017 }
2018
TEST_IMPL(fs_symlink_junction)2019 TEST_IMPL(fs_symlink_junction) {
2020 return test_symlink_dir_impl(UV_FS_SYMLINK_JUNCTION);
2021 }
2022
2023 #ifdef _WIN32
TEST_IMPL(fs_non_symlink_reparse_point)2024 TEST_IMPL(fs_non_symlink_reparse_point) {
2025 uv_fs_t req;
2026 int r;
2027 HANDLE file_handle;
2028 REPARSE_GUID_DATA_BUFFER reparse_buffer;
2029 DWORD bytes_returned;
2030 uv_dirent_t dent;
2031
2032 /* set-up */
2033 unlink("test_dir/test_file");
2034 rmdir("test_dir");
2035
2036 loop = uv_default_loop();
2037
2038 uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL);
2039 uv_fs_req_cleanup(&req);
2040
2041 file_handle = CreateFile("test_dir/test_file",
2042 GENERIC_WRITE | FILE_WRITE_ATTRIBUTES,
2043 0,
2044 NULL,
2045 CREATE_ALWAYS,
2046 FILE_FLAG_OPEN_REPARSE_POINT |
2047 FILE_FLAG_BACKUP_SEMANTICS,
2048 NULL);
2049 ASSERT(file_handle != INVALID_HANDLE_VALUE);
2050
2051 memset(&reparse_buffer, 0, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE);
2052 reparse_buffer.ReparseTag = REPARSE_TAG;
2053 reparse_buffer.ReparseDataLength = 0;
2054 reparse_buffer.ReparseGuid = REPARSE_GUID;
2055
2056 r = DeviceIoControl(file_handle,
2057 FSCTL_SET_REPARSE_POINT,
2058 &reparse_buffer,
2059 REPARSE_GUID_DATA_BUFFER_HEADER_SIZE,
2060 NULL,
2061 0,
2062 &bytes_returned,
2063 NULL);
2064 ASSERT(r != 0);
2065
2066 CloseHandle(file_handle);
2067
2068 r = uv_fs_readlink(NULL, &req, "test_dir/test_file", NULL);
2069 ASSERT(r == UV_EINVAL && GetLastError() == ERROR_SYMLINK_NOT_SUPPORTED);
2070 uv_fs_req_cleanup(&req);
2071
2072 /*
2073 Placeholder tests for exercising the behavior fixed in issue #995.
2074 To run, update the path with the IP address of a Mac with the hard drive
2075 shared via SMB as "Macintosh HD".
2076
2077 r = uv_fs_stat(NULL, &req, "\\\\<mac_ip>\\Macintosh HD\\.DS_Store", NULL);
2078 ASSERT(r == 0);
2079 uv_fs_req_cleanup(&req);
2080
2081 r = uv_fs_lstat(NULL, &req, "\\\\<mac_ip>\\Macintosh HD\\.DS_Store", NULL);
2082 ASSERT(r == 0);
2083 uv_fs_req_cleanup(&req);
2084 */
2085
2086 /*
2087 uv_fs_stat and uv_fs_lstat can only work on non-symlink reparse
2088 points when a minifilter driver is registered which intercepts
2089 associated filesystem requests. Installing a driver is beyond
2090 the scope of this test.
2091
2092 r = uv_fs_stat(NULL, &req, "test_dir/test_file", NULL);
2093 ASSERT(r == 0);
2094 uv_fs_req_cleanup(&req);
2095
2096 r = uv_fs_lstat(NULL, &req, "test_dir/test_file", NULL);
2097 ASSERT(r == 0);
2098 uv_fs_req_cleanup(&req);
2099 */
2100
2101 r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL);
2102 ASSERT(r == 1);
2103 ASSERT(scandir_req.result == 1);
2104 ASSERT(scandir_req.ptr);
2105 while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
2106 ASSERT(strcmp(dent.name, "test_file") == 0);
2107 /* uv_fs_scandir incorrectly identifies non-symlink reparse points
2108 as links because it doesn't open the file and verify the reparse
2109 point tag. The PowerShell Get-ChildItem command shares this
2110 behavior, so it's reasonable to leave it as is. */
2111 ASSERT(dent.type == UV_DIRENT_LINK);
2112 }
2113 uv_fs_req_cleanup(&scandir_req);
2114 ASSERT(!scandir_req.ptr);
2115
2116 /* clean-up */
2117 unlink("test_dir/test_file");
2118 rmdir("test_dir");
2119
2120 MAKE_VALGRIND_HAPPY();
2121 return 0;
2122 }
2123 #endif
2124
2125
TEST_IMPL(fs_utime)2126 TEST_IMPL(fs_utime) {
2127 utime_check_t checkme;
2128 const char* path = "test_file";
2129 double atime;
2130 double mtime;
2131 uv_fs_t req;
2132 int r;
2133
2134 /* Setup. */
2135 loop = uv_default_loop();
2136 unlink(path);
2137 r = uv_fs_open(NULL, &req, path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, NULL);
2138 ASSERT(r >= 0);
2139 ASSERT(req.result >= 0);
2140 uv_fs_req_cleanup(&req);
2141 close(r);
2142
2143 atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
2144
2145 /*
2146 * Test sub-second timestamps only on Windows (assuming NTFS). Some other
2147 * platforms support sub-second timestamps, but that support is filesystem-
2148 * dependent. Notably OS X (HFS Plus) does NOT support sub-second timestamps.
2149 */
2150 #ifdef _WIN32
2151 mtime += 0.444; /* 1982-09-10 11:22:33.444 */
2152 #endif
2153
2154 r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL);
2155 ASSERT(r == 0);
2156 ASSERT(req.result == 0);
2157 uv_fs_req_cleanup(&req);
2158
2159 r = uv_fs_stat(NULL, &req, path, NULL);
2160 ASSERT(r == 0);
2161 ASSERT(req.result == 0);
2162 check_utime(path, atime, mtime);
2163 uv_fs_req_cleanup(&req);
2164
2165 atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
2166 checkme.path = path;
2167 checkme.atime = atime;
2168 checkme.mtime = mtime;
2169
2170 /* async utime */
2171 utime_req.data = &checkme;
2172 r = uv_fs_utime(loop, &utime_req, path, atime, mtime, utime_cb);
2173 ASSERT(r == 0);
2174 uv_run(loop, UV_RUN_DEFAULT);
2175 ASSERT(utime_cb_count == 1);
2176
2177 /* Cleanup. */
2178 unlink(path);
2179
2180 MAKE_VALGRIND_HAPPY();
2181 return 0;
2182 }
2183
2184
2185 #ifdef _WIN32
TEST_IMPL(fs_stat_root)2186 TEST_IMPL(fs_stat_root) {
2187 int r;
2188
2189 r = uv_fs_stat(NULL, &stat_req, "\\", NULL);
2190 ASSERT(r == 0);
2191
2192 r = uv_fs_stat(NULL, &stat_req, "..\\..\\..\\..\\..\\..\\..", NULL);
2193 ASSERT(r == 0);
2194
2195 r = uv_fs_stat(NULL, &stat_req, "..", NULL);
2196 ASSERT(r == 0);
2197
2198 r = uv_fs_stat(NULL, &stat_req, "..\\", NULL);
2199 ASSERT(r == 0);
2200
2201 /* stats the current directory on c: */
2202 r = uv_fs_stat(NULL, &stat_req, "c:", NULL);
2203 ASSERT(r == 0);
2204
2205 r = uv_fs_stat(NULL, &stat_req, "c:\\", NULL);
2206 ASSERT(r == 0);
2207
2208 r = uv_fs_stat(NULL, &stat_req, "\\\\?\\C:\\", NULL);
2209 ASSERT(r == 0);
2210
2211 MAKE_VALGRIND_HAPPY();
2212 return 0;
2213 }
2214 #endif
2215
2216
TEST_IMPL(fs_futime)2217 TEST_IMPL(fs_futime) {
2218 #if defined(_AIX) && !defined(_AIX71)
2219 RETURN_SKIP("futime is not implemented for AIX versions below 7.1");
2220 #else
2221 utime_check_t checkme;
2222 const char* path = "test_file";
2223 double atime;
2224 double mtime;
2225 uv_file file;
2226 uv_fs_t req;
2227 int r;
2228
2229 /* Setup. */
2230 loop = uv_default_loop();
2231 unlink(path);
2232 r = uv_fs_open(NULL, &req, path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, NULL);
2233 ASSERT(r >= 0);
2234 ASSERT(req.result >= 0);
2235 uv_fs_req_cleanup(&req);
2236 close(r);
2237
2238 atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
2239
2240 /*
2241 * Test sub-second timestamps only on Windows (assuming NTFS). Some other
2242 * platforms support sub-second timestamps, but that support is filesystem-
2243 * dependent. Notably OS X (HFS Plus) does NOT support sub-second timestamps.
2244 */
2245 #ifdef _WIN32
2246 mtime += 0.444; /* 1982-09-10 11:22:33.444 */
2247 #endif
2248
2249 r = uv_fs_open(NULL, &req, path, O_RDWR, 0, NULL);
2250 ASSERT(r >= 0);
2251 ASSERT(req.result >= 0);
2252 file = req.result; /* FIXME probably not how it's supposed to be used */
2253 uv_fs_req_cleanup(&req);
2254
2255 r = uv_fs_futime(NULL, &req, file, atime, mtime, NULL);
2256 #if defined(__CYGWIN__) || defined(__MSYS__)
2257 ASSERT(r == UV_ENOSYS);
2258 RETURN_SKIP("futime not supported on Cygwin");
2259 #else
2260 ASSERT(r == 0);
2261 ASSERT(req.result == 0);
2262 #endif
2263 uv_fs_req_cleanup(&req);
2264
2265 r = uv_fs_stat(NULL, &req, path, NULL);
2266 ASSERT(r == 0);
2267 ASSERT(req.result == 0);
2268 check_utime(path, atime, mtime);
2269 uv_fs_req_cleanup(&req);
2270
2271 atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
2272
2273 checkme.atime = atime;
2274 checkme.mtime = mtime;
2275 checkme.path = path;
2276
2277 /* async futime */
2278 futime_req.data = &checkme;
2279 r = uv_fs_futime(loop, &futime_req, file, atime, mtime, futime_cb);
2280 ASSERT(r == 0);
2281 uv_run(loop, UV_RUN_DEFAULT);
2282 ASSERT(futime_cb_count == 1);
2283
2284 /* Cleanup. */
2285 unlink(path);
2286
2287 MAKE_VALGRIND_HAPPY();
2288 return 0;
2289 #endif
2290 }
2291
2292
TEST_IMPL(fs_stat_missing_path)2293 TEST_IMPL(fs_stat_missing_path) {
2294 uv_fs_t req;
2295 int r;
2296
2297 loop = uv_default_loop();
2298
2299 r = uv_fs_stat(NULL, &req, "non_existent_file", NULL);
2300 ASSERT(r == UV_ENOENT);
2301 ASSERT(req.result == UV_ENOENT);
2302 uv_fs_req_cleanup(&req);
2303
2304 MAKE_VALGRIND_HAPPY();
2305 return 0;
2306 }
2307
2308
TEST_IMPL(fs_scandir_empty_dir)2309 TEST_IMPL(fs_scandir_empty_dir) {
2310 const char* path;
2311 uv_fs_t req;
2312 uv_dirent_t dent;
2313 int r;
2314
2315 path = "./empty_dir/";
2316 loop = uv_default_loop();
2317
2318 uv_fs_mkdir(NULL, &req, path, 0777, NULL);
2319 uv_fs_req_cleanup(&req);
2320
2321 /* Fill the req to ensure that required fields are cleaned up */
2322 memset(&req, 0xdb, sizeof(req));
2323
2324 r = uv_fs_scandir(NULL, &req, path, 0, NULL);
2325 ASSERT(r == 0);
2326 ASSERT(req.result == 0);
2327 ASSERT(req.ptr == NULL);
2328 ASSERT(UV_EOF == uv_fs_scandir_next(&req, &dent));
2329 uv_fs_req_cleanup(&req);
2330
2331 r = uv_fs_scandir(loop, &scandir_req, path, 0, empty_scandir_cb);
2332 ASSERT(r == 0);
2333
2334 ASSERT(scandir_cb_count == 0);
2335 uv_run(loop, UV_RUN_DEFAULT);
2336 ASSERT(scandir_cb_count == 1);
2337
2338 uv_fs_rmdir(NULL, &req, path, NULL);
2339 uv_fs_req_cleanup(&req);
2340
2341 MAKE_VALGRIND_HAPPY();
2342 return 0;
2343 }
2344
2345
TEST_IMPL(fs_scandir_non_existent_dir)2346 TEST_IMPL(fs_scandir_non_existent_dir) {
2347 const char* path;
2348 uv_fs_t req;
2349 uv_dirent_t dent;
2350 int r;
2351
2352 path = "./non_existent_dir/";
2353 loop = uv_default_loop();
2354
2355 uv_fs_rmdir(NULL, &req, path, NULL);
2356 uv_fs_req_cleanup(&req);
2357
2358 /* Fill the req to ensure that required fields are cleaned up */
2359 memset(&req, 0xdb, sizeof(req));
2360
2361 r = uv_fs_scandir(NULL, &req, path, 0, NULL);
2362 ASSERT(r == UV_ENOENT);
2363 ASSERT(req.result == UV_ENOENT);
2364 ASSERT(req.ptr == NULL);
2365 ASSERT(UV_ENOENT == uv_fs_scandir_next(&req, &dent));
2366 uv_fs_req_cleanup(&req);
2367
2368 r = uv_fs_scandir(loop, &scandir_req, path, 0, non_existent_scandir_cb);
2369 ASSERT(r == 0);
2370
2371 ASSERT(scandir_cb_count == 0);
2372 uv_run(loop, UV_RUN_DEFAULT);
2373 ASSERT(scandir_cb_count == 1);
2374
2375 MAKE_VALGRIND_HAPPY();
2376 return 0;
2377 }
2378
TEST_IMPL(fs_scandir_file)2379 TEST_IMPL(fs_scandir_file) {
2380 const char* path;
2381 int r;
2382
2383 path = "test/fixtures/empty_file";
2384 loop = uv_default_loop();
2385
2386 r = uv_fs_scandir(NULL, &scandir_req, path, 0, NULL);
2387 ASSERT(r == UV_ENOTDIR);
2388 uv_fs_req_cleanup(&scandir_req);
2389
2390 r = uv_fs_scandir(loop, &scandir_req, path, 0, file_scandir_cb);
2391 ASSERT(r == 0);
2392
2393 ASSERT(scandir_cb_count == 0);
2394 uv_run(loop, UV_RUN_DEFAULT);
2395 ASSERT(scandir_cb_count == 1);
2396
2397 MAKE_VALGRIND_HAPPY();
2398 return 0;
2399 }
2400
2401
TEST_IMPL(fs_open_dir)2402 TEST_IMPL(fs_open_dir) {
2403 const char* path;
2404 uv_fs_t req;
2405 int r, file;
2406
2407 path = ".";
2408 loop = uv_default_loop();
2409
2410 r = uv_fs_open(NULL, &req, path, O_RDONLY, 0, NULL);
2411 ASSERT(r >= 0);
2412 ASSERT(req.result >= 0);
2413 ASSERT(req.ptr == NULL);
2414 file = r;
2415 uv_fs_req_cleanup(&req);
2416
2417 r = uv_fs_close(NULL, &req, file, NULL);
2418 ASSERT(r == 0);
2419
2420 r = uv_fs_open(loop, &req, path, O_RDONLY, 0, open_cb_simple);
2421 ASSERT(r == 0);
2422
2423 ASSERT(open_cb_count == 0);
2424 uv_run(loop, UV_RUN_DEFAULT);
2425 ASSERT(open_cb_count == 1);
2426
2427 MAKE_VALGRIND_HAPPY();
2428 return 0;
2429 }
2430
2431
TEST_IMPL(fs_file_open_append)2432 TEST_IMPL(fs_file_open_append) {
2433 int r;
2434
2435 /* Setup. */
2436 unlink("test_file");
2437
2438 loop = uv_default_loop();
2439
2440 r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT,
2441 S_IWUSR | S_IRUSR, NULL);
2442 ASSERT(r >= 0);
2443 ASSERT(open_req1.result >= 0);
2444 uv_fs_req_cleanup(&open_req1);
2445
2446 iov = uv_buf_init(test_buf, sizeof(test_buf));
2447 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
2448 ASSERT(r >= 0);
2449 ASSERT(write_req.result >= 0);
2450 uv_fs_req_cleanup(&write_req);
2451
2452 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2453 ASSERT(r == 0);
2454 ASSERT(close_req.result == 0);
2455 uv_fs_req_cleanup(&close_req);
2456
2457 r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR | O_APPEND, 0, NULL);
2458 ASSERT(r >= 0);
2459 ASSERT(open_req1.result >= 0);
2460 uv_fs_req_cleanup(&open_req1);
2461
2462 iov = uv_buf_init(test_buf, sizeof(test_buf));
2463 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
2464 ASSERT(r >= 0);
2465 ASSERT(write_req.result >= 0);
2466 uv_fs_req_cleanup(&write_req);
2467
2468 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2469 ASSERT(r == 0);
2470 ASSERT(close_req.result == 0);
2471 uv_fs_req_cleanup(&close_req);
2472
2473 r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, S_IRUSR, NULL);
2474 ASSERT(r >= 0);
2475 ASSERT(open_req1.result >= 0);
2476 uv_fs_req_cleanup(&open_req1);
2477
2478 iov = uv_buf_init(buf, sizeof(buf));
2479 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
2480 printf("read = %d\n", r);
2481 ASSERT(r == 26);
2482 ASSERT(read_req.result == 26);
2483 ASSERT(memcmp(buf,
2484 "test-buffer\n\0test-buffer\n\0",
2485 sizeof("test-buffer\n\0test-buffer\n\0") - 1) == 0);
2486 uv_fs_req_cleanup(&read_req);
2487
2488 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2489 ASSERT(r == 0);
2490 ASSERT(close_req.result == 0);
2491 uv_fs_req_cleanup(&close_req);
2492
2493 /* Cleanup */
2494 unlink("test_file");
2495
2496 MAKE_VALGRIND_HAPPY();
2497 return 0;
2498 }
2499
2500
TEST_IMPL(fs_rename_to_existing_file)2501 TEST_IMPL(fs_rename_to_existing_file) {
2502 int r;
2503
2504 /* Setup. */
2505 unlink("test_file");
2506 unlink("test_file2");
2507
2508 loop = uv_default_loop();
2509
2510 r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT,
2511 S_IWUSR | S_IRUSR, NULL);
2512 ASSERT(r >= 0);
2513 ASSERT(open_req1.result >= 0);
2514 uv_fs_req_cleanup(&open_req1);
2515
2516 iov = uv_buf_init(test_buf, sizeof(test_buf));
2517 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
2518 ASSERT(r >= 0);
2519 ASSERT(write_req.result >= 0);
2520 uv_fs_req_cleanup(&write_req);
2521
2522 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2523 ASSERT(r == 0);
2524 ASSERT(close_req.result == 0);
2525 uv_fs_req_cleanup(&close_req);
2526
2527 r = uv_fs_open(NULL, &open_req1, "test_file2", O_WRONLY | O_CREAT,
2528 S_IWUSR | S_IRUSR, NULL);
2529 ASSERT(r >= 0);
2530 ASSERT(open_req1.result >= 0);
2531 uv_fs_req_cleanup(&open_req1);
2532
2533 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2534 ASSERT(r == 0);
2535 ASSERT(close_req.result == 0);
2536 uv_fs_req_cleanup(&close_req);
2537
2538 r = uv_fs_rename(NULL, &rename_req, "test_file", "test_file2", NULL);
2539 ASSERT(r == 0);
2540 ASSERT(rename_req.result == 0);
2541 uv_fs_req_cleanup(&rename_req);
2542
2543 r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDONLY, 0, NULL);
2544 ASSERT(r >= 0);
2545 ASSERT(open_req1.result >= 0);
2546 uv_fs_req_cleanup(&open_req1);
2547
2548 memset(buf, 0, sizeof(buf));
2549 iov = uv_buf_init(buf, sizeof(buf));
2550 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
2551 ASSERT(r >= 0);
2552 ASSERT(read_req.result >= 0);
2553 ASSERT(strcmp(buf, test_buf) == 0);
2554 uv_fs_req_cleanup(&read_req);
2555
2556 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2557 ASSERT(r == 0);
2558 ASSERT(close_req.result == 0);
2559 uv_fs_req_cleanup(&close_req);
2560
2561 /* Cleanup */
2562 unlink("test_file");
2563 unlink("test_file2");
2564
2565 MAKE_VALGRIND_HAPPY();
2566 return 0;
2567 }
2568
2569
TEST_IMPL(fs_read_file_eof)2570 TEST_IMPL(fs_read_file_eof) {
2571 #if defined(__CYGWIN__) || defined(__MSYS__)
2572 RETURN_SKIP("Cygwin pread at EOF may (incorrectly) return data!");
2573 #endif
2574 int r;
2575
2576 /* Setup. */
2577 unlink("test_file");
2578
2579 loop = uv_default_loop();
2580
2581 r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT,
2582 S_IWUSR | S_IRUSR, NULL);
2583 ASSERT(r >= 0);
2584 ASSERT(open_req1.result >= 0);
2585 uv_fs_req_cleanup(&open_req1);
2586
2587 iov = uv_buf_init(test_buf, sizeof(test_buf));
2588 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
2589 ASSERT(r >= 0);
2590 ASSERT(write_req.result >= 0);
2591 uv_fs_req_cleanup(&write_req);
2592
2593 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2594 ASSERT(r == 0);
2595 ASSERT(close_req.result == 0);
2596 uv_fs_req_cleanup(&close_req);
2597
2598 r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, 0, NULL);
2599 ASSERT(r >= 0);
2600 ASSERT(open_req1.result >= 0);
2601 uv_fs_req_cleanup(&open_req1);
2602
2603 memset(buf, 0, sizeof(buf));
2604 iov = uv_buf_init(buf, sizeof(buf));
2605 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL);
2606 ASSERT(r >= 0);
2607 ASSERT(read_req.result >= 0);
2608 ASSERT(strcmp(buf, test_buf) == 0);
2609 uv_fs_req_cleanup(&read_req);
2610
2611 iov = uv_buf_init(buf, sizeof(buf));
2612 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1,
2613 read_req.result, NULL);
2614 ASSERT(r == 0);
2615 ASSERT(read_req.result == 0);
2616 uv_fs_req_cleanup(&read_req);
2617
2618 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2619 ASSERT(r == 0);
2620 ASSERT(close_req.result == 0);
2621 uv_fs_req_cleanup(&close_req);
2622
2623 /* Cleanup */
2624 unlink("test_file");
2625
2626 MAKE_VALGRIND_HAPPY();
2627 return 0;
2628 }
2629
2630
TEST_IMPL(fs_write_multiple_bufs)2631 TEST_IMPL(fs_write_multiple_bufs) {
2632 uv_buf_t iovs[2];
2633 int r;
2634
2635 /* Setup. */
2636 unlink("test_file");
2637
2638 loop = uv_default_loop();
2639
2640 r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT,
2641 S_IWUSR | S_IRUSR, NULL);
2642 ASSERT(r >= 0);
2643 ASSERT(open_req1.result >= 0);
2644 uv_fs_req_cleanup(&open_req1);
2645
2646 iovs[0] = uv_buf_init(test_buf, sizeof(test_buf));
2647 iovs[1] = uv_buf_init(test_buf2, sizeof(test_buf2));
2648 r = uv_fs_write(NULL, &write_req, open_req1.result, iovs, 2, 0, NULL);
2649 ASSERT(r >= 0);
2650 ASSERT(write_req.result >= 0);
2651 uv_fs_req_cleanup(&write_req);
2652
2653 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2654 ASSERT(r == 0);
2655 ASSERT(close_req.result == 0);
2656 uv_fs_req_cleanup(&close_req);
2657
2658 r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, 0, NULL);
2659 ASSERT(r >= 0);
2660 ASSERT(open_req1.result >= 0);
2661 uv_fs_req_cleanup(&open_req1);
2662
2663 memset(buf, 0, sizeof(buf));
2664 memset(buf2, 0, sizeof(buf2));
2665 /* Read the strings back to separate buffers. */
2666 iovs[0] = uv_buf_init(buf, sizeof(test_buf));
2667 iovs[1] = uv_buf_init(buf2, sizeof(test_buf2));
2668 r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, 2, 0, NULL);
2669 ASSERT(r >= 0);
2670 ASSERT(read_req.result >= 0);
2671 ASSERT(strcmp(buf, test_buf) == 0);
2672 ASSERT(strcmp(buf2, test_buf2) == 0);
2673 uv_fs_req_cleanup(&read_req);
2674
2675 iov = uv_buf_init(buf, sizeof(buf));
2676 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1,
2677 read_req.result, NULL);
2678 ASSERT(r == 0);
2679 ASSERT(read_req.result == 0);
2680 uv_fs_req_cleanup(&read_req);
2681
2682 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2683 ASSERT(r == 0);
2684 ASSERT(close_req.result == 0);
2685 uv_fs_req_cleanup(&close_req);
2686
2687 /* Cleanup */
2688 unlink("test_file");
2689
2690 MAKE_VALGRIND_HAPPY();
2691 return 0;
2692 }
2693
2694
TEST_IMPL(fs_write_alotof_bufs)2695 TEST_IMPL(fs_write_alotof_bufs) {
2696 const size_t iovcount = 54321;
2697 uv_buf_t* iovs;
2698 char* buffer;
2699 size_t index;
2700 int r;
2701
2702 /* Setup. */
2703 unlink("test_file");
2704
2705 loop = uv_default_loop();
2706
2707 iovs = malloc(sizeof(*iovs) * iovcount);
2708 ASSERT(iovs != NULL);
2709
2710 r = uv_fs_open(NULL,
2711 &open_req1,
2712 "test_file",
2713 O_RDWR | O_CREAT,
2714 S_IWUSR | S_IRUSR,
2715 NULL);
2716 ASSERT(r >= 0);
2717 ASSERT(open_req1.result >= 0);
2718 uv_fs_req_cleanup(&open_req1);
2719
2720 for (index = 0; index < iovcount; ++index)
2721 iovs[index] = uv_buf_init(test_buf, sizeof(test_buf));
2722
2723 r = uv_fs_write(NULL,
2724 &write_req,
2725 open_req1.result,
2726 iovs,
2727 iovcount,
2728 -1,
2729 NULL);
2730 ASSERT(r >= 0);
2731 ASSERT((size_t)write_req.result == sizeof(test_buf) * iovcount);
2732 uv_fs_req_cleanup(&write_req);
2733
2734 /* Read the strings back to separate buffers. */
2735 buffer = malloc(sizeof(test_buf) * iovcount);
2736 ASSERT(buffer != NULL);
2737
2738 for (index = 0; index < iovcount; ++index)
2739 iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf),
2740 sizeof(test_buf));
2741
2742 r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, iovcount, 0, NULL);
2743 ASSERT(r >= 0);
2744 ASSERT((size_t)read_req.result == sizeof(test_buf) * iovcount);
2745
2746 for (index = 0; index < iovcount; ++index)
2747 ASSERT(strncmp(buffer + index * sizeof(test_buf),
2748 test_buf,
2749 sizeof(test_buf)) == 0);
2750
2751 uv_fs_req_cleanup(&read_req);
2752 free(buffer);
2753
2754 iov = uv_buf_init(buf, sizeof(buf));
2755 r = uv_fs_read(NULL,
2756 &read_req,
2757 open_req1.result,
2758 &iov,
2759 1,
2760 read_req.result,
2761 NULL);
2762 ASSERT(r == 0);
2763 ASSERT(read_req.result == 0);
2764 uv_fs_req_cleanup(&read_req);
2765
2766 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2767 ASSERT(r == 0);
2768 ASSERT(close_req.result == 0);
2769 uv_fs_req_cleanup(&close_req);
2770
2771 /* Cleanup */
2772 unlink("test_file");
2773 free(iovs);
2774
2775 MAKE_VALGRIND_HAPPY();
2776 return 0;
2777 }
2778
2779
TEST_IMPL(fs_write_alotof_bufs_with_offset)2780 TEST_IMPL(fs_write_alotof_bufs_with_offset) {
2781 const size_t iovcount = 54321;
2782 uv_buf_t* iovs;
2783 char* buffer;
2784 size_t index;
2785 int r;
2786 int64_t offset;
2787 char* filler = "0123456789";
2788 int filler_len = strlen(filler);
2789
2790 /* Setup. */
2791 unlink("test_file");
2792
2793 loop = uv_default_loop();
2794
2795 iovs = malloc(sizeof(*iovs) * iovcount);
2796 ASSERT(iovs != NULL);
2797
2798 r = uv_fs_open(NULL,
2799 &open_req1,
2800 "test_file",
2801 O_RDWR | O_CREAT,
2802 S_IWUSR | S_IRUSR,
2803 NULL);
2804 ASSERT(r >= 0);
2805 ASSERT(open_req1.result >= 0);
2806 uv_fs_req_cleanup(&open_req1);
2807
2808 iov = uv_buf_init(filler, filler_len);
2809 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL);
2810 ASSERT(r == filler_len);
2811 ASSERT(write_req.result == filler_len);
2812 uv_fs_req_cleanup(&write_req);
2813 offset = (int64_t)r;
2814
2815 for (index = 0; index < iovcount; ++index)
2816 iovs[index] = uv_buf_init(test_buf, sizeof(test_buf));
2817
2818 r = uv_fs_write(NULL,
2819 &write_req,
2820 open_req1.result,
2821 iovs,
2822 iovcount,
2823 offset,
2824 NULL);
2825 ASSERT(r >= 0);
2826 ASSERT((size_t)write_req.result == sizeof(test_buf) * iovcount);
2827 uv_fs_req_cleanup(&write_req);
2828
2829 /* Read the strings back to separate buffers. */
2830 buffer = malloc(sizeof(test_buf) * iovcount);
2831 ASSERT(buffer != NULL);
2832
2833 for (index = 0; index < iovcount; ++index)
2834 iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf),
2835 sizeof(test_buf));
2836
2837 r = uv_fs_read(NULL, &read_req, open_req1.result,
2838 iovs, iovcount, offset, NULL);
2839 ASSERT(r >= 0);
2840 ASSERT((size_t)read_req.result == sizeof(test_buf) * iovcount);
2841
2842 for (index = 0; index < iovcount; ++index)
2843 ASSERT(strncmp(buffer + index * sizeof(test_buf),
2844 test_buf,
2845 sizeof(test_buf)) == 0);
2846
2847 uv_fs_req_cleanup(&read_req);
2848 free(buffer);
2849
2850 r = uv_fs_stat(NULL, &stat_req, "test_file", NULL);
2851 ASSERT(r == 0);
2852 ASSERT((int64_t)((uv_stat_t*)stat_req.ptr)->st_size ==
2853 offset + (int64_t)(iovcount * sizeof(test_buf)));
2854 uv_fs_req_cleanup(&stat_req);
2855
2856 iov = uv_buf_init(buf, sizeof(buf));
2857 r = uv_fs_read(NULL,
2858 &read_req,
2859 open_req1.result,
2860 &iov,
2861 1,
2862 read_req.result + offset,
2863 NULL);
2864 ASSERT(r == 0);
2865 ASSERT(read_req.result == 0);
2866 uv_fs_req_cleanup(&read_req);
2867
2868 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2869 ASSERT(r == 0);
2870 ASSERT(close_req.result == 0);
2871 uv_fs_req_cleanup(&close_req);
2872
2873 /* Cleanup */
2874 unlink("test_file");
2875 free(iovs);
2876
2877 MAKE_VALGRIND_HAPPY();
2878 return 0;
2879 }
2880
2881
TEST_IMPL(fs_read_write_null_arguments)2882 TEST_IMPL(fs_read_write_null_arguments) {
2883 int r;
2884
2885 r = uv_fs_read(NULL, &read_req, 0, NULL, 0, -1, NULL);
2886 ASSERT(r == UV_EINVAL);
2887 uv_fs_req_cleanup(&read_req);
2888
2889 r = uv_fs_write(NULL, &write_req, 0, NULL, 0, -1, NULL);
2890 /* Validate some memory management on failed input validation before sending
2891 fs work to the thread pool. */
2892 ASSERT(r == UV_EINVAL);
2893 ASSERT(write_req.path == NULL);
2894 ASSERT(write_req.ptr == NULL);
2895 #ifdef _WIN32
2896 ASSERT(write_req.file.pathw == NULL);
2897 ASSERT(write_req.fs.info.new_pathw == NULL);
2898 ASSERT(write_req.fs.info.bufs == NULL);
2899 #else
2900 ASSERT(write_req.new_path == NULL);
2901 ASSERT(write_req.bufs == NULL);
2902 #endif
2903 uv_fs_req_cleanup(&write_req);
2904
2905 iov = uv_buf_init(NULL, 0);
2906 r = uv_fs_read(NULL, &read_req, 0, &iov, 0, -1, NULL);
2907 ASSERT(r == UV_EINVAL);
2908 uv_fs_req_cleanup(&read_req);
2909
2910 iov = uv_buf_init(NULL, 0);
2911 r = uv_fs_write(NULL, &write_req, 0, &iov, 0, -1, NULL);
2912 ASSERT(r == UV_EINVAL);
2913 uv_fs_req_cleanup(&write_req);
2914
2915 /* If the arguments are invalid, the loop should not be kept open */
2916 loop = uv_default_loop();
2917
2918 r = uv_fs_read(loop, &read_req, 0, NULL, 0, -1, fail_cb);
2919 ASSERT(r == UV_EINVAL);
2920 uv_run(loop, UV_RUN_DEFAULT);
2921 uv_fs_req_cleanup(&read_req);
2922
2923 r = uv_fs_write(loop, &write_req, 0, NULL, 0, -1, fail_cb);
2924 ASSERT(r == UV_EINVAL);
2925 uv_run(loop, UV_RUN_DEFAULT);
2926 uv_fs_req_cleanup(&write_req);
2927
2928 iov = uv_buf_init(NULL, 0);
2929 r = uv_fs_read(loop, &read_req, 0, &iov, 0, -1, fail_cb);
2930 ASSERT(r == UV_EINVAL);
2931 uv_run(loop, UV_RUN_DEFAULT);
2932 uv_fs_req_cleanup(&read_req);
2933
2934 iov = uv_buf_init(NULL, 0);
2935 r = uv_fs_write(loop, &write_req, 0, &iov, 0, -1, fail_cb);
2936 ASSERT(r == UV_EINVAL);
2937 uv_run(loop, UV_RUN_DEFAULT);
2938 uv_fs_req_cleanup(&write_req);
2939
2940 return 0;
2941 }
2942
2943
TEST_IMPL(get_osfhandle_valid_handle)2944 TEST_IMPL(get_osfhandle_valid_handle) {
2945 int r;
2946 uv_os_fd_t fd;
2947
2948 /* Setup. */
2949 unlink("test_file");
2950
2951 loop = uv_default_loop();
2952
2953 r = uv_fs_open(NULL,
2954 &open_req1,
2955 "test_file",
2956 O_RDWR | O_CREAT,
2957 S_IWUSR | S_IRUSR,
2958 NULL);
2959 ASSERT(r >= 0);
2960 ASSERT(open_req1.result >= 0);
2961 uv_fs_req_cleanup(&open_req1);
2962
2963 fd = uv_get_osfhandle(open_req1.result);
2964 #ifdef _WIN32
2965 ASSERT(fd != INVALID_HANDLE_VALUE);
2966 #else
2967 ASSERT(fd >= 0);
2968 #endif
2969
2970 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
2971 ASSERT(r == 0);
2972 ASSERT(close_req.result == 0);
2973 uv_fs_req_cleanup(&close_req);
2974
2975 /* Cleanup. */
2976 unlink("test_file");
2977
2978 MAKE_VALGRIND_HAPPY();
2979 return 0;
2980 }
2981
TEST_IMPL(fs_file_pos_after_op_with_offset)2982 TEST_IMPL(fs_file_pos_after_op_with_offset) {
2983 int r;
2984
2985 /* Setup. */
2986 unlink("test_file");
2987 loop = uv_default_loop();
2988
2989 r = uv_fs_open(loop,
2990 &open_req1,
2991 "test_file",
2992 O_RDWR | O_CREAT,
2993 S_IWUSR | S_IRUSR,
2994 NULL);
2995 ASSERT(r > 0);
2996 uv_fs_req_cleanup(&open_req1);
2997
2998 iov = uv_buf_init(test_buf, sizeof(test_buf));
2999 r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 0, NULL);
3000 ASSERT(r == sizeof(test_buf));
3001 ASSERT(lseek(open_req1.result, 0, SEEK_CUR) == 0);
3002 uv_fs_req_cleanup(&write_req);
3003
3004 iov = uv_buf_init(buf, sizeof(buf));
3005 r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 0, NULL);
3006 ASSERT(r == sizeof(test_buf));
3007 ASSERT(strcmp(buf, test_buf) == 0);
3008 ASSERT(lseek(open_req1.result, 0, SEEK_CUR) == 0);
3009 uv_fs_req_cleanup(&read_req);
3010
3011 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
3012 ASSERT(r == 0);
3013 uv_fs_req_cleanup(&close_req);
3014
3015 /* Cleanup */
3016 unlink("test_file");
3017
3018 MAKE_VALGRIND_HAPPY();
3019 return 0;
3020 }
3021
TEST_IMPL(fs_null_req)3022 TEST_IMPL(fs_null_req) {
3023 /* Verify that all fs functions return UV_EINVAL when the request is NULL. */
3024 int r;
3025
3026 r = uv_fs_open(NULL, NULL, NULL, 0, 0, NULL);
3027 ASSERT(r == UV_EINVAL);
3028
3029 r = uv_fs_close(NULL, NULL, 0, NULL);
3030 ASSERT(r == UV_EINVAL);
3031
3032 r = uv_fs_read(NULL, NULL, 0, NULL, 0, -1, NULL);
3033 ASSERT(r == UV_EINVAL);
3034
3035 r = uv_fs_write(NULL, NULL, 0, NULL, 0, -1, NULL);
3036 ASSERT(r == UV_EINVAL);
3037
3038 r = uv_fs_unlink(NULL, NULL, NULL, NULL);
3039 ASSERT(r == UV_EINVAL);
3040
3041 r = uv_fs_mkdir(NULL, NULL, NULL, 0, NULL);
3042 ASSERT(r == UV_EINVAL);
3043
3044 r = uv_fs_mkdtemp(NULL, NULL, NULL, NULL);
3045 ASSERT(r == UV_EINVAL);
3046
3047 r = uv_fs_rmdir(NULL, NULL, NULL, NULL);
3048 ASSERT(r == UV_EINVAL);
3049
3050 r = uv_fs_scandir(NULL, NULL, NULL, 0, NULL);
3051 ASSERT(r == UV_EINVAL);
3052
3053 r = uv_fs_link(NULL, NULL, NULL, NULL, NULL);
3054 ASSERT(r == UV_EINVAL);
3055
3056 r = uv_fs_symlink(NULL, NULL, NULL, NULL, 0, NULL);
3057 ASSERT(r == UV_EINVAL);
3058
3059 r = uv_fs_readlink(NULL, NULL, NULL, NULL);
3060 ASSERT(r == UV_EINVAL);
3061
3062 r = uv_fs_realpath(NULL, NULL, NULL, NULL);
3063 ASSERT(r == UV_EINVAL);
3064
3065 r = uv_fs_chown(NULL, NULL, NULL, 0, 0, NULL);
3066 ASSERT(r == UV_EINVAL);
3067
3068 r = uv_fs_fchown(NULL, NULL, 0, 0, 0, NULL);
3069 ASSERT(r == UV_EINVAL);
3070
3071 r = uv_fs_stat(NULL, NULL, NULL, NULL);
3072 ASSERT(r == UV_EINVAL);
3073
3074 r = uv_fs_lstat(NULL, NULL, NULL, NULL);
3075 ASSERT(r == UV_EINVAL);
3076
3077 r = uv_fs_fstat(NULL, NULL, 0, NULL);
3078 ASSERT(r == UV_EINVAL);
3079
3080 r = uv_fs_rename(NULL, NULL, NULL, NULL, NULL);
3081 ASSERT(r == UV_EINVAL);
3082
3083 r = uv_fs_fsync(NULL, NULL, 0, NULL);
3084 ASSERT(r == UV_EINVAL);
3085
3086 r = uv_fs_fdatasync(NULL, NULL, 0, NULL);
3087 ASSERT(r == UV_EINVAL);
3088
3089 r = uv_fs_ftruncate(NULL, NULL, 0, 0, NULL);
3090 ASSERT(r == UV_EINVAL);
3091
3092 r = uv_fs_copyfile(NULL, NULL, NULL, NULL, 0, NULL);
3093 ASSERT(r == UV_EINVAL);
3094
3095 r = uv_fs_sendfile(NULL, NULL, 0, 0, 0, 0, NULL);
3096 ASSERT(r == UV_EINVAL);
3097
3098 r = uv_fs_access(NULL, NULL, NULL, 0, NULL);
3099 ASSERT(r == UV_EINVAL);
3100
3101 r = uv_fs_chmod(NULL, NULL, NULL, 0, NULL);
3102 ASSERT(r == UV_EINVAL);
3103
3104 r = uv_fs_fchmod(NULL, NULL, 0, 0, NULL);
3105 ASSERT(r == UV_EINVAL);
3106
3107 r = uv_fs_utime(NULL, NULL, NULL, 0.0, 0.0, NULL);
3108 ASSERT(r == UV_EINVAL);
3109
3110 r = uv_fs_futime(NULL, NULL, 0, 0.0, 0.0, NULL);
3111 ASSERT(r == UV_EINVAL);
3112
3113 /* This should be a no-op. */
3114 uv_fs_req_cleanup(NULL);
3115
3116 return 0;
3117 }
3118
3119 #ifdef _WIN32
TEST_IMPL(fs_exclusive_sharing_mode)3120 TEST_IMPL(fs_exclusive_sharing_mode) {
3121 int r;
3122
3123 /* Setup. */
3124 unlink("test_file");
3125
3126 ASSERT(UV_FS_O_EXLOCK > 0);
3127
3128 r = uv_fs_open(NULL,
3129 &open_req1,
3130 "test_file",
3131 O_RDWR | O_CREAT | UV_FS_O_EXLOCK,
3132 S_IWUSR | S_IRUSR,
3133 NULL);
3134 ASSERT(r >= 0);
3135 ASSERT(open_req1.result >= 0);
3136 uv_fs_req_cleanup(&open_req1);
3137
3138 r = uv_fs_open(NULL,
3139 &open_req2,
3140 "test_file",
3141 O_RDONLY | UV_FS_O_EXLOCK,
3142 S_IWUSR | S_IRUSR,
3143 NULL);
3144 ASSERT(r < 0);
3145 ASSERT(open_req2.result < 0);
3146 uv_fs_req_cleanup(&open_req2);
3147
3148 r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
3149 ASSERT(r == 0);
3150 ASSERT(close_req.result == 0);
3151 uv_fs_req_cleanup(&close_req);
3152
3153 r = uv_fs_open(NULL,
3154 &open_req2,
3155 "test_file",
3156 O_RDONLY | UV_FS_O_EXLOCK,
3157 S_IWUSR | S_IRUSR,
3158 NULL);
3159 ASSERT(r >= 0);
3160 ASSERT(open_req2.result >= 0);
3161 uv_fs_req_cleanup(&open_req2);
3162
3163 r = uv_fs_close(NULL, &close_req, open_req2.result, NULL);
3164 ASSERT(r == 0);
3165 ASSERT(close_req.result == 0);
3166 uv_fs_req_cleanup(&close_req);
3167
3168 /* Cleanup */
3169 unlink("test_file");
3170
3171 MAKE_VALGRIND_HAPPY();
3172 return 0;
3173 }
3174 #endif
3175