Back to index

lightning-sunbird  0.9+nobinonly
testfile.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nspr.h"
00039 #include "prpriv.h"
00040 
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #ifdef WIN32
00045 #include <windows.h>
00046 #include <process.h>
00047 #endif
00048 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
00049 #include <pthread.h>
00050 #endif
00051 
00052 #if defined(XP_OS2)
00053 #define INCL_DOSFILEMGR
00054 #include <os2.h>
00055 #ifdef XP_OS2_EMX
00056 #include <getopt.h>
00057 #include <errno.h>
00058 #endif /* XP_OS2_EMX */
00059 #endif /* XP_OS2 */
00060 
00061 static int _debug_on = 0;
00062 
00063 #ifdef XP_MAC
00064 #include "prlog.h"
00065 #include "primpl.h"
00066 #define printf PR_LogPrint
00067 #define setbuf(x,y)
00068 extern void SetupMacPrintfLog(char *logFile);
00069 #endif
00070 
00071 #ifdef XP_WIN
00072 #define mode_t int
00073 #endif
00074 
00075 #define DPRINTF(arg) if (_debug_on) printf arg
00076 
00077 PRLock *lock;
00078 PRMonitor *mon;
00079 PRInt32 count;
00080 int thread_count;
00081 
00082 #ifdef WIN16
00083 #define       BUF_DATA_SIZE 256 * 120
00084 #else
00085 #define       BUF_DATA_SIZE 256 * 1024
00086 #endif
00087 
00088 #define NUM_RDWR_THREADS    10
00089 #define NUM_DIRTEST_THREADS 4
00090 #define CHUNK_SIZE 512
00091 
00092 typedef struct buffer {
00093        char   data[BUF_DATA_SIZE];
00094 } buffer;
00095 
00096 typedef struct File_Rdwr_Param {
00097        char   *pathname;
00098        char   *buf;
00099        int    offset;
00100        int    len;
00101 } File_Rdwr_Param;
00102 
00103 #ifdef XP_PC
00104 #ifdef XP_OS2
00105 char *TEST_DIR = "prdir";
00106 #else
00107 char *TEST_DIR = "C:\\temp\\prdir";
00108 #endif
00109 char *FILE_NAME = "pr_testfile";
00110 char *HIDDEN_FILE_NAME = "hidden_pr_testfile";
00111 #else
00112 char *TEST_DIR = "/tmp/testfile_dir";
00113 char *FILE_NAME = "pr_testfile";
00114 char *HIDDEN_FILE_NAME = ".hidden_pr_testfile";
00115 #endif
00116 buffer *in_buf, *out_buf;
00117 char pathname[256], renamename[256];
00118 #define TMPDIR_LEN   64
00119 char testdir[TMPDIR_LEN];
00120 static PRInt32 PR_CALLBACK DirTest(void *argunused);
00121 PRInt32 dirtest_failed = 0;
00122 
00123 PRThread* create_new_thread(PRThreadType type,
00124                                                  void (*start)(void *arg),
00125                                                  void *arg,
00126                                                  PRThreadPriority priority,
00127                                                  PRThreadScope scope,
00128                                                  PRThreadState state,
00129                                                  PRUint32 stackSize, PRInt32 index)
00130 {
00131 PRInt32 native_thread = 0;
00132 
00133        PR_ASSERT(state == PR_UNJOINABLE_THREAD);
00134 
00135 #if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) || defined(XP_OS2)
00136 
00137        switch(index %  4) {
00138               case 0:
00139                      scope = (PR_LOCAL_THREAD);
00140                      break;
00141               case 1:
00142                      scope = (PR_GLOBAL_THREAD);
00143                      break;
00144               case 2:
00145                      scope = (PR_GLOBAL_BOUND_THREAD);
00146                      break;
00147               case 3:
00148                      native_thread = 1;
00149                      break;
00150               default:
00151                      PR_ASSERT(!"Invalid scope");
00152                      break;
00153        }
00154        if (native_thread) {
00155 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
00156               pthread_t tid;
00157               if (!pthread_create(&tid, NULL, start, arg))
00158                      return((PRThread *) tid);
00159               else
00160                      return (NULL);
00161 #elif defined(XP_OS2)
00162         TID tid;
00163 
00164         tid = (TID)_beginthread((void(* _Optlink)(void*))start,
00165                                 NULL, 32768, arg);
00166         if (tid == -1) {
00167           printf("_beginthread failed. errno %d\n", errno);
00168           return (NULL);
00169         }
00170         else
00171           return((PRThread *) tid);
00172 #else
00173               HANDLE thandle;
00174               unsigned tid;
00175               
00176               thandle = (HANDLE) _beginthreadex(
00177                                           NULL,
00178                                           stackSize,
00179                                           (unsigned (__stdcall *)(void *))start,
00180                                           arg,
00181                                           0,
00182                                           &tid);        
00183               return((PRThread *) thandle);
00184 #endif
00185        } else {
00186               return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
00187        }
00188 #else
00189        return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
00190 #endif
00191 }
00192 
00193 static void PR_CALLBACK File_Write(void *arg)
00194 {
00195 PRFileDesc *fd_file;
00196 File_Rdwr_Param *fp = (File_Rdwr_Param *) arg;
00197 char *name, *buf;
00198 int offset, len;
00199 
00200        setbuf(stdout, NULL);
00201        name = fp->pathname;
00202        buf = fp->buf;
00203        offset = fp->offset;
00204        len = fp->len;
00205        
00206        fd_file = PR_Open(name, PR_RDWR | PR_CREATE_FILE, 0777);
00207        if (fd_file == NULL) {
00208               printf("testfile failed to create/open file %s\n",name);
00209               return;
00210        }
00211        if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) {
00212               printf("testfile failed to seek in file %s\n",name);
00213               return;
00214        }      
00215        if ((PR_Write(fd_file, buf, len)) < 0) {
00216               printf("testfile failed to write to file %s\n",name);
00217               return;
00218        }      
00219        DPRINTF(("Write out_buf[0] = 0x%x\n",(*((int *) buf))));
00220        PR_Close(fd_file);
00221        PR_DELETE(fp);
00222 
00223        PR_EnterMonitor(mon);
00224        --thread_count;
00225        PR_Notify(mon);
00226        PR_ExitMonitor(mon);
00227 }
00228 
00229 static void PR_CALLBACK File_Read(void *arg)
00230 {
00231 PRFileDesc *fd_file;
00232 File_Rdwr_Param *fp = (File_Rdwr_Param *) arg;
00233 char *name, *buf;
00234 int offset, len;
00235 
00236        setbuf(stdout, NULL);
00237        name = fp->pathname;
00238        buf = fp->buf;
00239        offset = fp->offset;
00240        len = fp->len;
00241        
00242        fd_file = PR_Open(name, PR_RDONLY, 0);
00243        if (fd_file == NULL) {
00244               printf("testfile failed to open file %s\n",name);
00245               return;
00246        }
00247        if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) {
00248               printf("testfile failed to seek in file %s\n",name);
00249               return;
00250        }      
00251        if ((PR_Read(fd_file, buf, len)) < 0) {
00252               printf("testfile failed to read to file %s\n",name);
00253               return;
00254        }      
00255        DPRINTF(("Read in_buf[0] = 0x%x\n",(*((int *) buf))));
00256        PR_Close(fd_file);
00257        PR_DELETE(fp);
00258 
00259        PR_EnterMonitor(mon);
00260        --thread_count;
00261        PR_Notify(mon);
00262        PR_ExitMonitor(mon);
00263 }
00264 
00265 
00266 static PRInt32 Misc_File_Tests(char *pathname)
00267 {
00268 PRFileDesc *fd_file;
00269 int len, rv = 0;
00270 PRFileInfo file_info, file_info1;
00271 char tmpname[1024];
00272 
00273        setbuf(stdout, NULL);
00274        /*
00275         * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access
00276         */
00277 
00278        fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
00279 
00280        if (fd_file == NULL) {
00281               printf("testfile failed to create/open file %s\n",pathname);
00282               return -1;
00283        }
00284        if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) {
00285               printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
00286               rv = -1;
00287               goto cleanup;
00288        }
00289        if (PR_Access(pathname, PR_ACCESS_EXISTS) != 0) {
00290               printf("testfile PR_Access failed on file %s\n",pathname);
00291               rv = -1;
00292               goto cleanup;
00293        }
00294        if (PR_Access(pathname, PR_ACCESS_WRITE_OK) != 0) {
00295               printf("testfile PR_Access failed on file %s\n",pathname);
00296               rv = -1;
00297               goto cleanup;
00298        }
00299        if (PR_Access(pathname, PR_ACCESS_READ_OK) != 0) {
00300               printf("testfile PR_Access failed on file %s\n",pathname);
00301               rv = -1;
00302               goto cleanup;
00303        }
00304 
00305 
00306        if (PR_GetFileInfo(pathname, &file_info) < 0) {
00307               printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
00308               rv = -1;
00309               goto cleanup;
00310        }
00311        if (file_info.type != PR_FILE_FILE) {
00312        printf(
00313        "testfile: Error - PR_GetFileInfo returned incorrect type for file %s\n",
00314               pathname);
00315               rv = -1;
00316               goto cleanup;
00317        }
00318        if (file_info.size != 0) {
00319               printf(
00320               "testfile PR_GetFileInfo returned incorrect size (%d should be 0) for file %s\n",
00321               file_info.size, pathname);
00322               rv = -1;
00323               goto cleanup;
00324        }
00325        file_info1 = file_info;
00326 
00327        len = PR_Available(fd_file);
00328        if (len < 0) {
00329               printf("testfile PR_Available failed on file %s\n",pathname);
00330               rv = -1;
00331               goto cleanup;
00332        } else if (len != 0) {
00333               printf(
00334               "testfile PR_Available failed: expected/returned = %d/%d bytes\n",
00335                      0, len);
00336               rv = -1;
00337               goto cleanup;
00338        }
00339        if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) {
00340               printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
00341               goto cleanup;
00342        }
00343        if (LL_NE(file_info.creationTime , file_info1.creationTime)) {
00344               printf(
00345               "testfile PR_GetFileInfo returned incorrect status-change time: %s\n",
00346               pathname);
00347               printf("ft = %lld, ft1 = %lld\n",file_info.creationTime,
00348                                                                file_info1.creationTime);
00349               rv = -1;
00350               goto cleanup;
00351        }
00352        len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE);
00353        if (len < 0) {
00354               printf("testfile failed to write to file %s\n",pathname);
00355               rv = -1;
00356               goto cleanup;
00357        }
00358        if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) {
00359               printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
00360               goto cleanup;
00361        }
00362        if (file_info.size != CHUNK_SIZE) {
00363               printf(
00364               "testfile PR_GetFileInfo returned incorrect size (%d should be %d) for file %s\n",
00365               file_info.size, CHUNK_SIZE, pathname);
00366               rv = -1;
00367               goto cleanup;
00368        }
00369        if (LL_CMP(file_info.modifyTime, < , file_info1.modifyTime)) {
00370               printf(
00371               "testfile PR_GetFileInfo returned incorrect modify time: %s\n",
00372               pathname);
00373               printf("ft = %lld, ft1 = %lld\n",file_info.modifyTime,
00374                                                                file_info1.modifyTime);
00375               rv = -1;
00376               goto cleanup;
00377        }
00378 
00379        len = PR_Available(fd_file);
00380        if (len < 0) {
00381               printf("testfile PR_Available failed on file %s\n",pathname);
00382               rv = -1;
00383               goto cleanup;
00384        } else if (len != 0) {
00385               printf(
00386               "testfile PR_Available failed: expected/returned = %d/%d bytes\n",
00387                      0, len);
00388               rv = -1;
00389               goto cleanup;
00390        }
00391        
00392        PR_Seek(fd_file, 0, PR_SEEK_SET);
00393        len = PR_Available(fd_file);
00394        if (len < 0) {
00395               printf("testfile PR_Available failed on file %s\n",pathname);
00396               rv = -1;
00397               goto cleanup;
00398        } else if (len != CHUNK_SIZE) {
00399               printf(
00400               "testfile PR_Available failed: expected/returned = %d/%d bytes\n",
00401                      CHUNK_SIZE, len);
00402               rv = -1;
00403               goto cleanup;
00404        }
00405     PR_Close(fd_file);
00406 
00407        strcpy(tmpname,pathname);
00408        strcat(tmpname,".RENAMED");
00409        if (PR_FAILURE == PR_Rename(pathname, tmpname)) {
00410               printf("testfile failed to rename file %s\n",pathname);
00411               rv = -1;
00412               goto cleanup;
00413        }
00414 
00415        fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
00416        len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE);
00417     PR_Close(fd_file);
00418        if (PR_SUCCESS == PR_Rename(pathname, tmpname)) {
00419               printf("testfile renamed to existing file %s\n",pathname);
00420        }
00421 
00422        if ((PR_Delete(tmpname)) < 0) {
00423               printf("testfile failed to unlink file %s\n",tmpname);
00424               rv = -1;
00425        }
00426 
00427 cleanup:
00428        if ((PR_Delete(pathname)) < 0) {
00429               printf("testfile failed to unlink file %s\n",pathname);
00430               rv = -1;
00431        }
00432        return rv;
00433 }
00434 
00435 
00436 static PRInt32 PR_CALLBACK FileTest(void)
00437 {
00438 PRDir *fd_dir;
00439 int i, offset, len, rv = 0;
00440 PRThread *t;
00441 PRThreadScope scope;
00442 File_Rdwr_Param *fparamp;
00443 
00444        /*
00445         * Create Test dir
00446         */
00447        if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
00448               printf("testfile failed to create dir %s\n",TEST_DIR);
00449               return -1;
00450        }
00451        fd_dir = PR_OpenDir(TEST_DIR);
00452        if (fd_dir == NULL) {
00453               printf("testfile failed to open dir %s\n",TEST_DIR);
00454               rv =  -1;
00455               goto cleanup; 
00456        }
00457 
00458     PR_CloseDir(fd_dir);
00459 
00460        strcat(pathname, TEST_DIR);
00461        strcat(pathname, "/");
00462        strcat(pathname, FILE_NAME);
00463 
00464        in_buf = PR_NEW(buffer);
00465        if (in_buf == NULL) {
00466               printf(
00467               "testfile failed to alloc buffer struct\n");
00468               rv =  -1;
00469               goto cleanup; 
00470        }
00471        out_buf = PR_NEW(buffer);
00472        if (out_buf == NULL) {
00473               printf(
00474               "testfile failed to alloc buffer struct\n");
00475               rv =  -1;
00476               goto cleanup; 
00477        }
00478 
00479        /*
00480         * Start a bunch of writer threads
00481         */
00482        offset = 0;
00483        len = CHUNK_SIZE;
00484        PR_EnterMonitor(mon);
00485        for (i = 0; i < NUM_RDWR_THREADS; i++) {
00486               fparamp = PR_NEW(File_Rdwr_Param);
00487               if (fparamp == NULL) {
00488                      printf(
00489                      "testfile failed to alloc File_Rdwr_Param struct\n");
00490                      rv =  -1;
00491                      goto cleanup; 
00492               }
00493               fparamp->pathname = pathname;
00494               fparamp->buf = out_buf->data + offset;
00495               fparamp->offset = offset;
00496               fparamp->len = len;
00497               memset(fparamp->buf, i, len);
00498 
00499               t = create_new_thread(PR_USER_THREAD,
00500                            File_Write, (void *)fparamp, 
00501                            PR_PRIORITY_NORMAL,
00502                            scope,
00503                            PR_UNJOINABLE_THREAD,
00504                            0, i);
00505               offset += len;
00506        }
00507        thread_count = i;
00508        /* Wait for writer threads to exit */
00509        while (thread_count) {
00510               PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
00511        }
00512        PR_ExitMonitor(mon);
00513 
00514 
00515        /*
00516         * Start a bunch of reader threads
00517         */
00518        offset = 0;
00519        len = CHUNK_SIZE;
00520        PR_EnterMonitor(mon);
00521        for (i = 0; i < NUM_RDWR_THREADS; i++) {
00522               fparamp = PR_NEW(File_Rdwr_Param);
00523               if (fparamp == NULL) {
00524                      printf(
00525                      "testfile failed to alloc File_Rdwr_Param struct\n");
00526                      rv =  -1;
00527                      goto cleanup; 
00528               }
00529               fparamp->pathname = pathname;
00530               fparamp->buf = in_buf->data + offset;
00531               fparamp->offset = offset;
00532               fparamp->len = len;
00533 
00534               t = create_new_thread(PR_USER_THREAD,
00535                            File_Read, (void *)fparamp, 
00536                            PR_PRIORITY_NORMAL,
00537                            scope,
00538                            PR_UNJOINABLE_THREAD,
00539                            0, i);
00540               offset += len;
00541               if ((offset + len) > BUF_DATA_SIZE)
00542                      break;
00543        }
00544        thread_count = i;
00545 
00546        /* Wait for reader threads to exit */
00547        while (thread_count) {
00548               PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
00549        }
00550        PR_ExitMonitor(mon);
00551 
00552        if (memcmp(in_buf->data, out_buf->data, offset) != 0) {
00553               printf("File Test failed: file data corrupted\n");
00554               rv =  -1;
00555               goto cleanup; 
00556        }
00557 
00558        if ((PR_Delete(pathname)) < 0) {
00559               printf("testfile failed to unlink file %s\n",pathname);
00560               rv =  -1;
00561               goto cleanup; 
00562        }
00563 
00564        /*
00565         * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access
00566         */
00567        if (Misc_File_Tests(pathname) < 0) {
00568               rv = -1;
00569        }
00570 
00571 cleanup:
00572        if ((PR_RmDir(TEST_DIR)) < 0) {
00573               printf("testfile failed to rmdir %s\n", TEST_DIR);
00574               rv = -1;
00575        }
00576        return rv;
00577 }
00578 
00579 struct dirtest_arg {
00580        PRMonitor     *mon;
00581        PRInt32              done;
00582 };
00583 
00584 static PRInt32 RunDirTest(void)
00585 {
00586 int i;
00587 PRThread *t;
00588 PRMonitor *mon;
00589 struct dirtest_arg thrarg;
00590 
00591        mon = PR_NewMonitor();
00592        if (!mon) {
00593               printf("RunDirTest: Error - failed to create monitor\n");
00594               dirtest_failed = 1;
00595               return -1;
00596        }
00597        thrarg.mon = mon;
00598 
00599        for (i = 0; i < NUM_DIRTEST_THREADS; i++) {
00600 
00601               thrarg.done= 0;
00602               t = create_new_thread(PR_USER_THREAD,
00603                            DirTest, &thrarg, 
00604                            PR_PRIORITY_NORMAL,
00605                            PR_LOCAL_THREAD,
00606                            PR_UNJOINABLE_THREAD,
00607                            0, i);
00608               if (!t) {
00609                      printf("RunDirTest: Error - failed to create thread\n");
00610                      dirtest_failed = 1;
00611                      return -1;
00612               }
00613               PR_EnterMonitor(mon);
00614               while (!thrarg.done)
00615                      PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
00616               PR_ExitMonitor(mon);
00617 
00618        }
00619        PR_DestroyMonitor(mon);
00620        return 0;
00621 }
00622 
00623 static PRInt32 PR_CALLBACK DirTest(void *arg)
00624 {
00625 struct dirtest_arg *tinfo = (struct dirtest_arg *) arg;
00626 PRFileDesc *fd_file;
00627 PRDir *fd_dir;
00628 int i;
00629 int path_len;
00630 PRDirEntry *dirEntry;
00631 PRFileInfo info;
00632 PRInt32 num_files = 0;
00633 #if defined(XP_PC) && defined(WIN32)
00634 HANDLE hfile;
00635 #endif
00636 
00637 #define  FILES_IN_DIR 20
00638 
00639        /*
00640         * Create Test dir
00641         */
00642        DPRINTF(("Creating test dir %s\n",TEST_DIR));
00643        if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
00644               printf(
00645                      "testfile failed to create dir %s [%d, %d]\n",
00646                      TEST_DIR, PR_GetError(), PR_GetOSError());
00647               return -1;
00648        }
00649        fd_dir = PR_OpenDir(TEST_DIR);
00650        if (fd_dir == NULL) {
00651               printf(
00652                      "testfile failed to open dirctory %s [%d, %d]\n",
00653                      TEST_DIR, PR_GetError(), PR_GetOSError());
00654               return -1;
00655        }
00656 
00657        strcpy(pathname, TEST_DIR);
00658        strcat(pathname, "/");
00659        strcat(pathname, FILE_NAME);
00660        path_len = strlen(pathname);
00661        
00662        for (i = 0; i < FILES_IN_DIR; i++) {
00663 
00664               sprintf(pathname + path_len,"%d%s",i,"");
00665 
00666               DPRINTF(("Creating test file %s\n",pathname));
00667 
00668               fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
00669 
00670               if (fd_file == NULL) {
00671                      printf(
00672                                    "testfile failed to create/open file %s [%d, %d]\n",
00673                                    pathname, PR_GetError(), PR_GetOSError());
00674                      return -1;
00675               }
00676         PR_Close(fd_file);
00677        }
00678 #if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS)
00679        /*
00680         * Create a hidden file - a platform-dependent operation
00681         */
00682        strcpy(pathname, TEST_DIR);
00683        strcat(pathname, "/");
00684        strcat(pathname, HIDDEN_FILE_NAME);
00685 #if defined(XP_UNIX) || defined(XP_MAC) || defined(XP_BEOS)
00686        DPRINTF(("Creating hidden test file %s\n",pathname));
00687        fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
00688 
00689        if (fd_file == NULL) {
00690               printf(
00691                             "testfile failed to create/open hidden file %s [%d, %d]\n",
00692                             pathname, PR_GetError(), PR_GetOSError());
00693               return -1;
00694        }
00695 
00696 #if defined(XP_MAC)
00697        {
00698 #include <files.h>
00699 
00700        OSErr                err;
00701        FCBPBRec             fcbpb;
00702        CInfoPBRec           pb;
00703        Str255               pascalMacPath;
00704 
00705        fcbpb.ioNamePtr = pascalMacPath;
00706        fcbpb.ioVRefNum = 0;
00707        fcbpb.ioRefNum = fd_file->secret->md.osfd;
00708        fcbpb.ioFCBIndx = 0;
00709        
00710        err = PBGetFCBInfoSync(&fcbpb);
00711        if (err != noErr) {
00712        PR_Close(fd_file);
00713        return -1;
00714        }
00715        
00716        pb.hFileInfo.ioNamePtr = pascalMacPath;
00717        pb.hFileInfo.ioVRefNum = fcbpb.ioFCBVRefNum;
00718        pb.hFileInfo.ioDirID = fcbpb.ioFCBParID;
00719        pb.hFileInfo.ioFDirIndex = 0;
00720        
00721        err = PBGetCatInfoSync(&pb);
00722        if (err != noErr) {
00723        PR_Close(fd_file);
00724        return -1;
00725        }
00726 
00727        pb.hFileInfo.ioNamePtr = pascalMacPath;
00728        pb.hFileInfo.ioVRefNum = fcbpb.ioFCBVRefNum;
00729        pb.hFileInfo.ioDirID = fcbpb.ioFCBParID;
00730        pb.hFileInfo.ioFDirIndex = 0;
00731        
00732        pb.hFileInfo.ioFlFndrInfo.fdFlags |= fInvisible;
00733 
00734        err = PBSetCatInfoSync(&pb);
00735        if (err != noErr) {
00736        PR_Close(fd_file);
00737        return -1;
00738        }
00739 
00740        }
00741 #endif
00742 
00743     PR_Close(fd_file);
00744 
00745        
00746 #elif defined(XP_PC) && defined(WIN32)
00747        DPRINTF(("Creating hidden test file %s\n",pathname));
00748        hfile = CreateFile(pathname, GENERIC_READ,
00749                                           FILE_SHARE_READ|FILE_SHARE_WRITE,
00750                                           NULL,
00751                                           CREATE_NEW,
00752                                           FILE_ATTRIBUTE_HIDDEN,
00753                                           NULL);
00754        if (hfile == INVALID_HANDLE_VALUE) {
00755               printf("testfile failed to create/open hidden file %s [0, %d]\n",
00756                             pathname, GetLastError());
00757               return -1;
00758        }
00759        CloseHandle(hfile);
00760                                           
00761 #elif defined(OS2)
00762        DPRINTF(("Creating hidden test file %s\n",pathname));
00763        fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, (int)FILE_HIDDEN);
00764 
00765        if (fd_file == NULL) {
00766               printf("testfile failed to create/open hidden file %s [%d, %d]\n",
00767                             pathname, PR_GetError(), PR_GetOSError());
00768               return -1;
00769        }
00770        PR_Close(fd_file);
00771 #endif /* XP _UNIX || XP_MAC*/
00772 
00773 #endif /* XP_UNIX || XP_MAC ||(XP_PC && WIN32) */
00774 
00775 
00776        if (PR_FAILURE == PR_CloseDir(fd_dir))
00777        {
00778               printf(
00779                      "testfile failed to close dirctory %s [%d, %d]\n",
00780                      TEST_DIR, PR_GetError(), PR_GetOSError());
00781               return -1;
00782        }
00783        fd_dir = PR_OpenDir(TEST_DIR);
00784        if (fd_dir == NULL) {
00785               printf(
00786                      "testfile failed to reopen dirctory %s [%d, %d]\n",
00787                      TEST_DIR, PR_GetError(), PR_GetOSError());
00788               return -1;
00789        }
00790   
00791        /*
00792         * List all files, including hidden files
00793         */
00794        DPRINTF(("Listing all files in directory %s\n",TEST_DIR));
00795 #if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS)
00796        num_files = FILES_IN_DIR + 1;
00797 #else
00798        num_files = FILES_IN_DIR;
00799 #endif
00800        while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_BOTH)) != NULL) {
00801               num_files--;
00802               strcpy(pathname, TEST_DIR);
00803               strcat(pathname, "/");
00804               strcat(pathname, dirEntry->name);
00805               DPRINTF(("\t%s\n",dirEntry->name));
00806 
00807               if ((PR_GetFileInfo(pathname, &info)) < 0) {
00808                      printf(
00809                             "testfile failed to GetFileInfo file %s [%d, %d]\n",
00810                             pathname, PR_GetError(), PR_GetOSError());
00811                      return -1;
00812               }
00813               
00814               if (info.type != PR_FILE_FILE) {
00815                      printf(
00816                             "testfile incorrect fileinfo for file %s [%d, %d]\n",
00817                             pathname, PR_GetError(), PR_GetOSError());
00818                      return -1;
00819               }
00820        }
00821        if (num_files != 0)
00822        {
00823               printf(
00824                      "testfile failed to find all files in directory %s [%d, %d]\n",
00825                      TEST_DIR, PR_GetError(), PR_GetOSError());
00826               return -1;
00827        }
00828 
00829     PR_CloseDir(fd_dir);
00830 
00831 #if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS)
00832 
00833        /*
00834         * List all files, except hidden files
00835         */
00836 
00837        fd_dir = PR_OpenDir(TEST_DIR);
00838        if (fd_dir == NULL) {
00839               printf(
00840                      "testfile failed to reopen dirctory %s [%d, %d]\n",
00841                      TEST_DIR, PR_GetError(), PR_GetOSError());
00842               return -1;
00843        }
00844   
00845        DPRINTF(("Listing non-hidden files in directory %s\n",TEST_DIR));
00846        while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_HIDDEN)) != NULL) {
00847               DPRINTF(("\t%s\n",dirEntry->name));
00848               if (!strcmp(HIDDEN_FILE_NAME, dirEntry->name)) {
00849                      printf("testfile found hidden file %s\n", pathname);
00850                      return -1;
00851               }
00852 
00853        }
00854        /*
00855         * Delete hidden file
00856         */
00857        strcpy(pathname, TEST_DIR);
00858        strcat(pathname, "/");
00859        strcat(pathname, HIDDEN_FILE_NAME);
00860        if (PR_FAILURE == PR_Delete(pathname)) {
00861               printf(
00862                      "testfile failed to delete hidden file %s [%d, %d]\n",
00863                      pathname, PR_GetError(), PR_GetOSError());
00864               return -1;
00865        }
00866 
00867     PR_CloseDir(fd_dir);
00868 #endif /* XP_UNIX || XP_MAC || (XP_PC && WIN32) */
00869 
00870        strcpy(renamename, TEST_DIR);
00871        strcat(renamename, ".RENAMED");
00872        if (PR_FAILURE == PR_Rename(TEST_DIR, renamename)) {
00873               printf(
00874                      "testfile failed to rename directory %s [%d, %d]\n",
00875                      TEST_DIR, PR_GetError(), PR_GetOSError());
00876               return -1;
00877        }
00878     
00879        if (PR_FAILURE == PR_MkDir(TEST_DIR, 0777)) {
00880               printf(
00881                      "testfile failed to recreate dir %s [%d, %d]\n",
00882                      TEST_DIR, PR_GetError(), PR_GetOSError());
00883               return -1;
00884        }
00885        if (PR_SUCCESS == PR_Rename(renamename, TEST_DIR)) {
00886               printf(
00887                      "testfile renamed directory to existing name %s\n",
00888                      renamename);
00889               return -1;
00890        }
00891 
00892        if (PR_FAILURE == PR_RmDir(TEST_DIR)) {
00893               printf(
00894                      "testfile failed to rmdir %s [%d, %d]\n",
00895                      TEST_DIR, PR_GetError(), PR_GetOSError());
00896               return -1;
00897        }
00898 
00899        if (PR_FAILURE == PR_Rename(renamename, TEST_DIR)) {
00900               printf(
00901                      "testfile failed to rename directory %s [%d, %d]\n",
00902                      renamename, PR_GetError(), PR_GetOSError());
00903               return -1;
00904        }
00905        fd_dir = PR_OpenDir(TEST_DIR);
00906        if (fd_dir == NULL) {
00907               printf(
00908                      "testfile failed to reopen directory %s [%d, %d]\n",
00909                      TEST_DIR, PR_GetError(), PR_GetOSError());
00910               return -1;
00911        }
00912 
00913        strcpy(pathname, TEST_DIR);
00914        strcat(pathname, "/");
00915        strcat(pathname, FILE_NAME);
00916        path_len = strlen(pathname);
00917        
00918        for (i = 0; i < FILES_IN_DIR; i++) {
00919 
00920               sprintf(pathname + path_len,"%d%s",i,"");
00921 
00922               if (PR_FAILURE == PR_Delete(pathname)) {
00923                      printf(
00924                             "testfile failed to delete file %s [%d, %d]\n",
00925                             pathname, PR_GetError(), PR_GetOSError());
00926                      return -1;
00927               }
00928        }
00929 
00930     PR_CloseDir(fd_dir);
00931 
00932        if (PR_FAILURE == PR_RmDir(TEST_DIR)) {
00933               printf(
00934                      "testfile failed to rmdir %s [%d, %d]\n",
00935                      TEST_DIR, PR_GetError(), PR_GetOSError());
00936               return -1;
00937        }
00938        PR_EnterMonitor(tinfo->mon);
00939        tinfo->done = 1;
00940        PR_Notify(tinfo->mon);
00941        PR_ExitMonitor(tinfo->mon);
00942 
00943        return 0;
00944 }
00945 /************************************************************************/
00946 
00947 /*
00948  * Test file and directory NSPR APIs
00949  */
00950 
00951 int main(int argc, char **argv)
00952 {
00953 #ifdef WIN32
00954        PRUint32 len;
00955 #endif
00956 #if defined(XP_UNIX) || defined(XP_OS2_EMX)
00957         int opt;
00958         extern char *optarg;
00959        extern int optind;
00960 #endif
00961 #if defined(XP_UNIX) || defined(XP_OS2_EMX)
00962         while ((opt = getopt(argc, argv, "d")) != EOF) {
00963                 switch(opt) {
00964                         case 'd':
00965                                 _debug_on = 1;
00966                                 break;
00967                         default:
00968                                 break;
00969                 }
00970         }
00971 #endif
00972        PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
00973     PR_STDIO_INIT();
00974 
00975 #ifdef XP_MAC
00976        SetupMacPrintfLog("testfile.log");
00977 #endif
00978 
00979        mon = PR_NewMonitor();
00980        if (mon == NULL) {
00981               printf("testfile: PR_NewMonitor failed\n");
00982               exit(2);
00983        }
00984 #ifdef WIN32
00985        len = GetTempPath(TMPDIR_LEN, testdir);
00986        if ((len > 0) && (len < (TMPDIR_LEN - 6))) {
00987               /*
00988                * enough space for prdir
00989                */
00990               strcpy((testdir + len),"prdir");
00991               TEST_DIR = testdir;
00992               printf("TEST_DIR = %s\n",TEST_DIR);
00993        }
00994        
00995 #endif
00996 
00997        if (FileTest() < 0) {
00998               printf("File Test failed\n");
00999               exit(2);
01000        }
01001        printf("File Test passed\n");
01002        if ((RunDirTest() < 0) || dirtest_failed) {
01003               printf("Dir Test failed\n");
01004               exit(2);
01005        }
01006        printf("Dir Test passed\n");
01007 
01008        PR_DestroyMonitor(mon);
01009        PR_Cleanup();
01010     return 0;
01011 }