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