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