| /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| /* ***** BEGIN LICENSE BLOCK ***** |
| * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| * |
| * The contents of this file are subject to the Mozilla Public License Version |
| * 1.1 (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * http://www.mozilla.org/MPL/ |
| * |
| * Software distributed under the License is distributed on an "AS IS" basis, |
| * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| * for the specific language governing rights and limitations under the |
| * License. |
| * |
| * The Original Code is the Netscape Portable Runtime (NSPR). |
| * |
| * The Initial Developer of the Original Code is |
| * Netscape Communications Corporation. |
| * Portions created by the Initial Developer are Copyright (C) 1998-2000 |
| * the Initial Developer. All Rights Reserved. |
| * |
| * Contributor(s): |
| * |
| * Alternatively, the contents of this file may be used under the terms of |
| * either the GNU General Public License Version 2 or later (the "GPL"), or |
| * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
| * in which case the provisions of the GPL or the LGPL are applicable instead |
| * of those above. If you wish to allow use of your version of this file only |
| * under the terms of either the GPL or the LGPL, and not to allow others to |
| * use your version of this file under the terms of the MPL, indicate your |
| * decision by deleting the provisions above and replace them with the notice |
| * and other provisions required by the GPL or the LGPL. If you do not delete |
| * the provisions above, a recipient may use your version of this file under |
| * the terms of any one of the MPL, the GPL or the LGPL. |
| * |
| * ***** END LICENSE BLOCK ***** */ |
| |
| #include "nspr.h" |
| #include "prpriv.h" |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #ifdef WIN32 |
| #include <windows.h> |
| #include <process.h> |
| #endif |
| #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) |
| #include <pthread.h> |
| #endif |
| #ifdef SYMBIAN |
| #include <getopt.h> |
| #endif |
| |
| #if defined(XP_OS2) |
| #define INCL_DOSFILEMGR |
| #include <os2.h> |
| #include <getopt.h> |
| #include <errno.h> |
| #endif /* XP_OS2 */ |
| |
| static int _debug_on = 0; |
| |
| #ifdef WINCE |
| #define setbuf(x,y) |
| #endif |
| |
| #ifdef XP_WIN |
| #define mode_t int |
| #endif |
| |
| #define DPRINTF(arg) if (_debug_on) printf arg |
| |
| PRLock *lock; |
| PRMonitor *mon; |
| PRInt32 count; |
| int thread_count; |
| |
| #ifdef WIN16 |
| #define BUF_DATA_SIZE 256 * 120 |
| #else |
| #define BUF_DATA_SIZE 256 * 1024 |
| #endif |
| |
| #define NUM_RDWR_THREADS 10 |
| #define NUM_DIRTEST_THREADS 4 |
| #define CHUNK_SIZE 512 |
| |
| typedef struct buffer { |
| char data[BUF_DATA_SIZE]; |
| } buffer; |
| |
| typedef struct File_Rdwr_Param { |
| char *pathname; |
| char *buf; |
| int offset; |
| int len; |
| } File_Rdwr_Param; |
| |
| #ifdef XP_PC |
| #ifdef XP_OS2 |
| char *TEST_DIR = "prdir"; |
| #else |
| char *TEST_DIR = "C:\\temp\\prdir"; |
| #endif |
| char *FILE_NAME = "pr_testfile"; |
| char *HIDDEN_FILE_NAME = "hidden_pr_testfile"; |
| #else |
| #ifdef SYMBIAN |
| char *TEST_DIR = "c:\\data\\testfile_dir"; |
| #else |
| char *TEST_DIR = "/tmp/testfile_dir"; |
| #endif |
| char *FILE_NAME = "pr_testfile"; |
| char *HIDDEN_FILE_NAME = ".hidden_pr_testfile"; |
| #endif |
| buffer *in_buf, *out_buf; |
| char pathname[256], renamename[256]; |
| #ifdef WINCE |
| WCHAR wPathname[256]; |
| #endif |
| #define TMPDIR_LEN 64 |
| char testdir[TMPDIR_LEN]; |
| static PRInt32 PR_CALLBACK DirTest(void *argunused); |
| PRInt32 dirtest_failed = 0; |
| |
| PRThread* create_new_thread(PRThreadType type, |
| void (*start)(void *arg), |
| void *arg, |
| PRThreadPriority priority, |
| PRThreadScope scope, |
| PRThreadState state, |
| PRUint32 stackSize, PRInt32 index) |
| { |
| PRInt32 native_thread = 0; |
| |
| PR_ASSERT(state == PR_UNJOINABLE_THREAD); |
| |
| #if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) || defined(XP_OS2) |
| |
| switch(index % 4) { |
| case 0: |
| scope = (PR_LOCAL_THREAD); |
| break; |
| case 1: |
| scope = (PR_GLOBAL_THREAD); |
| break; |
| case 2: |
| scope = (PR_GLOBAL_BOUND_THREAD); |
| break; |
| case 3: |
| native_thread = 1; |
| break; |
| default: |
| PR_ASSERT(!"Invalid scope"); |
| break; |
| } |
| if (native_thread) { |
| #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) |
| pthread_t tid; |
| if (!pthread_create(&tid, NULL, start, arg)) |
| return((PRThread *) tid); |
| else |
| return (NULL); |
| #elif defined(XP_OS2) |
| TID tid; |
| |
| tid = (TID)_beginthread((void(* _Optlink)(void*))start, |
| NULL, 32768, arg); |
| if (tid == -1) { |
| printf("_beginthread failed. errno %d\n", errno); |
| return (NULL); |
| } |
| else |
| return((PRThread *) tid); |
| #else |
| HANDLE thandle; |
| unsigned tid; |
| |
| thandle = (HANDLE) _beginthreadex( |
| NULL, |
| stackSize, |
| (unsigned (__stdcall *)(void *))start, |
| arg, |
| 0, |
| &tid); |
| return((PRThread *) thandle); |
| #endif |
| } else { |
| return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); |
| } |
| #else |
| return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); |
| #endif |
| } |
| |
| static void PR_CALLBACK File_Write(void *arg) |
| { |
| PRFileDesc *fd_file; |
| File_Rdwr_Param *fp = (File_Rdwr_Param *) arg; |
| char *name, *buf; |
| int offset, len; |
| |
| setbuf(stdout, NULL); |
| name = fp->pathname; |
| buf = fp->buf; |
| offset = fp->offset; |
| len = fp->len; |
| |
| fd_file = PR_Open(name, PR_RDWR | PR_CREATE_FILE, 0777); |
| if (fd_file == NULL) { |
| printf("testfile failed to create/open file %s\n",name); |
| return; |
| } |
| if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { |
| printf("testfile failed to seek in file %s\n",name); |
| return; |
| } |
| if ((PR_Write(fd_file, buf, len)) < 0) { |
| printf("testfile failed to write to file %s\n",name); |
| return; |
| } |
| DPRINTF(("Write out_buf[0] = 0x%x\n",(*((int *) buf)))); |
| PR_Close(fd_file); |
| PR_DELETE(fp); |
| |
| PR_EnterMonitor(mon); |
| --thread_count; |
| PR_Notify(mon); |
| PR_ExitMonitor(mon); |
| } |
| |
| static void PR_CALLBACK File_Read(void *arg) |
| { |
| PRFileDesc *fd_file; |
| File_Rdwr_Param *fp = (File_Rdwr_Param *) arg; |
| char *name, *buf; |
| int offset, len; |
| |
| setbuf(stdout, NULL); |
| name = fp->pathname; |
| buf = fp->buf; |
| offset = fp->offset; |
| len = fp->len; |
| |
| fd_file = PR_Open(name, PR_RDONLY, 0); |
| if (fd_file == NULL) { |
| printf("testfile failed to open file %s\n",name); |
| return; |
| } |
| if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { |
| printf("testfile failed to seek in file %s\n",name); |
| return; |
| } |
| if ((PR_Read(fd_file, buf, len)) < 0) { |
| printf("testfile failed to read to file %s\n",name); |
| return; |
| } |
| DPRINTF(("Read in_buf[0] = 0x%x\n",(*((int *) buf)))); |
| PR_Close(fd_file); |
| PR_DELETE(fp); |
| |
| PR_EnterMonitor(mon); |
| --thread_count; |
| PR_Notify(mon); |
| PR_ExitMonitor(mon); |
| } |
| |
| |
| static PRInt32 Misc_File_Tests(char *pathname) |
| { |
| PRFileDesc *fd_file; |
| int len, rv = 0; |
| PRFileInfo file_info, file_info1; |
| char tmpname[1024]; |
| |
| setbuf(stdout, NULL); |
| /* |
| * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access |
| */ |
| |
| fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); |
| |
| if (fd_file == NULL) { |
| printf("testfile failed to create/open file %s\n",pathname); |
| return -1; |
| } |
| if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { |
| printf("testfile PR_GetFileInfo failed on file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| if (PR_Access(pathname, PR_ACCESS_EXISTS) != 0) { |
| printf("testfile PR_Access failed on file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| if (PR_Access(pathname, PR_ACCESS_WRITE_OK) != 0) { |
| printf("testfile PR_Access failed on file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| if (PR_Access(pathname, PR_ACCESS_READ_OK) != 0) { |
| printf("testfile PR_Access failed on file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| |
| |
| if (PR_GetFileInfo(pathname, &file_info) < 0) { |
| printf("testfile PR_GetFileInfo failed on file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| if (file_info.type != PR_FILE_FILE) { |
| printf( |
| "testfile: Error - PR_GetFileInfo returned incorrect type for file %s\n", |
| pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| if (file_info.size != 0) { |
| printf( |
| "testfile PR_GetFileInfo returned incorrect size (%d should be 0) for file %s\n", |
| file_info.size, pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| file_info1 = file_info; |
| |
| len = PR_Available(fd_file); |
| if (len < 0) { |
| printf("testfile PR_Available failed on file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } else if (len != 0) { |
| printf( |
| "testfile PR_Available failed: expected/returned = %d/%d bytes\n", |
| 0, len); |
| rv = -1; |
| goto cleanup; |
| } |
| if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { |
| printf("testfile PR_GetFileInfo failed on file %s\n",pathname); |
| goto cleanup; |
| } |
| if (LL_NE(file_info.creationTime , file_info1.creationTime)) { |
| printf( |
| "testfile PR_GetFileInfo returned incorrect status-change time: %s\n", |
| pathname); |
| printf("ft = %lld, ft1 = %lld\n",file_info.creationTime, |
| file_info1.creationTime); |
| rv = -1; |
| goto cleanup; |
| } |
| len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); |
| if (len < 0) { |
| printf("testfile failed to write to file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { |
| printf("testfile PR_GetFileInfo failed on file %s\n",pathname); |
| goto cleanup; |
| } |
| if (file_info.size != CHUNK_SIZE) { |
| printf( |
| "testfile PR_GetFileInfo returned incorrect size (%d should be %d) for file %s\n", |
| file_info.size, CHUNK_SIZE, pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| if (LL_CMP(file_info.modifyTime, < , file_info1.modifyTime)) { |
| printf( |
| "testfile PR_GetFileInfo returned incorrect modify time: %s\n", |
| pathname); |
| printf("ft = %lld, ft1 = %lld\n",file_info.modifyTime, |
| file_info1.modifyTime); |
| rv = -1; |
| goto cleanup; |
| } |
| |
| len = PR_Available(fd_file); |
| if (len < 0) { |
| printf("testfile PR_Available failed on file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } else if (len != 0) { |
| printf( |
| "testfile PR_Available failed: expected/returned = %d/%d bytes\n", |
| 0, len); |
| rv = -1; |
| goto cleanup; |
| } |
| |
| PR_Seek(fd_file, 0, PR_SEEK_SET); |
| len = PR_Available(fd_file); |
| if (len < 0) { |
| printf("testfile PR_Available failed on file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } else if (len != CHUNK_SIZE) { |
| printf( |
| "testfile PR_Available failed: expected/returned = %d/%d bytes\n", |
| CHUNK_SIZE, len); |
| rv = -1; |
| goto cleanup; |
| } |
| PR_Close(fd_file); |
| |
| strcpy(tmpname,pathname); |
| strcat(tmpname,".RENAMED"); |
| if (PR_FAILURE == PR_Rename(pathname, tmpname)) { |
| printf("testfile failed to rename file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| |
| fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); |
| len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); |
| PR_Close(fd_file); |
| if (PR_SUCCESS == PR_Rename(pathname, tmpname)) { |
| printf("testfile renamed to existing file %s\n",pathname); |
| } |
| |
| if ((PR_Delete(tmpname)) < 0) { |
| printf("testfile failed to unlink file %s\n",tmpname); |
| rv = -1; |
| } |
| |
| cleanup: |
| if ((PR_Delete(pathname)) < 0) { |
| printf("testfile failed to unlink file %s\n",pathname); |
| rv = -1; |
| } |
| return rv; |
| } |
| |
| |
| static PRInt32 PR_CALLBACK FileTest(void) |
| { |
| PRDir *fd_dir; |
| int i, offset, len, rv = 0; |
| PRThread *t; |
| PRThreadScope scope = PR_GLOBAL_THREAD; |
| File_Rdwr_Param *fparamp; |
| |
| /* |
| * Create Test dir |
| */ |
| if ((PR_MkDir(TEST_DIR, 0777)) < 0) { |
| printf("testfile failed to create dir %s\n",TEST_DIR); |
| return -1; |
| } |
| fd_dir = PR_OpenDir(TEST_DIR); |
| if (fd_dir == NULL) { |
| printf("testfile failed to open dir %s\n",TEST_DIR); |
| rv = -1; |
| goto cleanup; |
| } |
| |
| PR_CloseDir(fd_dir); |
| |
| strcat(pathname, TEST_DIR); |
| strcat(pathname, "/"); |
| strcat(pathname, FILE_NAME); |
| |
| in_buf = PR_NEW(buffer); |
| if (in_buf == NULL) { |
| printf( |
| "testfile failed to alloc buffer struct\n"); |
| rv = -1; |
| goto cleanup; |
| } |
| out_buf = PR_NEW(buffer); |
| if (out_buf == NULL) { |
| printf( |
| "testfile failed to alloc buffer struct\n"); |
| rv = -1; |
| goto cleanup; |
| } |
| |
| /* |
| * Start a bunch of writer threads |
| */ |
| offset = 0; |
| len = CHUNK_SIZE; |
| PR_EnterMonitor(mon); |
| for (i = 0; i < NUM_RDWR_THREADS; i++) { |
| fparamp = PR_NEW(File_Rdwr_Param); |
| if (fparamp == NULL) { |
| printf( |
| "testfile failed to alloc File_Rdwr_Param struct\n"); |
| rv = -1; |
| goto cleanup; |
| } |
| fparamp->pathname = pathname; |
| fparamp->buf = out_buf->data + offset; |
| fparamp->offset = offset; |
| fparamp->len = len; |
| memset(fparamp->buf, i, len); |
| |
| t = create_new_thread(PR_USER_THREAD, |
| File_Write, (void *)fparamp, |
| PR_PRIORITY_NORMAL, |
| scope, |
| PR_UNJOINABLE_THREAD, |
| 0, i); |
| offset += len; |
| } |
| thread_count = i; |
| /* Wait for writer threads to exit */ |
| while (thread_count) { |
| PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); |
| } |
| PR_ExitMonitor(mon); |
| |
| |
| /* |
| * Start a bunch of reader threads |
| */ |
| offset = 0; |
| len = CHUNK_SIZE; |
| PR_EnterMonitor(mon); |
| for (i = 0; i < NUM_RDWR_THREADS; i++) { |
| fparamp = PR_NEW(File_Rdwr_Param); |
| if (fparamp == NULL) { |
| printf( |
| "testfile failed to alloc File_Rdwr_Param struct\n"); |
| rv = -1; |
| goto cleanup; |
| } |
| fparamp->pathname = pathname; |
| fparamp->buf = in_buf->data + offset; |
| fparamp->offset = offset; |
| fparamp->len = len; |
| |
| t = create_new_thread(PR_USER_THREAD, |
| File_Read, (void *)fparamp, |
| PR_PRIORITY_NORMAL, |
| scope, |
| PR_UNJOINABLE_THREAD, |
| 0, i); |
| offset += len; |
| if ((offset + len) > BUF_DATA_SIZE) |
| break; |
| } |
| thread_count = i; |
| |
| /* Wait for reader threads to exit */ |
| while (thread_count) { |
| PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); |
| } |
| PR_ExitMonitor(mon); |
| |
| if (memcmp(in_buf->data, out_buf->data, offset) != 0) { |
| printf("File Test failed: file data corrupted\n"); |
| rv = -1; |
| goto cleanup; |
| } |
| |
| if ((PR_Delete(pathname)) < 0) { |
| printf("testfile failed to unlink file %s\n",pathname); |
| rv = -1; |
| goto cleanup; |
| } |
| |
| /* |
| * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access |
| */ |
| if (Misc_File_Tests(pathname) < 0) { |
| rv = -1; |
| } |
| |
| cleanup: |
| if ((PR_RmDir(TEST_DIR)) < 0) { |
| printf("testfile failed to rmdir %s\n", TEST_DIR); |
| rv = -1; |
| } |
| return rv; |
| } |
| |
| struct dirtest_arg { |
| PRMonitor *mon; |
| PRInt32 done; |
| }; |
| |
| static PRInt32 RunDirTest(void) |
| { |
| int i; |
| PRThread *t; |
| PRMonitor *mon; |
| struct dirtest_arg thrarg; |
| |
| mon = PR_NewMonitor(); |
| if (!mon) { |
| printf("RunDirTest: Error - failed to create monitor\n"); |
| dirtest_failed = 1; |
| return -1; |
| } |
| thrarg.mon = mon; |
| |
| for (i = 0; i < NUM_DIRTEST_THREADS; i++) { |
| |
| thrarg.done= 0; |
| t = create_new_thread(PR_USER_THREAD, |
| DirTest, &thrarg, |
| PR_PRIORITY_NORMAL, |
| PR_LOCAL_THREAD, |
| PR_UNJOINABLE_THREAD, |
| 0, i); |
| if (!t) { |
| printf("RunDirTest: Error - failed to create thread\n"); |
| dirtest_failed = 1; |
| return -1; |
| } |
| PR_EnterMonitor(mon); |
| while (!thrarg.done) |
| PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); |
| PR_ExitMonitor(mon); |
| |
| } |
| PR_DestroyMonitor(mon); |
| return 0; |
| } |
| |
| static PRInt32 PR_CALLBACK DirTest(void *arg) |
| { |
| struct dirtest_arg *tinfo = (struct dirtest_arg *) arg; |
| PRFileDesc *fd_file; |
| PRDir *fd_dir; |
| int i; |
| int path_len; |
| PRDirEntry *dirEntry; |
| PRFileInfo info; |
| PRInt32 num_files = 0; |
| #if defined(XP_PC) && defined(WIN32) |
| HANDLE hfile; |
| #endif |
| |
| #define FILES_IN_DIR 20 |
| |
| /* |
| * Create Test dir |
| */ |
| DPRINTF(("Creating test dir %s\n",TEST_DIR)); |
| if ((PR_MkDir(TEST_DIR, 0777)) < 0) { |
| printf( |
| "testfile failed to create dir %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| fd_dir = PR_OpenDir(TEST_DIR); |
| if (fd_dir == NULL) { |
| printf( |
| "testfile failed to open dirctory %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| strcpy(pathname, TEST_DIR); |
| strcat(pathname, "/"); |
| strcat(pathname, FILE_NAME); |
| path_len = strlen(pathname); |
| |
| for (i = 0; i < FILES_IN_DIR; i++) { |
| |
| sprintf(pathname + path_len,"%d%s",i,""); |
| |
| DPRINTF(("Creating test file %s\n",pathname)); |
| |
| fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); |
| |
| if (fd_file == NULL) { |
| printf( |
| "testfile failed to create/open file %s [%d, %d]\n", |
| pathname, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| PR_Close(fd_file); |
| } |
| #if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) |
| /* |
| * Create a hidden file - a platform-dependent operation |
| */ |
| strcpy(pathname, TEST_DIR); |
| strcat(pathname, "/"); |
| strcat(pathname, HIDDEN_FILE_NAME); |
| #if defined(XP_UNIX) || defined(XP_BEOS) |
| DPRINTF(("Creating hidden test file %s\n",pathname)); |
| fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); |
| |
| if (fd_file == NULL) { |
| printf( |
| "testfile failed to create/open hidden file %s [%d, %d]\n", |
| pathname, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| PR_Close(fd_file); |
| |
| #elif defined(WINCE) |
| DPRINTF(("Creating hidden test file %s\n",pathname)); |
| MultiByteToWideChar(CP_ACP, 0, pathname, -1, wPathname, 256); |
| hfile = CreateFile(wPathname, GENERIC_READ, |
| FILE_SHARE_READ|FILE_SHARE_WRITE, |
| NULL, |
| CREATE_NEW, |
| FILE_ATTRIBUTE_HIDDEN, |
| NULL); |
| if (hfile == INVALID_HANDLE_VALUE) { |
| printf("testfile failed to create/open hidden file %s [0, %d]\n", |
| pathname, GetLastError()); |
| return -1; |
| } |
| CloseHandle(hfile); |
| |
| #elif defined(XP_PC) && defined(WIN32) |
| DPRINTF(("Creating hidden test file %s\n",pathname)); |
| hfile = CreateFile(pathname, GENERIC_READ, |
| FILE_SHARE_READ|FILE_SHARE_WRITE, |
| NULL, |
| CREATE_NEW, |
| FILE_ATTRIBUTE_HIDDEN, |
| NULL); |
| if (hfile == INVALID_HANDLE_VALUE) { |
| printf("testfile failed to create/open hidden file %s [0, %d]\n", |
| pathname, GetLastError()); |
| return -1; |
| } |
| CloseHandle(hfile); |
| |
| #elif defined(OS2) |
| DPRINTF(("Creating hidden test file %s\n",pathname)); |
| fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, (int)FILE_HIDDEN); |
| |
| if (fd_file == NULL) { |
| printf("testfile failed to create/open hidden file %s [%d, %d]\n", |
| pathname, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| PR_Close(fd_file); |
| #endif /* XP_UNIX */ |
| |
| #endif /* XP_UNIX || (XP_PC && WIN32) */ |
| |
| |
| if (PR_FAILURE == PR_CloseDir(fd_dir)) |
| { |
| printf( |
| "testfile failed to close dirctory %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| fd_dir = PR_OpenDir(TEST_DIR); |
| if (fd_dir == NULL) { |
| printf( |
| "testfile failed to reopen dirctory %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| /* |
| * List all files, including hidden files |
| */ |
| DPRINTF(("Listing all files in directory %s\n",TEST_DIR)); |
| #if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) |
| num_files = FILES_IN_DIR + 1; |
| #else |
| num_files = FILES_IN_DIR; |
| #endif |
| while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_BOTH)) != NULL) { |
| num_files--; |
| strcpy(pathname, TEST_DIR); |
| strcat(pathname, "/"); |
| strcat(pathname, dirEntry->name); |
| DPRINTF(("\t%s\n",dirEntry->name)); |
| |
| if ((PR_GetFileInfo(pathname, &info)) < 0) { |
| printf( |
| "testfile failed to GetFileInfo file %s [%d, %d]\n", |
| pathname, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| if (info.type != PR_FILE_FILE) { |
| printf( |
| "testfile incorrect fileinfo for file %s [%d, %d]\n", |
| pathname, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| } |
| if (num_files != 0) |
| { |
| printf( |
| "testfile failed to find all files in directory %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| PR_CloseDir(fd_dir); |
| |
| #if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) |
| |
| /* |
| * List all files, except hidden files |
| */ |
| |
| fd_dir = PR_OpenDir(TEST_DIR); |
| if (fd_dir == NULL) { |
| printf( |
| "testfile failed to reopen dirctory %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| DPRINTF(("Listing non-hidden files in directory %s\n",TEST_DIR)); |
| while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_HIDDEN)) != NULL) { |
| DPRINTF(("\t%s\n",dirEntry->name)); |
| if (!strcmp(HIDDEN_FILE_NAME, dirEntry->name)) { |
| printf("testfile found hidden file %s\n", pathname); |
| return -1; |
| } |
| |
| } |
| /* |
| * Delete hidden file |
| */ |
| strcpy(pathname, TEST_DIR); |
| strcat(pathname, "/"); |
| strcat(pathname, HIDDEN_FILE_NAME); |
| if (PR_FAILURE == PR_Delete(pathname)) { |
| printf( |
| "testfile failed to delete hidden file %s [%d, %d]\n", |
| pathname, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| PR_CloseDir(fd_dir); |
| #endif /* XP_UNIX || (XP_PC && WIN32) */ |
| |
| strcpy(renamename, TEST_DIR); |
| strcat(renamename, ".RENAMED"); |
| if (PR_FAILURE == PR_Rename(TEST_DIR, renamename)) { |
| printf( |
| "testfile failed to rename directory %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| if (PR_FAILURE == PR_MkDir(TEST_DIR, 0777)) { |
| printf( |
| "testfile failed to recreate dir %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| if (PR_SUCCESS == PR_Rename(renamename, TEST_DIR)) { |
| printf( |
| "testfile renamed directory to existing name %s\n", |
| renamename); |
| return -1; |
| } |
| |
| if (PR_FAILURE == PR_RmDir(TEST_DIR)) { |
| printf( |
| "testfile failed to rmdir %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| if (PR_FAILURE == PR_Rename(renamename, TEST_DIR)) { |
| printf( |
| "testfile failed to rename directory %s [%d, %d]\n", |
| renamename, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| fd_dir = PR_OpenDir(TEST_DIR); |
| if (fd_dir == NULL) { |
| printf( |
| "testfile failed to reopen directory %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| |
| strcpy(pathname, TEST_DIR); |
| strcat(pathname, "/"); |
| strcat(pathname, FILE_NAME); |
| path_len = strlen(pathname); |
| |
| for (i = 0; i < FILES_IN_DIR; i++) { |
| |
| sprintf(pathname + path_len,"%d%s",i,""); |
| |
| if (PR_FAILURE == PR_Delete(pathname)) { |
| printf( |
| "testfile failed to delete file %s [%d, %d]\n", |
| pathname, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| } |
| |
| PR_CloseDir(fd_dir); |
| |
| if (PR_FAILURE == PR_RmDir(TEST_DIR)) { |
| printf( |
| "testfile failed to rmdir %s [%d, %d]\n", |
| TEST_DIR, PR_GetError(), PR_GetOSError()); |
| return -1; |
| } |
| PR_EnterMonitor(tinfo->mon); |
| tinfo->done = 1; |
| PR_Notify(tinfo->mon); |
| PR_ExitMonitor(tinfo->mon); |
| |
| return 0; |
| } |
| /************************************************************************/ |
| |
| /* |
| * Test file and directory NSPR APIs |
| */ |
| |
| int main(int argc, char **argv) |
| { |
| #ifdef WIN32 |
| PRUint32 len; |
| #endif |
| #if defined(XP_UNIX) || defined(XP_OS2) |
| int opt; |
| extern char *optarg; |
| extern int optind; |
| #endif |
| #if defined(XP_UNIX) || defined(XP_OS2) |
| while ((opt = getopt(argc, argv, "d")) != EOF) { |
| switch(opt) { |
| case 'd': |
| _debug_on = 1; |
| break; |
| default: |
| break; |
| } |
| } |
| #endif |
| PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); |
| PR_STDIO_INIT(); |
| |
| mon = PR_NewMonitor(); |
| if (mon == NULL) { |
| printf("testfile: PR_NewMonitor failed\n"); |
| exit(2); |
| } |
| #ifdef WIN32 |
| |
| #ifdef WINCE |
| { |
| WCHAR tdir[TMPDIR_LEN]; |
| len = GetTempPath(TMPDIR_LEN, tdir); |
| if ((len > 0) && (len < (TMPDIR_LEN - 6))) { |
| /* |
| * enough space for prdir |
| */ |
| WideCharToMultiByte(CP_ACP, 0, tdir, -1, testdir, TMPDIR_LEN, 0, 0); |
| } |
| } |
| #else |
| len = GetTempPath(TMPDIR_LEN, testdir); |
| #endif /* WINCE */ |
| |
| if ((len > 0) && (len < (TMPDIR_LEN - 6))) { |
| /* |
| * enough space for prdir |
| */ |
| strcpy((testdir + len),"prdir"); |
| TEST_DIR = testdir; |
| printf("TEST_DIR = %s\n",TEST_DIR); |
| } |
| #endif /* WIN32 */ |
| |
| if (FileTest() < 0) { |
| printf("File Test failed\n"); |
| exit(2); |
| } |
| printf("File Test passed\n"); |
| if ((RunDirTest() < 0) || dirtest_failed) { |
| printf("Dir Test failed\n"); |
| exit(2); |
| } |
| printf("Dir Test passed\n"); |
| |
| PR_DestroyMonitor(mon); |
| PR_Cleanup(); |
| return 0; |
| } |