diff options
Diffstat (limited to '')
-rw-r--r-- | src/libs/xpcom18a4/nsprpub/pr/src/md/windows/w16io.c | 855 |
1 files changed, 855 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/nsprpub/pr/src/md/windows/w16io.c b/src/libs/xpcom18a4/nsprpub/pr/src/md/windows/w16io.c new file mode 100644 index 00000000..6089d399 --- /dev/null +++ b/src/libs/xpcom18a4/nsprpub/pr/src/md/windows/w16io.c @@ -0,0 +1,855 @@ +/* -*- 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 "primpl.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <share.h> +#include <sys/locking.h> + + +/* +** Sleep this many milliseconds on each I/O operation +** to cause an intentional thread switch. +*/ +#define _PR_MD_WIN16_DELAY 1 + + +/* +** PR_MD_RegisterW16StdioCallbacks() -- Register Win16 stdio callback functions +** +** This public function call is unique to Win16. +** ... Sigh ... So much for platform independence. +** +** To get stdio to work from a command line executable, the stdio stream +** calls must be issued from the .EXE file; calling them from the .DLL +** sends the output to the bit-bucket. Therefore, the .EXE wanting to +** do stdio to the console window (must be built as a "quickwin" application) +** must have the wrapper functions defined in this module statically linked +** into the .EXE. +** +** There appears to be nothing you can do to get stdio to work from a +** Win16 GUI application. Oh Well! +** +*/ +PRStdinRead _pr_md_read_stdin = 0; +PRStdoutWrite _pr_md_write_stdout = 0; +PRStderrWrite _pr_md_write_stderr = 0; + +PRStatus +PR_MD_RegisterW16StdioCallbacks( PRStdinRead inReadf, PRStdoutWrite outWritef, PRStderrWrite errWritef ) +{ + _pr_md_write_stdout = outWritef; + _pr_md_write_stderr = errWritef; + _pr_md_read_stdin = inReadf; + + return(PR_SUCCESS); +} /* end PR_MD_RegisterW16StdioCallbacks() */ + + +/* +** _PR_MD_OPEN() -- Open a file +** +** Returns: a fileHandle or -1 +** +** +*/ +PRInt32 +_PR_MD_OPEN(const char *name, PRIntn osflags, int mode) +{ + PRInt32 file; + int access = O_BINARY; + int rights = 0; + + + /* + ** Map NSPR open flags to os open flags + */ + if (osflags & PR_RDONLY ) + access |= O_RDONLY; + if (osflags & PR_WRONLY ) + access |= O_WRONLY; + if (osflags & PR_RDWR ) + access |= O_RDWR; + if (osflags & PR_CREATE_FILE ) + { + access |= O_CREAT; + rights |= S_IRWXU; + } + if (osflags & PR_TRUNCATE) + access |= O_TRUNC; + if (osflags & PR_APPEND) + access |= O_APPEND; + else + access |= O_RDONLY; + + /* + ** Open the file + */ + file = (PRInt32) sopen( name, access, SH_DENYNO, rights ); + if ( -1 == (PRInt32)file ) + { + _PR_MD_MAP_OPEN_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return file; +} + +/* +** _PR_MD_READ() - Read something +** +** Returns: bytes read or -1 +** +*/ +PRInt32 +_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len) +{ + PRInt32 rv; + + if ( (PR_GetDescType(fd) == PR_DESC_FILE) && + ( fd->secret->md.osfd == PR_StandardInput ) && + ( _pr_md_write_stdout )) + { + rv = (*_pr_md_read_stdin)( buf, len); + } + else + { + rv = read( fd->secret->md.osfd, buf, len ); + } + + if ( rv == -1) + { + _PR_MD_MAP_READ_ERROR( errno ); + } + + PR_Sleep( _PR_MD_WIN16_DELAY ); + return rv; +} + +/* +** _PR_MD_WRITE() - Write something +** +** Returns: bytes written or -1 +** +** Note: for file handles 1 and 2 (stdout and stderr) +** call the Win16 NSPR stdio callback functions, if they are +** registered. +** +*/ +PRInt32 +_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len) +{ + PRInt32 rv; + + if ( (PR_GetDescType(fd) == PR_DESC_FILE)) + { + switch ( fd->secret->md.osfd ) + { + case PR_StandardOutput : + if ( _pr_md_write_stdout ) + rv = (*_pr_md_write_stdout)( (void *)buf, len); + else + rv = len; /* fake success */ + break; + + case PR_StandardError : + if ( _pr_md_write_stderr ) + rv = (*_pr_md_write_stderr)( (void *)buf, len); + else + rv = len; /* fake success */ + break; + + default: + rv = write( fd->secret->md.osfd, buf, len ); + if ( rv == -1 ) + { + _PR_MD_MAP_WRITE_ERROR( errno ); + } + break; + } + } + else + { + rv = write( fd->secret->md.osfd, buf, len ); + if ( rv == -1 ) + { + _PR_MD_MAP_WRITE_ERROR( errno ); + } + } + + PR_Sleep( _PR_MD_WIN16_DELAY ); + return rv; +} /* --- end _PR_MD_WRITE() --- */ + +/* +** _PR_MD_LSEEK() - Seek to position in a file +** +** Note: 'whence' maps directly to PR_... +** +** Returns: +** +*/ +PRInt32 +_PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, int whence) +{ + PRInt32 rv; + + rv = lseek( fd->secret->md.osfd, offset, whence ); + if ( rv == -1 ) + { + _PR_MD_MAP_LSEEK_ERROR( errno ); + + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return( rv ); +} + +/* +** _PR_MD_LSEEK64() -- Seek to position in file, 64bit offset. +** +*/ +PRInt64 +_PR_MD_LSEEK64( PRFileDesc *fd, PRInt64 offset, int whence ) +{ + PRInt64 test; + PRInt32 rv, off; + LL_SHR(test, offset, 32); + if (!LL_IS_ZERO(test)) + { + PR_SetError(PR_FILE_TOO_BIG_ERROR, 0); + LL_I2L(test, -1); + return test; + } + LL_L2I(off, offset); + rv = _PR_MD_LSEEK(fd, off, whence); + LL_I2L(test, rv); + return test; +} /* end _PR_MD_LSEEK64() */ + +/* +** _PR_MD_FSYNC() - Flush file buffers. +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_FSYNC(PRFileDesc *fd) +{ + PRInt32 rv; + + rv = (PRInt32) fsync( fd->secret->md.osfd ); + if ( rv == -1 ) + { + _PR_MD_MAP_FSYNC_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return(rv); +} + +/* +** _PR_MD_CLOSE() - Close an open file handle +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_CLOSE_FILE(PRInt32 osfd) +{ + PRInt32 rv; + + rv = (PRInt32) close( osfd ); + if ( rv == -1 ) + { + _PR_MD_MAP_CLOSE_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return(rv); +} /* --- end _MD_CloseFile() --- */ + + +/* --- DIR IO ------------------------------------------------------------ */ +#define GetFileFromDIR(d) (d)->d_entry.cFileName + +/* +** FlipSlashes() - Make forward slashes ('/') into backslashes +** +** Returns: void +** +** +*/ +void FlipSlashes(char *cp, int len) +{ + while (--len >= 0) { + if (cp[0] == '/') { + cp[0] = PR_DIRECTORY_SEPARATOR; + } + cp++; + } +} + + +/* +** _PR_MD_OPEN_DIR() - Open a Directory. +** +** Returns: +** +** +*/ +PRStatus +_PR_MD_OPEN_DIR(_MDDir *d, const char *name) +{ + d->dir = opendir( name ); + + if ( d->dir == NULL ) + { + _PR_MD_MAP_OPENDIR_ERROR( errno ); + return( PR_FAILURE ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return( PR_SUCCESS ); +} + + +/* +** _PR_MD_READ_DIR() - read next directory entry +** +** +*/ +char * +_PR_MD_READ_DIR(_MDDir *d, PRIntn flags) +{ + struct dirent *de; + int err; + + for (;;) + { + de = readdir( d->dir ); + if ( de == NULL ) { + _PR_MD_MAP_READDIR_ERROR( errno); + return 0; + } + if ((flags & PR_SKIP_DOT) && + (de->d_name[0] == '.') && (de->d_name[1] == 0)) + continue; + if ((flags & PR_SKIP_DOT_DOT) && + (de->d_name[0] == '.') && (de->d_name[1] == '.') && + (de->d_name[2] == 0)) + continue; + break; + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return de->d_name; +} + +/* +** _PR_MD_CLOSE_DIR() - Close a directory. +** +** +*/ +PRInt32 +_PR_MD_CLOSE_DIR(_MDDir *d) +{ + PRInt32 rv; + + if ( d->dir ) + { + rv = closedir( d->dir ); + if (rv != 0) + { + _PR_MD_MAP_CLOSEDIR_ERROR( errno ); + } + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return rv; +} + + +/* +** _PR_MD_DELETE() - Delete a file. +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_DELETE(const char *name) +{ + PRInt32 rv; + + rv = (PRInt32) remove( name ); + if ( rv != 0 ) + { + _PR_MD_MAP_DELETE_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return(rv); +} + + +/* +** _PR_MD_STAT() - Get file attributes by filename +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_STAT(const char *fn, struct stat *info) +{ + PRInt32 rv; + + rv = _stat(fn, (struct _stat *)info); + if ( rv == -1 ) + { + _PR_MD_MAP_STAT_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return( rv ); +} + +/* +** _PR_MD_GETFILEINFO() - Get file attributes by filename +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info) +{ + struct _stat sb; + PRInt32 rv; + + if ( (rv = _stat(fn, &sb)) == 0 ) { + if (info) { + if (S_IFREG & sb.st_mode) + info->type = PR_FILE_FILE ; + else if (S_IFDIR & sb.st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + info->size = sb.st_size; + LL_I2L(info->modifyTime, sb.st_mtime); + LL_I2L(info->creationTime, sb.st_ctime); + } + } + else + { + _PR_MD_MAP_STAT_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return rv; +} + +PRInt32 +_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info) +{ + PRFileInfo info32; + + PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32); + if (0 == rv) + { + info->type = info32.type; + info->modifyTime = info32.modifyTime; + info->creationTime = info32.creationTime; + LL_I2L(info->size, info32.size); + } + return(rv); +} + +/* +** _PR_MD_GETOPENFILEINFO() - Get file attributes from an open file handle +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info) +{ + struct stat statBuf; + PRInt32 rv = PR_SUCCESS; + + rv = fstat( fd->secret->md.osfd, &statBuf ); + if ( rv == 0) + { + if (statBuf.st_mode & S_IFREG ) + info->type = PR_FILE_FILE; + else if ( statBuf.st_mode & S_IFDIR ) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + info->size = statBuf.st_size; + LL_I2L(info->modifyTime, statBuf.st_mtime); + LL_I2L(info->creationTime, statBuf.st_ctime); + + } + else + { + _PR_MD_MAP_FSTAT_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return(rv); +} + +PRInt32 +_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info) +{ + PRFileInfo info32; + + PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32); + if (0 == rv) + { + info->type = info32.type; + info->modifyTime = info32.modifyTime; + info->creationTime = info32.creationTime; + LL_I2L(info->size, info32.size); + } + return(rv); +} + +/* +** _PR_MD_RENAME() - Rename a file +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_RENAME(const char *from, const char *to) +{ + PRInt32 rv; + + rv = rename( from, to ); + if ( rv == -1 ) + { + _PR_MD_MAP_RENAME_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return( rv ); +} + +/* +** _PR_MD_ACCESS() - Return file acesss attribute. +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_ACCESS(const char *name, PRIntn how) +{ + PRInt32 rv; + int mode = 0; + + if ( how & PR_ACCESS_WRITE_OK ) + mode |= W_OK; + if ( how & PR_ACCESS_READ_OK ) + mode |= R_OK; + + rv = (PRInt32) access( name, mode ); + if ( rv == -1 ) + { + _PR_MD_MAP_ACCESS_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return(rv); +} + +/* +** _PR_MD_MKDIR() - Make a directory +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_MKDIR(const char *name, PRIntn mode) +{ + PRInt32 rv; + + rv = mkdir( name ); + if ( rv == 0 ) + { + PR_Sleep( _PR_MD_WIN16_DELAY ); + return PR_SUCCESS; + } + else + { + _PR_MD_MAP_MKDIR_ERROR( errno ); + PR_Sleep( _PR_MD_WIN16_DELAY ); + return PR_FAILURE; + } +} + +/* +** _PR_MD_RMDIR() - Delete a directory +** +** Returns: +** +** +*/ +PRInt32 +_PR_MD_RMDIR(const char *name) +{ + PRInt32 rv; + + rv = (PRInt32) rmdir( name ); + if ( rv == -1 ) + { + _PR_MD_MAP_RMDIR_ERROR( errno ); + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return(rv); +} + +/* +** _PR_MD_LOCKFILE() - Lock a file. +** +** The _locking() call locks relative to the current file pointer. +** This function is required to lock all of the file, so, +** 1. Seek to the beginning of the file, preserving the original position. +** 2. Lock the file, pausing if it is locked by someone else, and +** try again. +** 3. Re-position to the original position in the file. +** +** For unlocking, a similar protocol of positioning is required. +** +*/ +PRStatus +_PR_MD_LOCKFILE(PRInt32 f) +{ + PRInt32 rv = PR_SUCCESS; /* What we return to our caller */ + long seekOrigin; /* original position in file */ + PRInt32 rc; /* what the system call returns to us */ + + /* + ** Seek to beginning of file, saving original position. + */ + seekOrigin = lseek( f, 0l, SEEK_SET ); + if ( rc == -1 ) + { + _PR_MD_MAP_LSEEK_ERROR( errno ); + return( PR_FAILURE ); + } + + /* + ** Attempt to lock the file. + ** If someone else has it, Sleep-a-while and try again. + */ + for( rc = -1; rc != 0; ) + { + rc = _locking( f, _LK_NBLCK , 0x7fffffff ); + if ( rc == -1 ) + { + if ( errno == EACCES ) + { + PR_Sleep( 100 ); + continue; + } + else + { + _PR_MD_MAP_LOCKF_ERROR( errno ); + rv = PR_FAILURE; + break; + } + } + } /* end for() */ + + /* + ** Now that the file is locked, re-position to + ** the original file position. + ** + */ + rc = lseek( f, seekOrigin, SEEK_SET ); + if ( rc == -1 ) + { + _PR_MD_MAP_LSEEK_ERROR( errno ); + rv = PR_FAILURE; + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return PR_SUCCESS; +} /* end _PR_MD_LOCKFILE() */ + +/* +** _PR_MD_TLOCKFILE() - Test and Lock file. +** +** The _locking() call locks relative to the current file pointer. +** This function is required to lock all of the file, so, +** 1. Seek to the beginning of the file, preserving the original position. +** 2. Attempt to Lock the file. +** If the file is locked by someone else, try NO MORE. +** 3. Re-position to the original position in the file. +** +** See the discussion of _PR_MD_LOCKFILE +** +** +*/ +PRStatus +_PR_MD_TLOCKFILE(PRInt32 f) +{ + PRInt32 rv = PR_SUCCESS; /* What we return */ + long seekOrigin; /* original position in file */ + PRInt32 rc; /* return value from system call */ + + /* + ** Seek to beginning of file, saving original position. + */ + seekOrigin = lseek( f, 0l, SEEK_SET ); + if ( rc == -1 ) + { + _PR_MD_MAP_LSEEK_ERROR( errno ); + return( PR_FAILURE ); + } + + /* + ** Attempt to lock the file. One ping; one ping only, Vasily. + ** If someone else has it, Reposition and return failure. + */ + rc = _locking( f, _LK_NBLCK , 0x7fffffff ); + if ( rc == -1 ) + { + if ( errno != EACCES ) + _PR_MD_MAP_LOCKF_ERROR( errno ); + rv = PR_FAILURE; + } + + /* + ** Now that the file is locked, maybe, re-position to + ** the original file position. + */ + rc = lseek( f, seekOrigin, SEEK_SET ); + if ( rc == -1 ) + { + _PR_MD_MAP_LSEEK_ERROR( errno ); + rv = PR_FAILURE; + } + + PR_Sleep( _PR_MD_WIN16_DELAY ); + return rv; +} /* end _PR_MD_TLOCKFILE() */ + + +/* +** _PR_MD_UNLOCKFILE() - Unlock a file. +** +** See the discussion of _PR_MD_LOCKFILE +** +*/ +PRStatus +_PR_MD_UNLOCKFILE(PRInt32 f) +{ + PRInt32 rv = PR_SUCCESS; /* What we return */ + long seekOrigin; /* original position in file */ + PRInt32 rc; /* return value from system call */ + + /* + ** Seek to beginning of file, saving original position. + */ + seekOrigin = lseek( f, 0l, SEEK_SET ); + if ( rc == -1 ) + { + _PR_MD_MAP_LSEEK_ERROR( errno ); + return( PR_FAILURE ); + } + + /* + ** Unlock the file. + */ + rc = _locking( f, _LK_UNLCK , 0x7fffffff ); + if ( rc == -1 ) + { + _PR_MD_MAP_LOCKF_ERROR( errno ); + rv = PR_FAILURE; + } + + /* + ** Now that the file is unlocked, re-position to + ** the original file position. + */ + rc = lseek( f, seekOrigin, SEEK_SET ); + if ( rc == -1 ) + { + _PR_MD_MAP_LSEEK_ERROR( errno ); + rv = PR_FAILURE; + } + PR_Sleep( _PR_MD_WIN16_DELAY ); + return rv; +} /* end _PR_MD_UNLOCKFILE() */ + +/* +** PR_Stat() -- Return status on a file +** +** This is a hack! ... See BugSplat: 98516 +** Basically, this hack takes a name and stat buffer as input. +** The input stat buffer is presumed to be a Microsoft stat buffer. +** The functions does a Watcom stat() then maps the result to +** the MS stat buffer. ... +** +*/ +PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf) +{ + PRInt32 rv; + _MDMSStat *mssb = (_MDMSStat*) buf; /* this is Microsoft's stat buffer */ + struct stat statBuf; /* this is Watcom's stat buffer */ + + /* First, get Watcom's idea of stat + ** then reformat it into a Microsoft idea of stat + */ + rv = (PRInt32) _stat( name, &statBuf); + if (rv == 0l ) + { + mssb->st_dev = statBuf.st_dev; + mssb->st_ino = statBuf.st_ino; /* not used, really */ + mssb->st_mode = statBuf.st_mode; + mssb->st_nlink = 1; /* always 1, says MS */ + mssb->st_uid = statBuf.st_uid; + mssb->st_gid = statBuf.st_gid; + mssb->st_rdev = statBuf.st_rdev; /* please Gh0d! Let these be the same */ + mssb->st_size = statBuf.st_size; + mssb->st_atime = statBuf.st_atime; + mssb->st_mtime = statBuf.st_mtime; + mssb->st_ctime = statBuf.st_ctime; + } + return rv; +} /* end PR_Stat() */ + + + +/* $$ end W16io.c */ |