Mercurial
comparison third_party/libuv/test/test-fs.c @ 160:948de3f54cea
[ThirdParty] Added libuv
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 14 Jan 2026 19:39:52 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 159:05cf9467a1c3 | 160:948de3f54cea |
|---|---|
| 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 |