diff options
author | wtc%netscape.com <devnull@localhost> | 2002-11-13 01:45:10 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2002-11-13 01:45:10 +0000 |
commit | e081edd01303f2e32071a77b6b8c1dfa75af3309 (patch) | |
tree | 0a5c860acea1d89b96eecde2e79b9bafc924d773 | |
parent | fc4c34590749e24c86377f3268522989165f28ab (diff) | |
download | nspr-hg-e081edd01303f2e32071a77b6b8c1dfa75af3309.tar.gz |
Bug 162358: checked in proposed patch v4 (attachment 100805).
Tag: NSPR_UNICODE_PATHNAME_BRANCH
-rw-r--r-- | config/config.mk | 4 | ||||
-rw-r--r-- | pr/include/md/_win95.h | 18 | ||||
-rw-r--r-- | pr/include/prio.h | 40 | ||||
-rw-r--r-- | pr/include/private/primpl.h | 25 | ||||
-rw-r--r-- | pr/include/prtypes.h | 10 | ||||
-rw-r--r-- | pr/src/io/prdir.c | 50 | ||||
-rw-r--r-- | pr/src/io/prfile.c | 32 | ||||
-rw-r--r-- | pr/src/md/windows/w95io.c | 168 | ||||
-rw-r--r-- | pr/src/pthreads/ptio.c | 29 |
9 files changed, 376 insertions, 0 deletions
diff --git a/config/config.mk b/config/config.mk index 623a0aae..c57687c9 100644 --- a/config/config.mk +++ b/config/config.mk @@ -127,6 +127,10 @@ ifeq ($(USE_IPV6),1) DEFINES += -D_PR_INET6 endif +ifeq ($(MOZ_UNICODE),1) +DEFINES += -DMOZ_UNICODE +endif + #################################################################### # # Configuration for the release process diff --git a/pr/include/md/_win95.h b/pr/include/md/_win95.h index 86b39d5d..e115d5f9 100644 --- a/pr/include/md/_win95.h +++ b/pr/include/md/_win95.h @@ -112,6 +112,16 @@ struct _MDDir { PRUint32 magic; /* for debugging */ }; +#ifdef MOZ_UNICODE +struct _MDDirUCS2 { + HANDLE d_hdl; + WIN32_FIND_DATAW d_entry; + PRBool firstEntry; /* Is this the entry returned + * by FindFirstFileW()? */ + PRUint32 magic; /* for debugging */ +}; +#endif /* MOZ_UNICODE */ + struct _MDCVar { PRUint32 magic; struct PRThread *waitHead, *waitTail; /* the wait queue: a doubly- @@ -213,6 +223,14 @@ extern PRInt32 _MD_CloseFile(PRInt32 osfd); #define _MD_TLOCKFILE _PR_MD_TLOCKFILE #define _MD_UNLOCKFILE _PR_MD_UNLOCKFILE +#ifdef MOZ_UNICODE +/* --- UCS2 IO stuff --- */ +#define _MD_OPEN_FILE_UCS2 _PR_MD_OPEN_FILE_UCS2 +#define _MD_OPEN_DIR_UCS2 _PR_MD_OPEN_DIR_UCS2 +#define _MD_READ_DIR_UCS2 _PR_MD_READ_DIR_UCS2 +#define _MD_CLOSE_DIR_UCS2 _PR_MD_CLOSE_DIR_UCS2 +#endif /* MOZ_UNICODE */ + /* --- Socket IO stuff --- */ #define _MD_EACCES WSAEACCES #define _MD_EADDRINUSE WSAEADDRINUSE diff --git a/pr/include/prio.h b/pr/include/prio.h index 12caf4ef..caf22d03 100644 --- a/pr/include/prio.h +++ b/pr/include/prio.h @@ -52,6 +52,10 @@ PR_BEGIN_EXTERN_C /* Typedefs */ typedef struct PRDir PRDir; typedef struct PRDirEntry PRDirEntry; +#ifdef MOZ_UNICODE +typedef struct PRDirUCS2 PRDirUCS2; +typedef struct PRDirEntryUCS2 PRDirEntryUCS2; +#endif /* MOZ_UNICODE */ typedef struct PRFileDesc PRFileDesc; typedef struct PRFileInfo PRFileInfo; typedef struct PRFileInfo64 PRFileInfo64; @@ -650,6 +654,14 @@ NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode); NSPR_API(PRFileDesc*) PR_OpenFile( const char *name, PRIntn flags, PRIntn mode); +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This function may be removed in a future release. + */ +NSPR_API(PRFileDesc*) PR_OpenFileUCS2( + const PRUnichar *name, PRIntn flags, PRIntn mode); +#endif /* MOZ_UNICODE */ + /* ************************************************************************** * FUNCTION: PR_Close @@ -984,6 +996,13 @@ struct PRDirEntry { const char *name; /* name of entry, relative to directory name */ }; +#ifdef MOZ_UNICODE +struct PRDirEntryUCS2 { + const PRUnichar *name; /* name of entry in UCS2, relative to + * directory name */ +}; +#endif /* MOZ_UNICODE */ + #if !defined(NO_NSPR_10_SUPPORT) #define PR_DirName(dirEntry) (dirEntry->name) #endif @@ -1010,6 +1029,13 @@ struct PRDirEntry { NSPR_API(PRDir*) PR_OpenDir(const char *name); +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This function may be removed in a future release. + */ +NSPR_API(PRDirUCS2*) PR_OpenDirUCS2(const PRUnichar *name); +#endif /* MOZ_UNICODE */ + /* ************************************************************************* * FUNCTION: PR_ReadDir @@ -1043,6 +1069,13 @@ typedef enum PRDirFlags { NSPR_API(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags); +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This function may be removed in a future release. + */ +NSPR_API(PRDirEntryUCS2*) PR_ReadDirUCS2(PRDirUCS2 *dir, PRDirFlags flags); +#endif /* MOZ_UNICODE */ + /* ************************************************************************* * FUNCTION: PR_CloseDir @@ -1062,6 +1095,13 @@ NSPR_API(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags); NSPR_API(PRStatus) PR_CloseDir(PRDir *dir); +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This function may be removed in a future release. + */ +NSPR_API(PRStatus) PR_CloseDirUCS2(PRDirUCS2 *dir); +#endif /* MOZ_UNICODE */ + /* ************************************************************************* * FUNCTION: PR_MkDir diff --git a/pr/include/private/primpl.h b/pr/include/private/primpl.h index 5455ed9c..013f89d3 100644 --- a/pr/include/private/primpl.h +++ b/pr/include/private/primpl.h @@ -144,6 +144,9 @@ typedef struct _MDThread _MDThread; typedef struct _MDThreadStack _MDThreadStack; typedef struct _MDSemaphore _MDSemaphore; typedef struct _MDDir _MDDir; +#ifdef MOZ_UNICODE +typedef struct _MDDirUCS2 _MDDirUCS2; +#endif /* MOZ_UNICODE */ typedef struct _MDFileDesc _MDFileDesc; typedef struct _MDProcess _MDProcess; typedef struct _MDFileMap _MDFileMap; @@ -1144,6 +1147,21 @@ extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode); extern PRInt32 _PR_MD_RMDIR(const char *name); #define _PR_MD_RMDIR _MD_RMDIR +#ifdef MOZ_UNICODE +/* UCS2 File I/O related */ +extern PRStatus _PR_MD_OPEN_DIR_UCS2(_MDDirUCS2 *md, const PRUnichar *name); +#define _PR_MD_OPEN_DIR_UCS2 _MD_OPEN_DIR_UCS2 + +extern PRInt32 _PR_MD_OPEN_FILE_UCS2(const PRUnichar *name, PRIntn osflags, PRIntn mode); +#define _PR_MD_OPEN_FILE_UCS2 _MD_OPEN_FILE_UCS2 + +extern PRUnichar * _PR_MD_READ_DIR_UCS2(_MDDirUCS2 *md, PRIntn flags); +#define _PR_MD_READ_DIR_UCS2 _MD_READ_DIR_UCS2 + +extern PRInt32 _PR_MD_CLOSE_DIR_UCS2(_MDDirUCS2 *md); +#define _PR_MD_CLOSE_DIR_UCS2 _MD_CLOSE_DIR_UCS2 +#endif /* MOZ_UNICODE */ + /* Socket I/O related */ extern void _PR_MD_INIT_IO(void); #define _PR_MD_INIT_IO _MD_INIT_IO @@ -1736,6 +1754,13 @@ struct PRDir { _MDDir md; }; +#ifdef MOZ_UNICODE +struct PRDirUCS2 { + PRDirEntry d; + _MDDirUCS2 md; +}; +#endif /* MOZ_UNICODE */ + extern void _PR_InitSegs(void); extern void _PR_InitStacks(void); extern void _PR_InitTPD(void); diff --git a/pr/include/prtypes.h b/pr/include/prtypes.h index 099e9306..de9fd2fd 100644 --- a/pr/include/prtypes.h +++ b/pr/include/prtypes.h @@ -464,6 +464,16 @@ typedef PRUint8 PRPackedBool; */ typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus; +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This type may be removed in a future release. + */ +#ifndef __PRUNICHAR__ +#define __PRUNICHAR__ +typedef PRUint16 PRUnichar; +#endif +#endif /* MOZ_UNICODE */ + /* ** WARNING: The undocumented data types PRWord and PRUword are ** only used in the garbage collection and arena code. Do not diff --git a/pr/src/io/prdir.c b/pr/src/io/prdir.c index d0f469e9..8af28f82 100644 --- a/pr/src/io/prdir.c +++ b/pr/src/io/prdir.c @@ -18,6 +18,7 @@ * Rights Reserved. * * Contributor(s): + * Roy Yokoyama <yokoyama@netscape.com> * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the @@ -109,3 +110,52 @@ PRInt32 rv; return PR_SUCCESS; } +#ifdef MOZ_UNICODE +/* + * UCS2 Interface + */ +PR_IMPLEMENT(PRDirUCS2*) PR_OpenDirUCS2(const PRUnichar *name) +{ + PRDirUCS2 *dir; + PRStatus sts; + + dir = PR_NEW(PRDirUCS2); + if (dir) { + sts = _PR_MD_OPEN_DIR_UCS2(&dir->md,name); + if (sts != PR_SUCCESS) { + PR_DELETE(dir); + return NULL; + } + } else { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + } + return dir; +} + +PR_IMPLEMENT(PRDirEntryUCS2*) PR_ReadDirUCS2(PRDirUCS2 *dir, PRDirFlags flags) +{ + /* + * _MD_READ_DIR_UCS2 return a PRUnichar* to the name; allocation in + * machine-dependent code + */ + PRUnichar* name = _PR_MD_READ_DIR_UCS2(&dir->md, flags); + dir->d.name = name; + return name ? &dir->d : NULL; +} + +PR_IMPLEMENT(PRStatus) PR_CloseDirUCS2(PRDirUCS2 *dir) +{ + PRInt32 rv; + + if (dir) { + rv = _PR_MD_CLOSE_DIR_UCS2(&dir->md); + PR_DELETE(dir); + if (rv < 0) + return PR_FAILURE; + else + return PR_SUCCESS; + } + return PR_SUCCESS; +} + +#endif /* MOZ_UNICODE */ diff --git a/pr/src/io/prfile.c b/pr/src/io/prfile.c index adb2ea55..5bb13b2c 100644 --- a/pr/src/io/prfile.c +++ b/pr/src/io/prfile.c @@ -779,3 +779,35 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe( return PR_FAILURE; #endif } + +#ifdef MOZ_UNICODE +/* ================ UCS2 Interfaces ================================ */ +PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUCS2( + const PRUnichar *name, PRIntn flags, PRIntn mode) +{ + PRInt32 osfd; + PRFileDesc *fd = 0; +#if !defined(XP_UNIX) /* BugZilla: 4090 */ + PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + /* Map pr open flags and mode to os specific flags */ + osfd = _PR_MD_OPEN_FILE_UCS2(name, flags, mode); + if (osfd != -1) { + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); + if (!fd) { + (void) _PR_MD_CLOSE_FILE(osfd); + } else { +#if !defined(XP_UNIX) /* BugZilla: 4090 */ + fd->secret->appendMode = appendMode; +#endif + _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); + } + } + return fd; +} + +/* ================ UCS2 Interfaces ================================ */ +#endif /* MOZ_UNICODE */ diff --git a/pr/src/md/windows/w95io.c b/pr/src/md/windows/w95io.c index 89669e6e..fe264b2a 100644 --- a/pr/src/md/windows/w95io.c +++ b/pr/src/md/windows/w95io.c @@ -41,6 +41,9 @@ #include "primpl.h" #include <direct.h> #include <mbstring.h> +#ifdef MOZ_UNICODE +#include <tchar.h> +#endif /* MOZ_UNICODE */ struct _MDLock _pr_ioq_lock; @@ -1088,3 +1091,168 @@ _PR_MD_PIPEAVAILABLE(PRFileDesc *fd) PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); return -1; } + +#ifdef MOZ_UNICODE +/* ================ UCS2 Interfaces ================================ */ +void FlipSlashesW(PRUnichar *cp, int len) +{ + while (--len >= 0) { + if (cp[0] == L'/') { + cp[0] = L'\\'; + } + cp++; + } +} /* end FlipSlashesW() */ + +PRInt32 +_PR_MD_OPEN_FILE_UCS2(const PRUnichar *name, PRIntn osflags, int mode) +{ + HANDLE file; + PRInt32 access = 0; + PRInt32 flags = 0; + PRInt32 flag6 = 0; + SECURITY_ATTRIBUTES sa; + LPSECURITY_ATTRIBUTES lpSA = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + + if (osflags & PR_CREATE_FILE) { + if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable, + &pSD, &pACL) == PR_SUCCESS) { + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = pSD; + sa.bInheritHandle = FALSE; + lpSA = &sa; + } + } + + if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; + + if (osflags & PR_RDONLY || osflags & PR_RDWR) + access |= GENERIC_READ; + if (osflags & PR_WRONLY || osflags & PR_RDWR) + access |= GENERIC_WRITE; + + if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) + flags = CREATE_NEW; + else if (osflags & PR_CREATE_FILE) { + if (osflags & PR_TRUNCATE) + flags = CREATE_ALWAYS; + else + flags = OPEN_ALWAYS; + } else { + if (osflags & PR_TRUNCATE) + flags = TRUNCATE_EXISTING; + else + flags = OPEN_EXISTING; + } + + file = CreateFileW(name, + access, + FILE_SHARE_READ|FILE_SHARE_WRITE, + lpSA, + flags, + flag6, + NULL); + if (lpSA != NULL) { + _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); + } + if (file == INVALID_HANDLE_VALUE) { + _PR_MD_MAP_OPEN_ERROR(GetLastError()); + return -1; + } + + return (PRInt32)file; +} + +PRStatus +_PR_MD_OPEN_DIR_UCS2(_MDDirUCS2 *d, const PRUnichar *name) +{ + PRUnichar filename[ MAX_PATH ]; + int len; + + len = wcslen(name); + /* Need 5 bytes for \*.* and the trailing null byte. */ + if (len + 5 > MAX_PATH) { + PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); + return PR_FAILURE; + } + wcscpy(filename, name); + + /* + * If 'name' ends in a slash or backslash, do not append + * another backslash. + */ + if (filename[len - 1] == L'/' || filename[len - 1] == L'\\') { + len--; + } + wcscpy(&filename[len], L"\\*.*"); + FlipSlashesW( filename, wcslen(filename) ); + + d->d_hdl = FindFirstFileW( filename, &(d->d_entry) ); + if ( d->d_hdl == INVALID_HANDLE_VALUE ) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return PR_FAILURE; + } + d->firstEntry = PR_TRUE; + d->magic = _MD_MAGIC_DIR; + return PR_SUCCESS; +} + +PRUnichar * +_PR_MD_READ_DIR_UCS2(_MDDirUCS2 *d, PRIntn flags) +{ + PRInt32 err; + BOOL rv; + PRUnichar *fileName; + + if ( d ) { + while (1) { + if (d->firstEntry) { + d->firstEntry = PR_FALSE; + rv = 1; + } else { + rv = FindNextFileW(d->d_hdl, &(d->d_entry)); + } + if (rv == 0) { + break; + } + fileName = GetFileFromDIR(d); + if ( (flags & PR_SKIP_DOT) && + (fileName[0] == L'.') && (fileName[1] == L'\0')) + continue; + if ( (flags & PR_SKIP_DOT_DOT) && + (fileName[0] == L'.') && (fileName[1] == L'.') && + (fileName[2] == L'\0')) + continue; + if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d)) + continue; + return fileName; + } + err = GetLastError(); + PR_ASSERT(NO_ERROR != err); + _PR_MD_MAP_READDIR_ERROR(err); + return NULL; + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; +} + +PRStatus +_PR_MD_CLOSE_DIR_UCS2(_MDDirUCS2 *d) +{ + if ( d ) { + if (FindClose(d->d_hdl)) { + d->magic = (PRUint32)-1; + return PR_SUCCESS; + } else { + _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError()); + return PR_FAILURE; + } + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; +} + +/* ================ end of UCS2 Interfaces ================================ */ +#endif /* MOZ_UNICODE */ diff --git a/pr/src/pthreads/ptio.c b/pr/src/pthreads/ptio.c index 65ba6254..5571552c 100644 --- a/pr/src/pthreads/ptio.c +++ b/pr/src/pthreads/ptio.c @@ -4786,4 +4786,33 @@ retry: } #endif /* defined(_PR_PTHREADS) */ +#ifdef MOZ_UNICODE +/* ================ UCS2 Interfaces ================================ */ +PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUCS2( + const PRUnichar *name, PRIntn flags, PRIntn mode) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(PRStatus) PR_CloseDirUCS2(PRDir *dir) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRDirUCS2*) PR_OpenDirUCS2(const PRUnichar *name) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(PRDirEntryUCS2*) PR_ReadDirUCS2(PRDirUCS2 *dir, PRDirFlags flags) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} +/* ================ UCS2 Interfaces ================================ */ +#endif /* MOZ_UNICODE */ + /* ptio.c */ |