michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nspr.h" michael@0: #include "prpriv.h" michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #ifdef WIN32 michael@0: #include michael@0: #include michael@0: #endif michael@0: #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) michael@0: #include michael@0: #endif michael@0: #ifdef SYMBIAN michael@0: #include michael@0: #endif michael@0: michael@0: #if defined(XP_OS2) michael@0: #define INCL_DOSFILEMGR michael@0: #include michael@0: #include michael@0: #include michael@0: #endif /* XP_OS2 */ michael@0: michael@0: static int _debug_on = 0; michael@0: michael@0: #ifdef WINCE michael@0: #define setbuf(x,y) michael@0: #endif michael@0: michael@0: #ifdef XP_WIN michael@0: #define mode_t int michael@0: #endif michael@0: michael@0: #define DPRINTF(arg) if (_debug_on) printf arg michael@0: michael@0: PRLock *lock; michael@0: PRMonitor *mon; michael@0: PRInt32 count; michael@0: int thread_count; michael@0: michael@0: #ifdef WIN16 michael@0: #define BUF_DATA_SIZE 256 * 120 michael@0: #else michael@0: #define BUF_DATA_SIZE 256 * 1024 michael@0: #endif michael@0: michael@0: #define NUM_RDWR_THREADS 10 michael@0: #define NUM_DIRTEST_THREADS 4 michael@0: #define CHUNK_SIZE 512 michael@0: michael@0: typedef struct buffer { michael@0: char data[BUF_DATA_SIZE]; michael@0: } buffer; michael@0: michael@0: typedef struct File_Rdwr_Param { michael@0: char *pathname; michael@0: char *buf; michael@0: int offset; michael@0: int len; michael@0: } File_Rdwr_Param; michael@0: michael@0: #ifdef XP_PC michael@0: #ifdef XP_OS2 michael@0: char *TEST_DIR = "prdir"; michael@0: #else michael@0: char *TEST_DIR = "C:\\temp\\prdir"; michael@0: #endif michael@0: char *FILE_NAME = "pr_testfile"; michael@0: char *HIDDEN_FILE_NAME = "hidden_pr_testfile"; michael@0: #else michael@0: #ifdef SYMBIAN michael@0: char *TEST_DIR = "c:\\data\\testfile_dir"; michael@0: #else michael@0: char *TEST_DIR = "/tmp/testfile_dir"; michael@0: #endif michael@0: char *FILE_NAME = "pr_testfile"; michael@0: char *HIDDEN_FILE_NAME = ".hidden_pr_testfile"; michael@0: #endif michael@0: buffer *in_buf, *out_buf; michael@0: char pathname[256], renamename[256]; michael@0: #ifdef WINCE michael@0: WCHAR wPathname[256]; michael@0: #endif michael@0: #define TMPDIR_LEN 64 michael@0: char testdir[TMPDIR_LEN]; michael@0: static PRInt32 PR_CALLBACK DirTest(void *argunused); michael@0: PRInt32 dirtest_failed = 0; michael@0: michael@0: PRThread* create_new_thread(PRThreadType type, michael@0: void (*start)(void *arg), michael@0: void *arg, michael@0: PRThreadPriority priority, michael@0: PRThreadScope scope, michael@0: PRThreadState state, michael@0: PRUint32 stackSize, PRInt32 index) michael@0: { michael@0: PRInt32 native_thread = 0; michael@0: michael@0: PR_ASSERT(state == PR_UNJOINABLE_THREAD); michael@0: michael@0: #if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) || defined(XP_OS2) michael@0: michael@0: switch(index % 4) { michael@0: case 0: michael@0: scope = (PR_LOCAL_THREAD); michael@0: break; michael@0: case 1: michael@0: scope = (PR_GLOBAL_THREAD); michael@0: break; michael@0: case 2: michael@0: scope = (PR_GLOBAL_BOUND_THREAD); michael@0: break; michael@0: case 3: michael@0: native_thread = 1; michael@0: break; michael@0: default: michael@0: PR_ASSERT(!"Invalid scope"); michael@0: break; michael@0: } michael@0: if (native_thread) { michael@0: #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) michael@0: pthread_t tid; michael@0: if (!pthread_create(&tid, NULL, start, arg)) michael@0: return((PRThread *) tid); michael@0: else michael@0: return (NULL); michael@0: #elif defined(XP_OS2) michael@0: TID tid; michael@0: michael@0: tid = (TID)_beginthread((void(* _Optlink)(void*))start, michael@0: NULL, 32768, arg); michael@0: if (tid == -1) { michael@0: printf("_beginthread failed. errno %d\n", errno); michael@0: return (NULL); michael@0: } michael@0: else michael@0: return((PRThread *) tid); michael@0: #else michael@0: HANDLE thandle; michael@0: unsigned tid; michael@0: michael@0: thandle = (HANDLE) _beginthreadex( michael@0: NULL, michael@0: stackSize, michael@0: (unsigned (__stdcall *)(void *))start, michael@0: arg, michael@0: STACK_SIZE_PARAM_IS_A_RESERVATION, michael@0: &tid); michael@0: return((PRThread *) thandle); michael@0: #endif michael@0: } else { michael@0: return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); michael@0: } michael@0: #else michael@0: return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); michael@0: #endif michael@0: } michael@0: michael@0: static void PR_CALLBACK File_Write(void *arg) michael@0: { michael@0: PRFileDesc *fd_file; michael@0: File_Rdwr_Param *fp = (File_Rdwr_Param *) arg; michael@0: char *name, *buf; michael@0: int offset, len; michael@0: michael@0: setbuf(stdout, NULL); michael@0: name = fp->pathname; michael@0: buf = fp->buf; michael@0: offset = fp->offset; michael@0: len = fp->len; michael@0: michael@0: fd_file = PR_Open(name, PR_RDWR | PR_CREATE_FILE, 0777); michael@0: if (fd_file == NULL) { michael@0: printf("testfile failed to create/open file %s\n",name); michael@0: return; michael@0: } michael@0: if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { michael@0: printf("testfile failed to seek in file %s\n",name); michael@0: return; michael@0: } michael@0: if ((PR_Write(fd_file, buf, len)) < 0) { michael@0: printf("testfile failed to write to file %s\n",name); michael@0: return; michael@0: } michael@0: DPRINTF(("Write out_buf[0] = 0x%x\n",(*((int *) buf)))); michael@0: PR_Close(fd_file); michael@0: PR_DELETE(fp); michael@0: michael@0: PR_EnterMonitor(mon); michael@0: --thread_count; michael@0: PR_Notify(mon); michael@0: PR_ExitMonitor(mon); michael@0: } michael@0: michael@0: static void PR_CALLBACK File_Read(void *arg) michael@0: { michael@0: PRFileDesc *fd_file; michael@0: File_Rdwr_Param *fp = (File_Rdwr_Param *) arg; michael@0: char *name, *buf; michael@0: int offset, len; michael@0: michael@0: setbuf(stdout, NULL); michael@0: name = fp->pathname; michael@0: buf = fp->buf; michael@0: offset = fp->offset; michael@0: len = fp->len; michael@0: michael@0: fd_file = PR_Open(name, PR_RDONLY, 0); michael@0: if (fd_file == NULL) { michael@0: printf("testfile failed to open file %s\n",name); michael@0: return; michael@0: } michael@0: if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { michael@0: printf("testfile failed to seek in file %s\n",name); michael@0: return; michael@0: } michael@0: if ((PR_Read(fd_file, buf, len)) < 0) { michael@0: printf("testfile failed to read to file %s\n",name); michael@0: return; michael@0: } michael@0: DPRINTF(("Read in_buf[0] = 0x%x\n",(*((int *) buf)))); michael@0: PR_Close(fd_file); michael@0: PR_DELETE(fp); michael@0: michael@0: PR_EnterMonitor(mon); michael@0: --thread_count; michael@0: PR_Notify(mon); michael@0: PR_ExitMonitor(mon); michael@0: } michael@0: michael@0: michael@0: static PRInt32 Misc_File_Tests(char *pathname) michael@0: { michael@0: PRFileDesc *fd_file; michael@0: int len, rv = 0; michael@0: PRFileInfo file_info, file_info1; michael@0: char tmpname[1024]; michael@0: michael@0: setbuf(stdout, NULL); michael@0: /* michael@0: * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access michael@0: */ michael@0: michael@0: fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); michael@0: michael@0: if (fd_file == NULL) { michael@0: printf("testfile failed to create/open file %s\n",pathname); michael@0: return -1; michael@0: } michael@0: if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { michael@0: printf("testfile PR_GetFileInfo failed on file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: if (PR_Access(pathname, PR_ACCESS_EXISTS) != 0) { michael@0: printf("testfile PR_Access failed on file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: if (PR_Access(pathname, PR_ACCESS_WRITE_OK) != 0) { michael@0: printf("testfile PR_Access failed on file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: if (PR_Access(pathname, PR_ACCESS_READ_OK) != 0) { michael@0: printf("testfile PR_Access failed on file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: michael@0: michael@0: if (PR_GetFileInfo(pathname, &file_info) < 0) { michael@0: printf("testfile PR_GetFileInfo failed on file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: if (file_info.type != PR_FILE_FILE) { michael@0: printf( michael@0: "testfile: Error - PR_GetFileInfo returned incorrect type for file %s\n", michael@0: pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: if (file_info.size != 0) { michael@0: printf( michael@0: "testfile PR_GetFileInfo returned incorrect size (%d should be 0) for file %s\n", michael@0: file_info.size, pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: file_info1 = file_info; michael@0: michael@0: len = PR_Available(fd_file); michael@0: if (len < 0) { michael@0: printf("testfile PR_Available failed on file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } else if (len != 0) { michael@0: printf( michael@0: "testfile PR_Available failed: expected/returned = %d/%d bytes\n", michael@0: 0, len); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { michael@0: printf("testfile PR_GetFileInfo failed on file %s\n",pathname); michael@0: goto cleanup; michael@0: } michael@0: if (LL_NE(file_info.creationTime , file_info1.creationTime)) { michael@0: printf( michael@0: "testfile PR_GetFileInfo returned incorrect status-change time: %s\n", michael@0: pathname); michael@0: printf("ft = %lld, ft1 = %lld\n",file_info.creationTime, michael@0: file_info1.creationTime); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); michael@0: if (len < 0) { michael@0: printf("testfile failed to write to file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { michael@0: printf("testfile PR_GetFileInfo failed on file %s\n",pathname); michael@0: goto cleanup; michael@0: } michael@0: if (file_info.size != CHUNK_SIZE) { michael@0: printf( michael@0: "testfile PR_GetFileInfo returned incorrect size (%d should be %d) for file %s\n", michael@0: file_info.size, CHUNK_SIZE, pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: if (LL_CMP(file_info.modifyTime, < , file_info1.modifyTime)) { michael@0: printf( michael@0: "testfile PR_GetFileInfo returned incorrect modify time: %s\n", michael@0: pathname); michael@0: printf("ft = %lld, ft1 = %lld\n",file_info.modifyTime, michael@0: file_info1.modifyTime); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: michael@0: len = PR_Available(fd_file); michael@0: if (len < 0) { michael@0: printf("testfile PR_Available failed on file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } else if (len != 0) { michael@0: printf( michael@0: "testfile PR_Available failed: expected/returned = %d/%d bytes\n", michael@0: 0, len); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: michael@0: PR_Seek(fd_file, 0, PR_SEEK_SET); michael@0: len = PR_Available(fd_file); michael@0: if (len < 0) { michael@0: printf("testfile PR_Available failed on file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } else if (len != CHUNK_SIZE) { michael@0: printf( michael@0: "testfile PR_Available failed: expected/returned = %d/%d bytes\n", michael@0: CHUNK_SIZE, len); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: PR_Close(fd_file); michael@0: michael@0: strcpy(tmpname,pathname); michael@0: strcat(tmpname,".RENAMED"); michael@0: if (PR_FAILURE == PR_Rename(pathname, tmpname)) { michael@0: printf("testfile failed to rename file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: michael@0: fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); michael@0: len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); michael@0: PR_Close(fd_file); michael@0: if (PR_SUCCESS == PR_Rename(pathname, tmpname)) { michael@0: printf("testfile renamed to existing file %s\n",pathname); michael@0: } michael@0: michael@0: if ((PR_Delete(tmpname)) < 0) { michael@0: printf("testfile failed to unlink file %s\n",tmpname); michael@0: rv = -1; michael@0: } michael@0: michael@0: cleanup: michael@0: if ((PR_Delete(pathname)) < 0) { michael@0: printf("testfile failed to unlink file %s\n",pathname); michael@0: rv = -1; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: michael@0: static PRInt32 PR_CALLBACK FileTest(void) michael@0: { michael@0: PRDir *fd_dir; michael@0: int i, offset, len, rv = 0; michael@0: PRThread *t; michael@0: PRThreadScope scope = PR_GLOBAL_THREAD; michael@0: File_Rdwr_Param *fparamp; michael@0: michael@0: /* michael@0: * Create Test dir michael@0: */ michael@0: if ((PR_MkDir(TEST_DIR, 0777)) < 0) { michael@0: printf("testfile failed to create dir %s\n",TEST_DIR); michael@0: return -1; michael@0: } michael@0: fd_dir = PR_OpenDir(TEST_DIR); michael@0: if (fd_dir == NULL) { michael@0: printf("testfile failed to open dir %s\n",TEST_DIR); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: michael@0: PR_CloseDir(fd_dir); michael@0: michael@0: strcat(pathname, TEST_DIR); michael@0: strcat(pathname, "/"); michael@0: strcat(pathname, FILE_NAME); michael@0: michael@0: in_buf = PR_NEW(buffer); michael@0: if (in_buf == NULL) { michael@0: printf( michael@0: "testfile failed to alloc buffer struct\n"); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: out_buf = PR_NEW(buffer); michael@0: if (out_buf == NULL) { michael@0: printf( michael@0: "testfile failed to alloc buffer struct\n"); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: michael@0: /* michael@0: * Start a bunch of writer threads michael@0: */ michael@0: offset = 0; michael@0: len = CHUNK_SIZE; michael@0: PR_EnterMonitor(mon); michael@0: for (i = 0; i < NUM_RDWR_THREADS; i++) { michael@0: fparamp = PR_NEW(File_Rdwr_Param); michael@0: if (fparamp == NULL) { michael@0: printf( michael@0: "testfile failed to alloc File_Rdwr_Param struct\n"); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: fparamp->pathname = pathname; michael@0: fparamp->buf = out_buf->data + offset; michael@0: fparamp->offset = offset; michael@0: fparamp->len = len; michael@0: memset(fparamp->buf, i, len); michael@0: michael@0: t = create_new_thread(PR_USER_THREAD, michael@0: File_Write, (void *)fparamp, michael@0: PR_PRIORITY_NORMAL, michael@0: scope, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0, i); michael@0: offset += len; michael@0: } michael@0: thread_count = i; michael@0: /* Wait for writer threads to exit */ michael@0: while (thread_count) { michael@0: PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); michael@0: } michael@0: PR_ExitMonitor(mon); michael@0: michael@0: michael@0: /* michael@0: * Start a bunch of reader threads michael@0: */ michael@0: offset = 0; michael@0: len = CHUNK_SIZE; michael@0: PR_EnterMonitor(mon); michael@0: for (i = 0; i < NUM_RDWR_THREADS; i++) { michael@0: fparamp = PR_NEW(File_Rdwr_Param); michael@0: if (fparamp == NULL) { michael@0: printf( michael@0: "testfile failed to alloc File_Rdwr_Param struct\n"); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: fparamp->pathname = pathname; michael@0: fparamp->buf = in_buf->data + offset; michael@0: fparamp->offset = offset; michael@0: fparamp->len = len; michael@0: michael@0: t = create_new_thread(PR_USER_THREAD, michael@0: File_Read, (void *)fparamp, michael@0: PR_PRIORITY_NORMAL, michael@0: scope, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0, i); michael@0: offset += len; michael@0: if ((offset + len) > BUF_DATA_SIZE) michael@0: break; michael@0: } michael@0: thread_count = i; michael@0: michael@0: /* Wait for reader threads to exit */ michael@0: while (thread_count) { michael@0: PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); michael@0: } michael@0: PR_ExitMonitor(mon); michael@0: michael@0: if (memcmp(in_buf->data, out_buf->data, offset) != 0) { michael@0: printf("File Test failed: file data corrupted\n"); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: michael@0: if ((PR_Delete(pathname)) < 0) { michael@0: printf("testfile failed to unlink file %s\n",pathname); michael@0: rv = -1; michael@0: goto cleanup; michael@0: } michael@0: michael@0: /* michael@0: * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access michael@0: */ michael@0: if (Misc_File_Tests(pathname) < 0) { michael@0: rv = -1; michael@0: } michael@0: michael@0: cleanup: michael@0: if ((PR_RmDir(TEST_DIR)) < 0) { michael@0: printf("testfile failed to rmdir %s\n", TEST_DIR); michael@0: rv = -1; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: struct dirtest_arg { michael@0: PRMonitor *mon; michael@0: PRInt32 done; michael@0: }; michael@0: michael@0: static PRInt32 RunDirTest(void) michael@0: { michael@0: int i; michael@0: PRThread *t; michael@0: PRMonitor *mon; michael@0: struct dirtest_arg thrarg; michael@0: michael@0: mon = PR_NewMonitor(); michael@0: if (!mon) { michael@0: printf("RunDirTest: Error - failed to create monitor\n"); michael@0: dirtest_failed = 1; michael@0: return -1; michael@0: } michael@0: thrarg.mon = mon; michael@0: michael@0: for (i = 0; i < NUM_DIRTEST_THREADS; i++) { michael@0: michael@0: thrarg.done= 0; michael@0: t = create_new_thread(PR_USER_THREAD, michael@0: DirTest, &thrarg, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_LOCAL_THREAD, michael@0: PR_UNJOINABLE_THREAD, michael@0: 0, i); michael@0: if (!t) { michael@0: printf("RunDirTest: Error - failed to create thread\n"); michael@0: dirtest_failed = 1; michael@0: return -1; michael@0: } michael@0: PR_EnterMonitor(mon); michael@0: while (!thrarg.done) michael@0: PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); michael@0: PR_ExitMonitor(mon); michael@0: michael@0: } michael@0: PR_DestroyMonitor(mon); michael@0: return 0; michael@0: } michael@0: michael@0: static PRInt32 PR_CALLBACK DirTest(void *arg) michael@0: { michael@0: struct dirtest_arg *tinfo = (struct dirtest_arg *) arg; michael@0: PRFileDesc *fd_file; michael@0: PRDir *fd_dir; michael@0: int i; michael@0: int path_len; michael@0: PRDirEntry *dirEntry; michael@0: PRFileInfo info; michael@0: PRInt32 num_files = 0; michael@0: #if defined(XP_PC) && defined(WIN32) michael@0: HANDLE hfile; michael@0: #endif michael@0: michael@0: #define FILES_IN_DIR 20 michael@0: michael@0: /* michael@0: * Create Test dir michael@0: */ michael@0: DPRINTF(("Creating test dir %s\n",TEST_DIR)); michael@0: if ((PR_MkDir(TEST_DIR, 0777)) < 0) { michael@0: printf( michael@0: "testfile failed to create dir %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: fd_dir = PR_OpenDir(TEST_DIR); michael@0: if (fd_dir == NULL) { michael@0: printf( michael@0: "testfile failed to open dirctory %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: strcpy(pathname, TEST_DIR); michael@0: strcat(pathname, "/"); michael@0: strcat(pathname, FILE_NAME); michael@0: path_len = strlen(pathname); michael@0: michael@0: for (i = 0; i < FILES_IN_DIR; i++) { michael@0: michael@0: sprintf(pathname + path_len,"%d%s",i,""); michael@0: michael@0: DPRINTF(("Creating test file %s\n",pathname)); michael@0: michael@0: fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); michael@0: michael@0: if (fd_file == NULL) { michael@0: printf( michael@0: "testfile failed to create/open file %s [%d, %d]\n", michael@0: pathname, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: PR_Close(fd_file); michael@0: } michael@0: #if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) michael@0: /* michael@0: * Create a hidden file - a platform-dependent operation michael@0: */ michael@0: strcpy(pathname, TEST_DIR); michael@0: strcat(pathname, "/"); michael@0: strcat(pathname, HIDDEN_FILE_NAME); michael@0: #if defined(XP_UNIX) || defined(XP_BEOS) michael@0: DPRINTF(("Creating hidden test file %s\n",pathname)); michael@0: fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); michael@0: michael@0: if (fd_file == NULL) { michael@0: printf( michael@0: "testfile failed to create/open hidden file %s [%d, %d]\n", michael@0: pathname, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: PR_Close(fd_file); michael@0: michael@0: #elif defined(WINCE) michael@0: DPRINTF(("Creating hidden test file %s\n",pathname)); michael@0: MultiByteToWideChar(CP_ACP, 0, pathname, -1, wPathname, 256); michael@0: hfile = CreateFile(wPathname, GENERIC_READ, michael@0: FILE_SHARE_READ|FILE_SHARE_WRITE, michael@0: NULL, michael@0: CREATE_NEW, michael@0: FILE_ATTRIBUTE_HIDDEN, michael@0: NULL); michael@0: if (hfile == INVALID_HANDLE_VALUE) { michael@0: printf("testfile failed to create/open hidden file %s [0, %d]\n", michael@0: pathname, GetLastError()); michael@0: return -1; michael@0: } michael@0: CloseHandle(hfile); michael@0: michael@0: #elif defined(XP_PC) && defined(WIN32) michael@0: DPRINTF(("Creating hidden test file %s\n",pathname)); michael@0: hfile = CreateFile(pathname, GENERIC_READ, michael@0: FILE_SHARE_READ|FILE_SHARE_WRITE, michael@0: NULL, michael@0: CREATE_NEW, michael@0: FILE_ATTRIBUTE_HIDDEN, michael@0: NULL); michael@0: if (hfile == INVALID_HANDLE_VALUE) { michael@0: printf("testfile failed to create/open hidden file %s [0, %d]\n", michael@0: pathname, GetLastError()); michael@0: return -1; michael@0: } michael@0: CloseHandle(hfile); michael@0: michael@0: #elif defined(OS2) michael@0: DPRINTF(("Creating hidden test file %s\n",pathname)); michael@0: fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, (int)FILE_HIDDEN); michael@0: michael@0: if (fd_file == NULL) { michael@0: printf("testfile failed to create/open hidden file %s [%d, %d]\n", michael@0: pathname, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: PR_Close(fd_file); michael@0: #endif /* XP_UNIX */ michael@0: michael@0: #endif /* XP_UNIX || (XP_PC && WIN32) */ michael@0: michael@0: michael@0: if (PR_FAILURE == PR_CloseDir(fd_dir)) michael@0: { michael@0: printf( michael@0: "testfile failed to close dirctory %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: fd_dir = PR_OpenDir(TEST_DIR); michael@0: if (fd_dir == NULL) { michael@0: printf( michael@0: "testfile failed to reopen dirctory %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: /* michael@0: * List all files, including hidden files michael@0: */ michael@0: DPRINTF(("Listing all files in directory %s\n",TEST_DIR)); michael@0: #if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) michael@0: num_files = FILES_IN_DIR + 1; michael@0: #else michael@0: num_files = FILES_IN_DIR; michael@0: #endif michael@0: while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_BOTH)) != NULL) { michael@0: num_files--; michael@0: strcpy(pathname, TEST_DIR); michael@0: strcat(pathname, "/"); michael@0: strcat(pathname, dirEntry->name); michael@0: DPRINTF(("\t%s\n",dirEntry->name)); michael@0: michael@0: if ((PR_GetFileInfo(pathname, &info)) < 0) { michael@0: printf( michael@0: "testfile failed to GetFileInfo file %s [%d, %d]\n", michael@0: pathname, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: if (info.type != PR_FILE_FILE) { michael@0: printf( michael@0: "testfile incorrect fileinfo for file %s [%d, %d]\n", michael@0: pathname, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: } michael@0: if (num_files != 0) michael@0: { michael@0: printf( michael@0: "testfile failed to find all files in directory %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: PR_CloseDir(fd_dir); michael@0: michael@0: #if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) michael@0: michael@0: /* michael@0: * List all files, except hidden files michael@0: */ michael@0: michael@0: fd_dir = PR_OpenDir(TEST_DIR); michael@0: if (fd_dir == NULL) { michael@0: printf( michael@0: "testfile failed to reopen dirctory %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: DPRINTF(("Listing non-hidden files in directory %s\n",TEST_DIR)); michael@0: while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_HIDDEN)) != NULL) { michael@0: DPRINTF(("\t%s\n",dirEntry->name)); michael@0: if (!strcmp(HIDDEN_FILE_NAME, dirEntry->name)) { michael@0: printf("testfile found hidden file %s\n", pathname); michael@0: return -1; michael@0: } michael@0: michael@0: } michael@0: /* michael@0: * Delete hidden file michael@0: */ michael@0: strcpy(pathname, TEST_DIR); michael@0: strcat(pathname, "/"); michael@0: strcat(pathname, HIDDEN_FILE_NAME); michael@0: if (PR_FAILURE == PR_Delete(pathname)) { michael@0: printf( michael@0: "testfile failed to delete hidden file %s [%d, %d]\n", michael@0: pathname, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: PR_CloseDir(fd_dir); michael@0: #endif /* XP_UNIX || (XP_PC && WIN32) */ michael@0: michael@0: strcpy(renamename, TEST_DIR); michael@0: strcat(renamename, ".RENAMED"); michael@0: if (PR_FAILURE == PR_Rename(TEST_DIR, renamename)) { michael@0: printf( michael@0: "testfile failed to rename directory %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: if (PR_FAILURE == PR_MkDir(TEST_DIR, 0777)) { michael@0: printf( michael@0: "testfile failed to recreate dir %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: if (PR_SUCCESS == PR_Rename(renamename, TEST_DIR)) { michael@0: printf( michael@0: "testfile renamed directory to existing name %s\n", michael@0: renamename); michael@0: return -1; michael@0: } michael@0: michael@0: if (PR_FAILURE == PR_RmDir(TEST_DIR)) { michael@0: printf( michael@0: "testfile failed to rmdir %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: if (PR_FAILURE == PR_Rename(renamename, TEST_DIR)) { michael@0: printf( michael@0: "testfile failed to rename directory %s [%d, %d]\n", michael@0: renamename, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: fd_dir = PR_OpenDir(TEST_DIR); michael@0: if (fd_dir == NULL) { michael@0: printf( michael@0: "testfile failed to reopen directory %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: michael@0: strcpy(pathname, TEST_DIR); michael@0: strcat(pathname, "/"); michael@0: strcat(pathname, FILE_NAME); michael@0: path_len = strlen(pathname); michael@0: michael@0: for (i = 0; i < FILES_IN_DIR; i++) { michael@0: michael@0: sprintf(pathname + path_len,"%d%s",i,""); michael@0: michael@0: if (PR_FAILURE == PR_Delete(pathname)) { michael@0: printf( michael@0: "testfile failed to delete file %s [%d, %d]\n", michael@0: pathname, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: } michael@0: michael@0: PR_CloseDir(fd_dir); michael@0: michael@0: if (PR_FAILURE == PR_RmDir(TEST_DIR)) { michael@0: printf( michael@0: "testfile failed to rmdir %s [%d, %d]\n", michael@0: TEST_DIR, PR_GetError(), PR_GetOSError()); michael@0: return -1; michael@0: } michael@0: PR_EnterMonitor(tinfo->mon); michael@0: tinfo->done = 1; michael@0: PR_Notify(tinfo->mon); michael@0: PR_ExitMonitor(tinfo->mon); michael@0: michael@0: return 0; michael@0: } michael@0: /************************************************************************/ michael@0: michael@0: /* michael@0: * Test file and directory NSPR APIs michael@0: */ michael@0: michael@0: int main(int argc, char **argv) michael@0: { michael@0: #ifdef WIN32 michael@0: PRUint32 len; michael@0: #endif michael@0: #if defined(XP_UNIX) || defined(XP_OS2) michael@0: int opt; michael@0: extern char *optarg; michael@0: extern int optind; michael@0: #endif michael@0: #if defined(XP_UNIX) || defined(XP_OS2) michael@0: while ((opt = getopt(argc, argv, "d")) != EOF) { michael@0: switch(opt) { michael@0: case 'd': michael@0: _debug_on = 1; michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: } michael@0: #endif michael@0: PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); michael@0: PR_STDIO_INIT(); michael@0: michael@0: mon = PR_NewMonitor(); michael@0: if (mon == NULL) { michael@0: printf("testfile: PR_NewMonitor failed\n"); michael@0: exit(2); michael@0: } michael@0: #ifdef WIN32 michael@0: michael@0: #ifdef WINCE michael@0: { michael@0: WCHAR tdir[TMPDIR_LEN]; michael@0: len = GetTempPath(TMPDIR_LEN, tdir); michael@0: if ((len > 0) && (len < (TMPDIR_LEN - 6))) { michael@0: /* michael@0: * enough space for prdir michael@0: */ michael@0: WideCharToMultiByte(CP_ACP, 0, tdir, -1, testdir, TMPDIR_LEN, 0, 0); michael@0: } michael@0: } michael@0: #else michael@0: len = GetTempPath(TMPDIR_LEN, testdir); michael@0: #endif /* WINCE */ michael@0: michael@0: if ((len > 0) && (len < (TMPDIR_LEN - 6))) { michael@0: /* michael@0: * enough space for prdir michael@0: */ michael@0: strcpy((testdir + len),"prdir"); michael@0: TEST_DIR = testdir; michael@0: printf("TEST_DIR = %s\n",TEST_DIR); michael@0: } michael@0: #endif /* WIN32 */ michael@0: michael@0: if (FileTest() < 0) { michael@0: printf("File Test failed\n"); michael@0: exit(2); michael@0: } michael@0: printf("File Test passed\n"); michael@0: if ((RunDirTest() < 0) || dirtest_failed) { michael@0: printf("Dir Test failed\n"); michael@0: exit(2); michael@0: } michael@0: printf("Dir Test passed\n"); michael@0: michael@0: PR_DestroyMonitor(mon); michael@0: PR_Cleanup(); michael@0: return 0; michael@0: }