testfile.c (23420B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "nspr.h" 7 #include "prpriv.h" 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #ifdef WIN32 13 # include <windows.h> 14 # include <process.h> 15 #endif 16 #if defined(_PR_PTHREADS) 17 # include <pthread.h> 18 #endif 19 20 #if defined(XP_UNIX) 21 # include <unistd.h> 22 #endif 23 24 static int _debug_on = 0; 25 26 #ifdef WINCE 27 # define setbuf(x, y) 28 #endif 29 30 #ifdef XP_WIN 31 # define mode_t int 32 #endif 33 34 #define DPRINTF(arg) \ 35 if (_debug_on) printf arg 36 37 PRLock* lock; 38 PRMonitor* mon; 39 PRInt32 count; 40 int thread_count; 41 42 #define BUF_DATA_SIZE 256 * 1024 43 44 #define NUM_RDWR_THREADS 10 45 #define NUM_DIRTEST_THREADS 4 46 #define CHUNK_SIZE 512 47 48 typedef struct buffer { 49 char data[BUF_DATA_SIZE]; 50 } buffer; 51 52 typedef struct File_Rdwr_Param { 53 char* pathname; 54 char* buf; 55 int offset; 56 int len; 57 } File_Rdwr_Param; 58 59 #ifdef XP_PC 60 char* TEST_DIR = "C:\\temp\\prdir"; 61 char* FILE_NAME = "pr_testfile"; 62 char* HIDDEN_FILE_NAME = "hidden_pr_testfile"; 63 #else 64 char* TEST_DIR = "./tmp-testfile_dir"; 65 char* FILE_NAME = "pr_testfile"; 66 char* HIDDEN_FILE_NAME = ".hidden_pr_testfile"; 67 #endif 68 buffer *in_buf, *out_buf; 69 char pathname[256], renamename[256]; 70 #ifdef WINCE 71 WCHAR wPathname[256]; 72 #endif 73 #define TMPDIR_LEN 64 74 char testdir[TMPDIR_LEN]; 75 static PRInt32 PR_CALLBACK DirTest(void* argunused); 76 PRInt32 dirtest_failed = 0; 77 78 #if defined(_PR_PTHREADS) 79 typedef void* (*nativeStartType)(void*); 80 #elif defined(WIN32) 81 typedef unsigned(__stdcall* nativeStartType)(void*); 82 #else 83 typedef void (*nativeStartType)(void*); 84 #endif 85 86 #if defined(_PR_PTHREADS) 87 static void* PR_CALLBACK DirTestWrapper(void* argunused) { 88 (void)DirTest(argunused); 89 return NULL; 90 } 91 #elif defined(WIN32) 92 static unsigned __stdcall DirTestWrapper(void* argunused) { 93 (void)DirTest(argunused); 94 return 0; 95 } 96 #else 97 static void PR_CALLBACK DirTestWrapper(void* argunused) { 98 (void)DirTest(argunused); 99 } 100 #endif 101 102 static void PR_CALLBACK DirTestVoid(void* argunused) { 103 (void)DirTest(argunused); 104 } 105 106 PRThread* create_new_thread(PRThreadType type, nativeStartType nativeStart, 107 void (*prStart)(void*), void* arg, 108 PRThreadPriority priority, PRThreadScope scope, 109 PRThreadState state, PRUint32 stackSize, 110 PRInt32 index) { 111 PRInt32 native_thread = 0; 112 113 PR_ASSERT(state == PR_UNJOINABLE_THREAD); 114 115 #if defined(_PR_PTHREADS) || defined(WIN32) 116 117 switch (index % 4) { 118 case 0: 119 scope = (PR_LOCAL_THREAD); 120 break; 121 case 1: 122 scope = (PR_GLOBAL_THREAD); 123 break; 124 case 2: 125 scope = (PR_GLOBAL_BOUND_THREAD); 126 break; 127 case 3: 128 native_thread = 1; 129 break; 130 default: 131 PR_NOT_REACHED("Invalid scope"); 132 break; 133 } 134 if (native_thread) { 135 # if defined(_PR_PTHREADS) 136 pthread_t tid; 137 if (!pthread_create(&tid, NULL, nativeStart, arg)) { 138 return ((PRThread*)tid); 139 } else { 140 return (NULL); 141 } 142 # else 143 HANDLE thandle; 144 unsigned tid; 145 146 thandle = (HANDLE)_beginthreadex(NULL, stackSize, nativeStart, arg, 147 STACK_SIZE_PARAM_IS_A_RESERVATION, &tid); 148 return ((PRThread*)thandle); 149 # endif 150 } else { 151 return ( 152 PR_CreateThread(type, prStart, arg, priority, scope, state, stackSize)); 153 } 154 #else 155 return ( 156 PR_CreateThread(type, prStart, arg, priority, scope, state, stackSize)); 157 #endif 158 } 159 160 static void PR_CALLBACK File_Write(void* arg) { 161 PRFileDesc* fd_file; 162 File_Rdwr_Param* fp = (File_Rdwr_Param*)arg; 163 char *name, *buf; 164 int offset, len; 165 166 setbuf(stdout, NULL); 167 name = fp->pathname; 168 buf = fp->buf; 169 offset = fp->offset; 170 len = fp->len; 171 172 fd_file = PR_Open(name, PR_RDWR | PR_CREATE_FILE, 0777); 173 if (fd_file == NULL) { 174 printf("testfile failed to create/open file %s\n", name); 175 return; 176 } 177 if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { 178 printf("testfile failed to seek in file %s\n", name); 179 return; 180 } 181 if ((PR_Write(fd_file, buf, len)) < 0) { 182 printf("testfile failed to write to file %s\n", name); 183 return; 184 } 185 DPRINTF(("Write out_buf[0] = 0x%x\n", (*((int*)buf)))); 186 PR_Close(fd_file); 187 PR_DELETE(fp); 188 189 PR_EnterMonitor(mon); 190 --thread_count; 191 PR_Notify(mon); 192 PR_ExitMonitor(mon); 193 } 194 195 #if defined(_PR_PTHREADS) 196 static void* PR_CALLBACK File_Write_Wrapper(void* argunused) { 197 (void)File_Write(argunused); 198 return NULL; 199 } 200 #elif defined(WIN32) 201 static unsigned __stdcall File_Write_Wrapper(void* argunused) { 202 (void)File_Write(argunused); 203 return 0; 204 } 205 #else 206 static void PR_CALLBACK File_Write_Wrapper(void* argunused) { 207 (void)File_Write(argunused); 208 } 209 #endif 210 211 static void PR_CALLBACK File_Read(void* arg) { 212 PRFileDesc* fd_file; 213 File_Rdwr_Param* fp = (File_Rdwr_Param*)arg; 214 char *name, *buf; 215 int offset, len; 216 217 setbuf(stdout, NULL); 218 name = fp->pathname; 219 buf = fp->buf; 220 offset = fp->offset; 221 len = fp->len; 222 223 fd_file = PR_Open(name, PR_RDONLY, 0); 224 if (fd_file == NULL) { 225 printf("testfile failed to open file %s\n", name); 226 return; 227 } 228 if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { 229 printf("testfile failed to seek in file %s\n", name); 230 return; 231 } 232 if ((PR_Read(fd_file, buf, len)) < 0) { 233 printf("testfile failed to read to file %s\n", name); 234 return; 235 } 236 DPRINTF(("Read in_buf[0] = 0x%x\n", (*((int*)buf)))); 237 PR_Close(fd_file); 238 PR_DELETE(fp); 239 240 PR_EnterMonitor(mon); 241 --thread_count; 242 PR_Notify(mon); 243 PR_ExitMonitor(mon); 244 } 245 246 #if defined(_PR_PTHREADS) 247 static void* PR_CALLBACK File_Read_Wrapper(void* argunused) { 248 (void)File_Read(argunused); 249 return NULL; 250 } 251 #elif defined(WIN32) 252 static unsigned __stdcall File_Read_Wrapper(void* argunused) { 253 (void)File_Read(argunused); 254 return 0; 255 } 256 #else 257 static void PR_CALLBACK File_Read_Wrapper(void* argunused) { 258 (void)File_Read(argunused); 259 } 260 #endif 261 262 static PRInt32 Misc_File_Tests(char* pathname) { 263 PRFileDesc* fd_file; 264 int len, rv = 0; 265 PRFileInfo file_info, file_info1; 266 char tmpname[1024]; 267 268 setbuf(stdout, NULL); 269 /* 270 * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access 271 */ 272 273 fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); 274 275 if (fd_file == NULL) { 276 printf("testfile failed to create/open file %s\n", pathname); 277 return -1; 278 } 279 if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { 280 printf("testfile PR_GetFileInfo failed on file %s\n", pathname); 281 rv = -1; 282 goto cleanup; 283 } 284 if (PR_Access(pathname, PR_ACCESS_EXISTS) != 0) { 285 printf("testfile PR_Access failed on file %s\n", pathname); 286 rv = -1; 287 goto cleanup; 288 } 289 if (PR_Access(pathname, PR_ACCESS_WRITE_OK) != 0) { 290 printf("testfile PR_Access failed on file %s\n", pathname); 291 rv = -1; 292 goto cleanup; 293 } 294 if (PR_Access(pathname, PR_ACCESS_READ_OK) != 0) { 295 printf("testfile PR_Access failed on file %s\n", pathname); 296 rv = -1; 297 goto cleanup; 298 } 299 300 if (PR_GetFileInfo(pathname, &file_info) < 0) { 301 printf("testfile PR_GetFileInfo failed on file %s\n", pathname); 302 rv = -1; 303 goto cleanup; 304 } 305 if (file_info.type != PR_FILE_FILE) { 306 printf( 307 "testfile: Error - PR_GetFileInfo returned incorrect type for file " 308 "%s\n", 309 pathname); 310 rv = -1; 311 goto cleanup; 312 } 313 if (file_info.size != 0) { 314 printf( 315 "testfile PR_GetFileInfo returned incorrect size (%d should be 0) for " 316 "file %s\n", 317 file_info.size, pathname); 318 rv = -1; 319 goto cleanup; 320 } 321 file_info1 = file_info; 322 323 len = PR_Available(fd_file); 324 if (len < 0) { 325 printf("testfile PR_Available failed on file %s\n", pathname); 326 rv = -1; 327 goto cleanup; 328 } else if (len != 0) { 329 printf("testfile PR_Available failed: expected/returned = %d/%d bytes\n", 0, 330 len); 331 rv = -1; 332 goto cleanup; 333 } 334 if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { 335 printf("testfile PR_GetFileInfo failed on file %s\n", pathname); 336 goto cleanup; 337 } 338 if (LL_NE(file_info.creationTime, file_info1.creationTime)) { 339 printf( 340 "testfile PR_GetFileInfo returned incorrect status-change time: %s\n", 341 pathname); 342 printf("ft = %lld, ft1 = %lld\n", (long long)file_info.creationTime, 343 (long long)file_info1.creationTime); 344 rv = -1; 345 goto cleanup; 346 } 347 len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); 348 if (len < 0) { 349 printf("testfile failed to write to file %s\n", pathname); 350 rv = -1; 351 goto cleanup; 352 } 353 if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { 354 printf("testfile PR_GetFileInfo failed on file %s\n", pathname); 355 goto cleanup; 356 } 357 if (file_info.size != CHUNK_SIZE) { 358 printf( 359 "testfile PR_GetFileInfo returned incorrect size (%d should be %d) for " 360 "file %s\n", 361 file_info.size, CHUNK_SIZE, pathname); 362 rv = -1; 363 goto cleanup; 364 } 365 if (LL_CMP(file_info.modifyTime, <, file_info1.modifyTime)) { 366 printf("testfile PR_GetFileInfo returned incorrect modify time: %s\n", 367 pathname); 368 printf("ft = %lld, ft1 = %lld\n", (long long)file_info.modifyTime, 369 (long long)file_info1.modifyTime); 370 rv = -1; 371 goto cleanup; 372 } 373 374 len = PR_Available(fd_file); 375 if (len < 0) { 376 printf("testfile PR_Available failed on file %s\n", pathname); 377 rv = -1; 378 goto cleanup; 379 } else if (len != 0) { 380 printf("testfile PR_Available failed: expected/returned = %d/%d bytes\n", 0, 381 len); 382 rv = -1; 383 goto cleanup; 384 } 385 386 PR_Seek(fd_file, 0, PR_SEEK_SET); 387 len = PR_Available(fd_file); 388 if (len < 0) { 389 printf("testfile PR_Available failed on file %s\n", pathname); 390 rv = -1; 391 goto cleanup; 392 } else if (len != CHUNK_SIZE) { 393 printf("testfile PR_Available failed: expected/returned = %d/%d bytes\n", 394 CHUNK_SIZE, len); 395 rv = -1; 396 goto cleanup; 397 } 398 PR_Close(fd_file); 399 400 strcpy(tmpname, pathname); 401 strcat(tmpname, ".RENAMED"); 402 if (PR_FAILURE == PR_Rename(pathname, tmpname)) { 403 printf("testfile failed to rename file %s\n", pathname); 404 rv = -1; 405 goto cleanup; 406 } 407 408 fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); 409 len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); 410 PR_Close(fd_file); 411 if (PR_SUCCESS == PR_Rename(pathname, tmpname)) { 412 printf("testfile renamed to existing file %s\n", pathname); 413 } 414 415 if ((PR_Delete(tmpname)) < 0) { 416 printf("testfile failed to unlink file %s\n", tmpname); 417 rv = -1; 418 } 419 420 cleanup: 421 if ((PR_Delete(pathname)) < 0) { 422 printf("testfile failed to unlink file %s\n", pathname); 423 rv = -1; 424 } 425 return rv; 426 } 427 428 static PRInt32 PR_CALLBACK FileTest(void) { 429 PRDir* fd_dir; 430 int i, offset, len, rv = 0; 431 PRThreadScope scope = PR_GLOBAL_THREAD; 432 File_Rdwr_Param* fparamp; 433 434 /* 435 * Create Test dir 436 */ 437 if ((PR_MkDir(TEST_DIR, 0777)) < 0) { 438 printf("testfile failed to create dir %s\n", TEST_DIR); 439 return -1; 440 } 441 fd_dir = PR_OpenDir(TEST_DIR); 442 if (fd_dir == NULL) { 443 printf("testfile failed to open dir %s\n", TEST_DIR); 444 rv = -1; 445 goto cleanup; 446 } 447 448 PR_CloseDir(fd_dir); 449 450 strcat(pathname, TEST_DIR); 451 strcat(pathname, "/"); 452 strcat(pathname, FILE_NAME); 453 454 in_buf = PR_NEW(buffer); 455 if (in_buf == NULL) { 456 printf("testfile failed to alloc buffer struct\n"); 457 rv = -1; 458 goto cleanup; 459 } 460 out_buf = PR_NEW(buffer); 461 if (out_buf == NULL) { 462 printf("testfile failed to alloc buffer struct\n"); 463 rv = -1; 464 goto cleanup; 465 } 466 467 /* 468 * Start a bunch of writer threads 469 */ 470 offset = 0; 471 len = CHUNK_SIZE; 472 PR_EnterMonitor(mon); 473 for (i = 0; i < NUM_RDWR_THREADS; i++) { 474 fparamp = PR_NEW(File_Rdwr_Param); 475 if (fparamp == NULL) { 476 printf("testfile failed to alloc File_Rdwr_Param struct\n"); 477 rv = -1; 478 goto cleanup; 479 } 480 fparamp->pathname = pathname; 481 fparamp->buf = out_buf->data + offset; 482 fparamp->offset = offset; 483 fparamp->len = len; 484 memset(fparamp->buf, i, len); 485 486 (void)create_new_thread(PR_USER_THREAD, File_Write_Wrapper, File_Write, 487 (void*)fparamp, PR_PRIORITY_NORMAL, scope, 488 PR_UNJOINABLE_THREAD, 0, i); 489 offset += len; 490 } 491 thread_count = i; 492 /* Wait for writer threads to exit */ 493 while (thread_count) { 494 PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); 495 } 496 PR_ExitMonitor(mon); 497 498 /* 499 * Start a bunch of reader threads 500 */ 501 offset = 0; 502 len = CHUNK_SIZE; 503 PR_EnterMonitor(mon); 504 for (i = 0; i < NUM_RDWR_THREADS; i++) { 505 fparamp = PR_NEW(File_Rdwr_Param); 506 if (fparamp == NULL) { 507 printf("testfile failed to alloc File_Rdwr_Param struct\n"); 508 rv = -1; 509 goto cleanup; 510 } 511 fparamp->pathname = pathname; 512 fparamp->buf = in_buf->data + offset; 513 fparamp->offset = offset; 514 fparamp->len = len; 515 516 (void)create_new_thread(PR_USER_THREAD, File_Read_Wrapper, File_Read, 517 (void*)fparamp, PR_PRIORITY_NORMAL, scope, 518 PR_UNJOINABLE_THREAD, 0, i); 519 offset += len; 520 if ((offset + len) > BUF_DATA_SIZE) { 521 break; 522 } 523 } 524 thread_count = i; 525 526 /* Wait for reader threads to exit */ 527 while (thread_count) { 528 PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); 529 } 530 PR_ExitMonitor(mon); 531 532 if (memcmp(in_buf->data, out_buf->data, offset) != 0) { 533 printf("File Test failed: file data corrupted\n"); 534 rv = -1; 535 goto cleanup; 536 } 537 538 if ((PR_Delete(pathname)) < 0) { 539 printf("testfile failed to unlink file %s\n", pathname); 540 rv = -1; 541 goto cleanup; 542 } 543 544 /* 545 * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access 546 */ 547 if (Misc_File_Tests(pathname) < 0) { 548 rv = -1; 549 } 550 551 cleanup: 552 if ((PR_RmDir(TEST_DIR)) < 0) { 553 printf("testfile failed to rmdir %s\n", TEST_DIR); 554 rv = -1; 555 } 556 return rv; 557 } 558 559 struct dirtest_arg { 560 PRMonitor* mon; 561 PRInt32 done; 562 }; 563 564 static PRInt32 RunDirTest(void) { 565 int i; 566 PRThread* t; 567 PRMonitor* mon; 568 struct dirtest_arg thrarg; 569 570 mon = PR_NewMonitor(); 571 if (!mon) { 572 printf("RunDirTest: Error - failed to create monitor\n"); 573 dirtest_failed = 1; 574 return -1; 575 } 576 thrarg.mon = mon; 577 578 for (i = 0; i < NUM_DIRTEST_THREADS; i++) { 579 thrarg.done = 0; 580 t = create_new_thread(PR_USER_THREAD, DirTestWrapper, DirTestVoid, &thrarg, 581 PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, 582 PR_UNJOINABLE_THREAD, 0, i); 583 if (!t) { 584 printf("RunDirTest: Error - failed to create thread\n"); 585 dirtest_failed = 1; 586 return -1; 587 } 588 PR_EnterMonitor(mon); 589 while (!thrarg.done) { 590 PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); 591 } 592 PR_ExitMonitor(mon); 593 } 594 PR_DestroyMonitor(mon); 595 return 0; 596 } 597 598 static PRInt32 PR_CALLBACK DirTest(void* arg) { 599 struct dirtest_arg* tinfo = (struct dirtest_arg*)arg; 600 PRFileDesc* fd_file; 601 PRDir* fd_dir; 602 int i; 603 int path_len; 604 PRDirEntry* dirEntry; 605 PRFileInfo info; 606 PRInt32 num_files = 0; 607 #if defined(XP_PC) && defined(WIN32) 608 HANDLE hfile; 609 #endif 610 611 #define FILES_IN_DIR 20 612 613 /* 614 * Create Test dir 615 */ 616 DPRINTF(("Creating test dir %s\n", TEST_DIR)); 617 if ((PR_MkDir(TEST_DIR, 0777)) < 0) { 618 printf("testfile failed to create dir %s [%d, %d]\n", TEST_DIR, 619 PR_GetError(), PR_GetOSError()); 620 return -1; 621 } 622 fd_dir = PR_OpenDir(TEST_DIR); 623 if (fd_dir == NULL) { 624 printf("testfile failed to open dirctory %s [%d, %d]\n", TEST_DIR, 625 PR_GetError(), PR_GetOSError()); 626 return -1; 627 } 628 629 strcpy(pathname, TEST_DIR); 630 strcat(pathname, "/"); 631 strcat(pathname, FILE_NAME); 632 path_len = strlen(pathname); 633 634 for (i = 0; i < FILES_IN_DIR; i++) { 635 sprintf(pathname + path_len, "%d%s", i, ""); 636 637 DPRINTF(("Creating test file %s\n", pathname)); 638 639 fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); 640 641 if (fd_file == NULL) { 642 printf("testfile failed to create/open file %s [%d, %d]\n", pathname, 643 PR_GetError(), PR_GetOSError()); 644 return -1; 645 } 646 PR_Close(fd_file); 647 } 648 #if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) 649 /* 650 * Create a hidden file - a platform-dependent operation 651 */ 652 strcpy(pathname, TEST_DIR); 653 strcat(pathname, "/"); 654 strcat(pathname, HIDDEN_FILE_NAME); 655 # if defined(XP_UNIX) 656 DPRINTF(("Creating hidden test file %s\n", pathname)); 657 fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); 658 659 if (fd_file == NULL) { 660 printf("testfile failed to create/open hidden file %s [%d, %d]\n", pathname, 661 PR_GetError(), PR_GetOSError()); 662 return -1; 663 } 664 665 PR_Close(fd_file); 666 667 # elif defined(WINCE) 668 DPRINTF(("Creating hidden test file %s\n", pathname)); 669 MultiByteToWideChar(CP_ACP, 0, pathname, -1, wPathname, 256); 670 hfile = 671 CreateFile(wPathname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 672 NULL, CREATE_NEW, FILE_ATTRIBUTE_HIDDEN, NULL); 673 if (hfile == INVALID_HANDLE_VALUE) { 674 printf("testfile failed to create/open hidden file %s [0, %d]\n", pathname, 675 GetLastError()); 676 return -1; 677 } 678 CloseHandle(hfile); 679 680 # elif defined(XP_PC) && defined(WIN32) 681 DPRINTF(("Creating hidden test file %s\n", pathname)); 682 hfile = CreateFile(pathname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 683 NULL, CREATE_NEW, FILE_ATTRIBUTE_HIDDEN, NULL); 684 if (hfile == INVALID_HANDLE_VALUE) { 685 printf("testfile failed to create/open hidden file %s [0, %d]\n", pathname, 686 GetLastError()); 687 return -1; 688 } 689 CloseHandle(hfile); 690 691 # endif /* XP_UNIX */ 692 693 #endif /* XP_UNIX || (XP_PC && WIN32) */ 694 695 if (PR_FAILURE == PR_CloseDir(fd_dir)) { 696 printf("testfile failed to close dirctory %s [%d, %d]\n", TEST_DIR, 697 PR_GetError(), PR_GetOSError()); 698 return -1; 699 } 700 fd_dir = PR_OpenDir(TEST_DIR); 701 if (fd_dir == NULL) { 702 printf("testfile failed to reopen dirctory %s [%d, %d]\n", TEST_DIR, 703 PR_GetError(), PR_GetOSError()); 704 return -1; 705 } 706 707 /* 708 * List all files, including hidden files 709 */ 710 DPRINTF(("Listing all files in directory %s\n", TEST_DIR)); 711 #if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) 712 num_files = FILES_IN_DIR + 1; 713 #else 714 num_files = FILES_IN_DIR; 715 #endif 716 while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_BOTH)) != NULL) { 717 num_files--; 718 strcpy(pathname, TEST_DIR); 719 strcat(pathname, "/"); 720 strcat(pathname, dirEntry->name); 721 DPRINTF(("\t%s\n", dirEntry->name)); 722 723 if ((PR_GetFileInfo(pathname, &info)) < 0) { 724 printf("testfile failed to GetFileInfo file %s [%d, %d]\n", pathname, 725 PR_GetError(), PR_GetOSError()); 726 return -1; 727 } 728 729 if (info.type != PR_FILE_FILE) { 730 printf("testfile incorrect fileinfo for file %s [%d, %d]\n", pathname, 731 PR_GetError(), PR_GetOSError()); 732 return -1; 733 } 734 } 735 if (num_files != 0) { 736 printf("testfile failed to find all files in directory %s [%d, %d]\n", 737 TEST_DIR, PR_GetError(), PR_GetOSError()); 738 return -1; 739 } 740 741 PR_CloseDir(fd_dir); 742 743 #if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) 744 745 /* 746 * List all files, except hidden files 747 */ 748 749 fd_dir = PR_OpenDir(TEST_DIR); 750 if (fd_dir == NULL) { 751 printf("testfile failed to reopen dirctory %s [%d, %d]\n", TEST_DIR, 752 PR_GetError(), PR_GetOSError()); 753 return -1; 754 } 755 756 DPRINTF(("Listing non-hidden files in directory %s\n", TEST_DIR)); 757 while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_HIDDEN)) != NULL) { 758 DPRINTF(("\t%s\n", dirEntry->name)); 759 if (!strcmp(HIDDEN_FILE_NAME, dirEntry->name)) { 760 printf("testfile found hidden file %s\n", pathname); 761 return -1; 762 } 763 } 764 /* 765 * Delete hidden file 766 */ 767 strcpy(pathname, TEST_DIR); 768 strcat(pathname, "/"); 769 strcat(pathname, HIDDEN_FILE_NAME); 770 if (PR_FAILURE == PR_Delete(pathname)) { 771 printf("testfile failed to delete hidden file %s [%d, %d]\n", pathname, 772 PR_GetError(), PR_GetOSError()); 773 return -1; 774 } 775 776 PR_CloseDir(fd_dir); 777 #endif /* XP_UNIX || (XP_PC && WIN32) */ 778 779 strcpy(renamename, TEST_DIR); 780 strcat(renamename, ".RENAMED"); 781 if (PR_FAILURE == PR_Rename(TEST_DIR, renamename)) { 782 printf("testfile failed to rename directory %s [%d, %d]\n", TEST_DIR, 783 PR_GetError(), PR_GetOSError()); 784 return -1; 785 } 786 787 if (PR_FAILURE == PR_MkDir(TEST_DIR, 0777)) { 788 printf("testfile failed to recreate dir %s [%d, %d]\n", TEST_DIR, 789 PR_GetError(), PR_GetOSError()); 790 return -1; 791 } 792 if (PR_SUCCESS == PR_Rename(renamename, TEST_DIR)) { 793 printf("testfile renamed directory to existing name %s\n", renamename); 794 return -1; 795 } 796 797 if (PR_FAILURE == PR_RmDir(TEST_DIR)) { 798 printf("testfile failed to rmdir %s [%d, %d]\n", TEST_DIR, PR_GetError(), 799 PR_GetOSError()); 800 return -1; 801 } 802 803 if (PR_FAILURE == PR_Rename(renamename, TEST_DIR)) { 804 printf("testfile failed to rename directory %s [%d, %d]\n", renamename, 805 PR_GetError(), PR_GetOSError()); 806 return -1; 807 } 808 fd_dir = PR_OpenDir(TEST_DIR); 809 if (fd_dir == NULL) { 810 printf("testfile failed to reopen directory %s [%d, %d]\n", TEST_DIR, 811 PR_GetError(), PR_GetOSError()); 812 return -1; 813 } 814 815 strcpy(pathname, TEST_DIR); 816 strcat(pathname, "/"); 817 strcat(pathname, FILE_NAME); 818 path_len = strlen(pathname); 819 820 for (i = 0; i < FILES_IN_DIR; i++) { 821 sprintf(pathname + path_len, "%d%s", i, ""); 822 823 if (PR_FAILURE == PR_Delete(pathname)) { 824 printf("testfile failed to delete file %s [%d, %d]\n", pathname, 825 PR_GetError(), PR_GetOSError()); 826 return -1; 827 } 828 } 829 830 PR_CloseDir(fd_dir); 831 832 if (PR_FAILURE == PR_RmDir(TEST_DIR)) { 833 printf("testfile failed to rmdir %s [%d, %d]\n", TEST_DIR, PR_GetError(), 834 PR_GetOSError()); 835 return -1; 836 } 837 PR_EnterMonitor(tinfo->mon); 838 tinfo->done = 1; 839 PR_Notify(tinfo->mon); 840 PR_ExitMonitor(tinfo->mon); 841 842 return 0; 843 } 844 /************************************************************************/ 845 846 /* 847 * Test file and directory NSPR APIs 848 */ 849 850 int main(int argc, char** argv) { 851 #ifdef WIN32 852 PRUint32 len; 853 #endif 854 #if defined(XP_UNIX) 855 int opt; 856 extern char* optarg; 857 extern int optind; 858 #endif 859 #if defined(XP_UNIX) 860 while ((opt = getopt(argc, argv, "d")) != EOF) { 861 switch (opt) { 862 case 'd': 863 _debug_on = 1; 864 break; 865 default: 866 break; 867 } 868 } 869 #endif 870 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); 871 872 mon = PR_NewMonitor(); 873 if (mon == NULL) { 874 printf("testfile: PR_NewMonitor failed\n"); 875 exit(2); 876 } 877 #ifdef WIN32 878 879 # ifdef WINCE 880 { 881 WCHAR tdir[TMPDIR_LEN]; 882 len = GetTempPath(TMPDIR_LEN, tdir); 883 if ((len > 0) && (len < (TMPDIR_LEN - 6))) { 884 /* 885 * enough space for prdir 886 */ 887 WideCharToMultiByte(CP_ACP, 0, tdir, -1, testdir, TMPDIR_LEN, 0, 0); 888 } 889 } 890 # else 891 len = GetTempPath(TMPDIR_LEN, testdir); 892 # endif /* WINCE */ 893 894 if ((len > 0) && (len < (TMPDIR_LEN - 6))) { 895 /* 896 * enough space for prdir 897 */ 898 strcpy((testdir + len), "prdir"); 899 TEST_DIR = testdir; 900 printf("TEST_DIR = %s\n", TEST_DIR); 901 } 902 #endif /* WIN32 */ 903 904 if (FileTest() < 0) { 905 printf("File Test failed\n"); 906 exit(2); 907 } 908 printf("File Test passed\n"); 909 if ((RunDirTest() < 0) || dirtest_failed) { 910 printf("Dir Test failed\n"); 911 exit(2); 912 } 913 printf("Dir Test passed\n"); 914 915 PR_DestroyMonitor(mon); 916 PR_Cleanup(); 917 return 0; 918 }