Mercurial
comparison third_party/libuv/test/test-fs-open-flags.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 libuv project 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 #ifdef _WIN32 | |
| 23 | |
| 24 #include "uv.h" | |
| 25 #include "task.h" | |
| 26 | |
| 27 #if defined(__unix__) || defined(__POSIX__) || \ | |
| 28 defined(__APPLE__) || defined(__sun) || \ | |
| 29 defined(_AIX) || defined(__MVS__) || \ | |
| 30 defined(__HAIKU__) | |
| 31 # include <unistd.h> /* unlink, rmdir */ | |
| 32 #else | |
| 33 # include <direct.h> | |
| 34 # define rmdir _rmdir | |
| 35 # define unlink _unlink | |
| 36 #endif | |
| 37 | |
| 38 static int flags; | |
| 39 | |
| 40 static uv_fs_t close_req; | |
| 41 static uv_fs_t mkdir_req; | |
| 42 static uv_fs_t open_req; | |
| 43 static uv_fs_t read_req; | |
| 44 static uv_fs_t rmdir_req; | |
| 45 static uv_fs_t unlink_req; | |
| 46 static uv_fs_t write_req; | |
| 47 | |
| 48 static char buf[32]; | |
| 49 static uv_buf_t iov; | |
| 50 | |
| 51 /* Opening the same file multiple times quickly can cause uv_fs_open to fail | |
| 52 * with EBUSY, so append an identifier to the file name for each operation */ | |
| 53 static int sid = 0; | |
| 54 | |
| 55 #define FILE_NAME_SIZE 128 | |
| 56 static char absent_file[FILE_NAME_SIZE]; | |
| 57 static char empty_file[FILE_NAME_SIZE]; | |
| 58 static char dummy_file[FILE_NAME_SIZE]; | |
| 59 static char empty_dir[] = "empty_dir"; | |
| 60 | |
| 61 static void setup(void) { | |
| 62 int r; | |
| 63 | |
| 64 /* empty_dir */ | |
| 65 r = uv_fs_rmdir(NULL, &rmdir_req, empty_dir, NULL); | |
| 66 ASSERT(r == 0 || r == UV_ENOENT); | |
| 67 ASSERT(rmdir_req.result == 0 || rmdir_req.result == UV_ENOENT); | |
| 68 uv_fs_req_cleanup(&rmdir_req); | |
| 69 | |
| 70 r = uv_fs_mkdir(NULL, &mkdir_req, empty_dir, 0755, NULL); | |
| 71 ASSERT_OK(r); | |
| 72 ASSERT_OK(mkdir_req.result); | |
| 73 uv_fs_req_cleanup(&mkdir_req); | |
| 74 } | |
| 75 | |
| 76 static void refresh(void) { | |
| 77 int r; | |
| 78 | |
| 79 /* absent_file */ | |
| 80 sprintf(absent_file, "test_file_%d", sid++); | |
| 81 | |
| 82 r = uv_fs_unlink(NULL, &unlink_req, absent_file, NULL); | |
| 83 ASSERT(r == 0 || r == UV_ENOENT); | |
| 84 ASSERT(unlink_req.result == 0 || unlink_req.result == UV_ENOENT); | |
| 85 uv_fs_req_cleanup(&unlink_req); | |
| 86 | |
| 87 /* empty_file */ | |
| 88 sprintf(empty_file, "test_file_%d", sid++); | |
| 89 | |
| 90 r = uv_fs_open(NULL, &open_req, empty_file, | |
| 91 UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, NULL); | |
| 92 ASSERT_GE(r, 0); | |
| 93 ASSERT_GE(open_req.result, 0); | |
| 94 uv_fs_req_cleanup(&open_req); | |
| 95 | |
| 96 r = uv_fs_close(NULL, &close_req, open_req.result, NULL); | |
| 97 ASSERT_OK(r); | |
| 98 ASSERT_OK(close_req.result); | |
| 99 uv_fs_req_cleanup(&close_req); | |
| 100 | |
| 101 /* dummy_file */ | |
| 102 sprintf(dummy_file, "test_file_%d", sid++); | |
| 103 | |
| 104 r = uv_fs_open(NULL, &open_req, dummy_file, | |
| 105 UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, NULL); | |
| 106 ASSERT_GE(r, 0); | |
| 107 ASSERT_GE(open_req.result, 0); | |
| 108 uv_fs_req_cleanup(&open_req); | |
| 109 | |
| 110 iov = uv_buf_init("a", 1); | |
| 111 r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); | |
| 112 ASSERT_EQ(1, r); | |
| 113 ASSERT_EQ(1, write_req.result); | |
| 114 uv_fs_req_cleanup(&write_req); | |
| 115 | |
| 116 r = uv_fs_close(NULL, &close_req, open_req.result, NULL); | |
| 117 ASSERT_OK(r); | |
| 118 ASSERT_OK(close_req.result); | |
| 119 uv_fs_req_cleanup(&close_req); | |
| 120 } | |
| 121 | |
| 122 static void cleanup(void) { | |
| 123 unlink(absent_file); | |
| 124 unlink(empty_file); | |
| 125 unlink(dummy_file); | |
| 126 } | |
| 127 | |
| 128 static void openFail(char *file, int error) { | |
| 129 int r; | |
| 130 | |
| 131 refresh(); | |
| 132 | |
| 133 r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL); | |
| 134 ASSERT_EQ(r, error); | |
| 135 ASSERT_EQ(open_req.result, error); | |
| 136 uv_fs_req_cleanup(&open_req); | |
| 137 | |
| 138 /* Ensure the first call does not create the file */ | |
| 139 r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL); | |
| 140 ASSERT_EQ(r, error); | |
| 141 ASSERT_EQ(open_req.result, error); | |
| 142 uv_fs_req_cleanup(&open_req); | |
| 143 | |
| 144 cleanup(); | |
| 145 } | |
| 146 | |
| 147 static void refreshOpen(char *file) { | |
| 148 int r; | |
| 149 | |
| 150 refresh(); | |
| 151 | |
| 152 r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL); | |
| 153 ASSERT_GE(r, 0); | |
| 154 ASSERT_GE(open_req.result, 0); | |
| 155 uv_fs_req_cleanup(&open_req); | |
| 156 } | |
| 157 | |
| 158 static void writeExpect(char *file, char *expected, int size) { | |
| 159 int r; | |
| 160 | |
| 161 refreshOpen(file); | |
| 162 | |
| 163 iov = uv_buf_init("b", 1); | |
| 164 r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); | |
| 165 ASSERT_EQ(1, r); | |
| 166 ASSERT_EQ(1, write_req.result); | |
| 167 uv_fs_req_cleanup(&write_req); | |
| 168 | |
| 169 iov = uv_buf_init("c", 1); | |
| 170 r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); | |
| 171 ASSERT_EQ(1, r); | |
| 172 ASSERT_EQ(1, write_req.result); | |
| 173 uv_fs_req_cleanup(&write_req); | |
| 174 | |
| 175 r = uv_fs_close(NULL, &close_req, open_req.result, NULL); | |
| 176 ASSERT_OK(r); | |
| 177 ASSERT_OK(close_req.result); | |
| 178 uv_fs_req_cleanup(&close_req); | |
| 179 | |
| 180 /* Check contents */ | |
| 181 r = uv_fs_open(NULL, &open_req, file, UV_FS_O_RDONLY, S_IWUSR | S_IRUSR, NULL); | |
| 182 ASSERT_GE(r, 0); | |
| 183 ASSERT_GE(open_req.result, 0); | |
| 184 uv_fs_req_cleanup(&open_req); | |
| 185 | |
| 186 iov = uv_buf_init(buf, sizeof(buf)); | |
| 187 r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL); | |
| 188 ASSERT_EQ(r, size); | |
| 189 ASSERT_EQ(read_req.result, size); | |
| 190 ASSERT_OK(strncmp(buf, expected, size)); | |
| 191 uv_fs_req_cleanup(&read_req); | |
| 192 | |
| 193 r = uv_fs_close(NULL, &close_req, open_req.result, NULL); | |
| 194 ASSERT_OK(r); | |
| 195 ASSERT_OK(close_req.result); | |
| 196 uv_fs_req_cleanup(&close_req); | |
| 197 | |
| 198 cleanup(); | |
| 199 } | |
| 200 | |
| 201 static void writeFail(char *file, int error) { | |
| 202 int r; | |
| 203 | |
| 204 refreshOpen(file); | |
| 205 | |
| 206 iov = uv_buf_init("z", 1); | |
| 207 r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); | |
| 208 ASSERT_EQ(r, error); | |
| 209 ASSERT_EQ(write_req.result, error); | |
| 210 uv_fs_req_cleanup(&write_req); | |
| 211 | |
| 212 iov = uv_buf_init("z", 1); | |
| 213 r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); | |
| 214 ASSERT_EQ(r, error); | |
| 215 ASSERT_EQ(write_req.result, error); | |
| 216 uv_fs_req_cleanup(&write_req); | |
| 217 | |
| 218 r = uv_fs_close(NULL, &close_req, open_req.result, NULL); | |
| 219 ASSERT_OK(r); | |
| 220 ASSERT_OK(close_req.result); | |
| 221 uv_fs_req_cleanup(&close_req); | |
| 222 | |
| 223 cleanup(); | |
| 224 } | |
| 225 | |
| 226 static void readExpect(char *file, char *expected, int size) { | |
| 227 int r; | |
| 228 | |
| 229 refreshOpen(file); | |
| 230 | |
| 231 iov = uv_buf_init(buf, sizeof(buf)); | |
| 232 r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL); | |
| 233 ASSERT_EQ(r, size); | |
| 234 ASSERT_EQ(read_req.result, size); | |
| 235 ASSERT_OK(strncmp(buf, expected, size)); | |
| 236 uv_fs_req_cleanup(&read_req); | |
| 237 | |
| 238 r = uv_fs_close(NULL, &close_req, open_req.result, NULL); | |
| 239 ASSERT_OK(r); | |
| 240 ASSERT_OK(close_req.result); | |
| 241 uv_fs_req_cleanup(&close_req); | |
| 242 | |
| 243 cleanup(); | |
| 244 } | |
| 245 | |
| 246 static void readFail(char *file, int error) { | |
| 247 int r; | |
| 248 | |
| 249 refreshOpen(file); | |
| 250 | |
| 251 iov = uv_buf_init(buf, sizeof(buf)); | |
| 252 r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL); | |
| 253 ASSERT_EQ(r, error); | |
| 254 ASSERT_EQ(read_req.result, error); | |
| 255 uv_fs_req_cleanup(&read_req); | |
| 256 | |
| 257 iov = uv_buf_init(buf, sizeof(buf)); | |
| 258 r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL); | |
| 259 ASSERT_EQ(r, error); | |
| 260 ASSERT_EQ(read_req.result, error); | |
| 261 uv_fs_req_cleanup(&read_req); | |
| 262 | |
| 263 r = uv_fs_close(NULL, &close_req, open_req.result, NULL); | |
| 264 ASSERT_OK(r); | |
| 265 ASSERT_OK(close_req.result); | |
| 266 uv_fs_req_cleanup(&close_req); | |
| 267 | |
| 268 cleanup(); | |
| 269 } | |
| 270 | |
| 271 static void fs_open_flags(int add_flags) { | |
| 272 /* Follow the order from | |
| 273 * https://github.com/nodejs/node/blob/1a96abe849/lib/internal/fs/utils.js#L329-L354 | |
| 274 */ | |
| 275 | |
| 276 /* r */ | |
| 277 flags = add_flags | UV_FS_O_RDONLY; | |
| 278 openFail(absent_file, UV_ENOENT); | |
| 279 writeFail(empty_file, UV_EBADF); | |
| 280 readExpect(empty_file, "", 0); | |
| 281 writeFail(dummy_file, UV_EBADF); | |
| 282 readExpect(dummy_file, "a", 1); | |
| 283 writeFail(empty_dir, UV_EBADF); | |
| 284 readFail(empty_dir, UV_EISDIR); | |
| 285 | |
| 286 /* rs */ | |
| 287 flags = add_flags | UV_FS_O_RDONLY | UV_FS_O_SYNC; | |
| 288 openFail(absent_file, UV_ENOENT); | |
| 289 writeFail(empty_file, UV_EBADF); | |
| 290 readExpect(empty_file, "", 0); | |
| 291 writeFail(dummy_file, UV_EBADF); | |
| 292 readExpect(dummy_file, "a", 1); | |
| 293 writeFail(empty_dir, UV_EBADF); | |
| 294 readFail(empty_dir, UV_EISDIR); | |
| 295 | |
| 296 /* r+ */ | |
| 297 flags = add_flags | UV_FS_O_RDWR; | |
| 298 openFail(absent_file, UV_ENOENT); | |
| 299 writeExpect(empty_file, "bc", 2); | |
| 300 readExpect(empty_file, "", 0); | |
| 301 writeExpect(dummy_file, "bc", 2); | |
| 302 readExpect(dummy_file, "a", 1); | |
| 303 writeFail(empty_dir, UV_EISDIR); | |
| 304 readFail(empty_dir, UV_EISDIR); | |
| 305 | |
| 306 /* rs+ */ | |
| 307 flags = add_flags | UV_FS_O_RDWR | UV_FS_O_SYNC; | |
| 308 openFail(absent_file, UV_ENOENT); | |
| 309 writeExpect(empty_file, "bc", 2); | |
| 310 readExpect(empty_file, "", 0); | |
| 311 writeExpect(dummy_file, "bc", 2); | |
| 312 readExpect(dummy_file, "a", 1); | |
| 313 writeFail(empty_dir, UV_EISDIR); | |
| 314 readFail(empty_dir, UV_EISDIR); | |
| 315 | |
| 316 /* w */ | |
| 317 flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY; | |
| 318 writeExpect(absent_file, "bc", 2); | |
| 319 readFail(absent_file, UV_EBADF); | |
| 320 writeExpect(empty_file, "bc", 2); | |
| 321 readFail(empty_file, UV_EBADF); | |
| 322 writeExpect(dummy_file, "bc", 2); | |
| 323 readFail(dummy_file, UV_EBADF); | |
| 324 openFail(empty_dir, UV_EISDIR); | |
| 325 | |
| 326 /* wx */ | |
| 327 flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY | | |
| 328 UV_FS_O_EXCL; | |
| 329 writeExpect(absent_file, "bc", 2); | |
| 330 readFail(absent_file, UV_EBADF); | |
| 331 openFail(empty_file, UV_EEXIST); | |
| 332 openFail(dummy_file, UV_EEXIST); | |
| 333 openFail(empty_dir, UV_EEXIST); | |
| 334 | |
| 335 /* w+ */ | |
| 336 flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_RDWR; | |
| 337 writeExpect(absent_file, "bc", 2); | |
| 338 readExpect(absent_file, "", 0); | |
| 339 writeExpect(empty_file, "bc", 2); | |
| 340 readExpect(empty_file, "", 0); | |
| 341 writeExpect(dummy_file, "bc", 2); | |
| 342 readExpect(dummy_file, "", 0); | |
| 343 openFail(empty_dir, UV_EISDIR); | |
| 344 | |
| 345 /* wx+ */ | |
| 346 flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_RDWR | | |
| 347 UV_FS_O_EXCL; | |
| 348 writeExpect(absent_file, "bc", 2); | |
| 349 readExpect(absent_file, "", 0); | |
| 350 openFail(empty_file, UV_EEXIST); | |
| 351 openFail(dummy_file, UV_EEXIST); | |
| 352 openFail(empty_dir, UV_EEXIST); | |
| 353 | |
| 354 /* a */ | |
| 355 flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY; | |
| 356 writeExpect(absent_file, "bc", 2); | |
| 357 readFail(absent_file, UV_EBADF); | |
| 358 writeExpect(empty_file, "bc", 2); | |
| 359 readFail(empty_file, UV_EBADF); | |
| 360 writeExpect(dummy_file, "abc", 3); | |
| 361 readFail(dummy_file, UV_EBADF); | |
| 362 writeFail(empty_dir, UV_EISDIR); | |
| 363 readFail(empty_dir, UV_EBADF); | |
| 364 | |
| 365 /* ax */ | |
| 366 flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY | | |
| 367 UV_FS_O_EXCL; | |
| 368 writeExpect(absent_file, "bc", 2); | |
| 369 readFail(absent_file, UV_EBADF); | |
| 370 openFail(empty_file, UV_EEXIST); | |
| 371 openFail(dummy_file, UV_EEXIST); | |
| 372 openFail(empty_dir, UV_EEXIST); | |
| 373 | |
| 374 /* as */ | |
| 375 flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY | | |
| 376 UV_FS_O_SYNC; | |
| 377 writeExpect(absent_file, "bc", 2); | |
| 378 readFail(absent_file, UV_EBADF); | |
| 379 writeExpect(empty_file, "bc", 2); | |
| 380 readFail(empty_file, UV_EBADF); | |
| 381 writeExpect(dummy_file, "abc", 3); | |
| 382 readFail(dummy_file, UV_EBADF); | |
| 383 writeFail(empty_dir, UV_EISDIR); | |
| 384 readFail(empty_dir, UV_EBADF); | |
| 385 | |
| 386 /* a+ */ | |
| 387 flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR; | |
| 388 writeExpect(absent_file, "bc", 2); | |
| 389 readExpect(absent_file, "", 0); | |
| 390 writeExpect(empty_file, "bc", 2); | |
| 391 readExpect(empty_file, "", 0); | |
| 392 writeExpect(dummy_file, "abc", 3); | |
| 393 readExpect(dummy_file, "a", 1); | |
| 394 writeFail(empty_dir, UV_EISDIR); | |
| 395 readFail(empty_dir, UV_EISDIR); | |
| 396 | |
| 397 /* ax+ */ | |
| 398 flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR | | |
| 399 UV_FS_O_EXCL; | |
| 400 writeExpect(absent_file, "bc", 2); | |
| 401 readExpect(absent_file, "", 0); | |
| 402 openFail(empty_file, UV_EEXIST); | |
| 403 openFail(dummy_file, UV_EEXIST); | |
| 404 openFail(empty_dir, UV_EEXIST); | |
| 405 | |
| 406 /* as+ */ | |
| 407 flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR | | |
| 408 UV_FS_O_SYNC; | |
| 409 writeExpect(absent_file, "bc", 2); | |
| 410 readExpect(absent_file, "", 0); | |
| 411 writeExpect(empty_file, "bc", 2); | |
| 412 readExpect(empty_file, "", 0); | |
| 413 writeExpect(dummy_file, "abc", 3); | |
| 414 readExpect(dummy_file, "a", 1); | |
| 415 writeFail(empty_dir, UV_EISDIR); | |
| 416 readFail(empty_dir, UV_EISDIR); | |
| 417 } | |
| 418 TEST_IMPL(fs_open_flags) { | |
| 419 setup(); | |
| 420 | |
| 421 fs_open_flags(0); | |
| 422 fs_open_flags(UV_FS_O_FILEMAP); | |
| 423 | |
| 424 /* Cleanup. */ | |
| 425 rmdir(empty_dir); | |
| 426 | |
| 427 MAKE_VALGRIND_HAPPY(uv_default_loop()); | |
| 428 return 0; | |
| 429 } | |
| 430 | |
| 431 #else | |
| 432 | |
| 433 typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ | |
| 434 | |
| 435 #endif /* ifndef _WIN32 */ |