summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>2002-11-13 01:45:10 +0000
committerwtc%netscape.com <devnull@localhost>2002-11-13 01:45:10 +0000
commite081edd01303f2e32071a77b6b8c1dfa75af3309 (patch)
tree0a5c860acea1d89b96eecde2e79b9bafc924d773
parentfc4c34590749e24c86377f3268522989165f28ab (diff)
downloadnspr-hg-e081edd01303f2e32071a77b6b8c1dfa75af3309.tar.gz
Bug 162358: checked in proposed patch v4 (attachment 100805).
Tag: NSPR_UNICODE_PATHNAME_BRANCH
-rw-r--r--config/config.mk4
-rw-r--r--pr/include/md/_win95.h18
-rw-r--r--pr/include/prio.h40
-rw-r--r--pr/include/private/primpl.h25
-rw-r--r--pr/include/prtypes.h10
-rw-r--r--pr/src/io/prdir.c50
-rw-r--r--pr/src/io/prfile.c32
-rw-r--r--pr/src/md/windows/w95io.c168
-rw-r--r--pr/src/pthreads/ptio.c29
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 */