Back to index

lightning-sunbird  0.9+nobinonly
w16io.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "primpl.h"
00039 #include <sys/types.h>
00040 #include <sys/stat.h>
00041 #include <share.h>
00042 #include <sys/locking.h>
00043 
00044 
00045 /*
00046 ** Sleep this many milliseconds on each I/O operation
00047 ** to cause an intentional thread switch. 
00048 */
00049 #define _PR_MD_WIN16_DELAY 1
00050 
00051 
00052 /*
00053 ** PR_MD_RegisterW16StdioCallbacks() -- Register Win16 stdio callback functions
00054 **
00055 ** This public function call is unique to Win16. 
00056 ** ... Sigh ... So much for platform independence.
00057 ** 
00058 ** To get stdio to work from a command line executable, the stdio stream
00059 ** calls must be issued from the .EXE file; calling them from the .DLL
00060 ** sends the output to the bit-bucket. Therefore, the .EXE wanting to
00061 ** do stdio to the console window (must be built as a "quickwin" application)
00062 ** must have the wrapper functions defined in this module statically linked
00063 ** into the .EXE.
00064 **
00065 ** There appears to be nothing you can do to get stdio to work from a
00066 ** Win16 GUI application. Oh Well!
00067 **
00068 */
00069 PRStdinRead   _pr_md_read_stdin = 0;
00070 PRStdoutWrite _pr_md_write_stdout = 0;
00071 PRStderrWrite _pr_md_write_stderr = 0;
00072 
00073 PRStatus
00074 PR_MD_RegisterW16StdioCallbacks( PRStdinRead inReadf, PRStdoutWrite outWritef, PRStderrWrite errWritef )
00075 {
00076     _pr_md_write_stdout = outWritef;
00077     _pr_md_write_stderr = errWritef;
00078     _pr_md_read_stdin   = inReadf;
00079     
00080     return(PR_SUCCESS);
00081 } /* end PR_MD_RegisterW16StdioCallbacks() */
00082 
00083 
00084 /*
00085 ** _PR_MD_OPEN() -- Open a file
00086 **
00087 ** Returns: a fileHandle or -1
00088 **
00089 **
00090 */
00091 PRInt32
00092 _PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
00093 {
00094     PRInt32 file;
00095     int     access = O_BINARY;
00096     int     rights = 0;
00097     
00098     
00099     /*
00100     ** Map NSPR open flags to os open flags
00101     */
00102     if (osflags & PR_RDONLY )
00103         access |= O_RDONLY;
00104     if (osflags & PR_WRONLY )
00105         access |= O_WRONLY;
00106     if (osflags & PR_RDWR )
00107         access |= O_RDWR;
00108     if (osflags & PR_CREATE_FILE )
00109     {
00110         access |= O_CREAT;
00111         rights |= S_IRWXU;
00112     }
00113     if (osflags & PR_TRUNCATE)
00114         access |= O_TRUNC;
00115     if (osflags & PR_APPEND)
00116         access |= O_APPEND;
00117     else
00118         access |= O_RDONLY;
00119         
00120     /*
00121     ** Open the file
00122     */        
00123     file = (PRInt32) sopen( name, access, SH_DENYNO, rights );
00124     if ( -1 == (PRInt32)file )
00125     {
00126         _PR_MD_MAP_OPEN_ERROR( errno );
00127     }
00128     PR_Sleep( _PR_MD_WIN16_DELAY );    
00129     return file;
00130 }
00131 
00132 /*
00133 ** _PR_MD_READ() - Read something
00134 **
00135 ** Returns: bytes read or -1
00136 **
00137 */
00138 PRInt32
00139 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
00140 {
00141     PRInt32     rv;
00142     
00143     if ( (PR_GetDescType(fd) == PR_DESC_FILE) &&
00144          ( fd->secret->md.osfd == PR_StandardInput ) &&
00145          ( _pr_md_write_stdout ))
00146     {
00147         rv = (*_pr_md_read_stdin)( buf, len);    
00148     }
00149     else
00150     {
00151         rv = read( fd->secret->md.osfd, buf, len );
00152     }
00153     
00154     if ( rv == -1)
00155     {
00156         _PR_MD_MAP_READ_ERROR( errno );
00157     }
00158     
00159     PR_Sleep( _PR_MD_WIN16_DELAY );    
00160     return rv;
00161 }
00162 
00163 /*
00164 ** _PR_MD_WRITE() - Write something
00165 **
00166 ** Returns:  bytes written or -1
00167 **
00168 ** Note: for file handles 1 and 2 (stdout and stderr)
00169 ** call the Win16 NSPR stdio callback functions, if they are 
00170 ** registered.
00171 **
00172 */
00173 PRInt32
00174 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
00175 {
00176     PRInt32     rv;
00177 
00178     if ( (PR_GetDescType(fd) == PR_DESC_FILE))
00179     {
00180         switch ( fd->secret->md.osfd )
00181         {
00182             case  PR_StandardOutput :
00183                 if ( _pr_md_write_stdout )
00184                     rv = (*_pr_md_write_stdout)( (void *)buf, len);
00185                 else
00186                     rv = len; /* fake success */
00187                 break;
00188                 
00189             case  PR_StandardError  :
00190                 if ( _pr_md_write_stderr )
00191                     rv = (*_pr_md_write_stderr)( (void *)buf, len);    
00192                 else
00193                     rv = len; /* fake success */
00194                 break;
00195                 
00196             default:
00197                 rv = write( fd->secret->md.osfd, buf, len );
00198                 if ( rv == -1 )
00199                 {
00200                     _PR_MD_MAP_WRITE_ERROR( errno );
00201                 }
00202                 break;
00203         }
00204     }
00205     else
00206     {
00207         rv = write( fd->secret->md.osfd, buf, len );
00208         if ( rv == -1 )
00209         {
00210             _PR_MD_MAP_WRITE_ERROR( errno );
00211         }
00212     }
00213     
00214     PR_Sleep( _PR_MD_WIN16_DELAY );    
00215     return rv;
00216 } /* --- end _PR_MD_WRITE() --- */
00217 
00218 /*
00219 ** _PR_MD_LSEEK() - Seek to position in a file
00220 **
00221 ** Note: 'whence' maps directly to PR_...
00222 **
00223 ** Returns:
00224 **
00225 */
00226 PRInt32
00227 _PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, int whence)
00228 {
00229     PRInt32     rv;
00230     
00231     rv = lseek( fd->secret->md.osfd, offset, whence );
00232     if ( rv == -1 )
00233     {
00234         _PR_MD_MAP_LSEEK_ERROR( errno );
00235         
00236     }
00237     PR_Sleep( _PR_MD_WIN16_DELAY );    
00238     return( rv );
00239 }
00240 
00241 /*
00242 ** _PR_MD_LSEEK64() -- Seek to position in file, 64bit offset.
00243 **
00244 */
00245 PRInt64
00246 _PR_MD_LSEEK64( PRFileDesc *fd, PRInt64 offset, int whence )
00247 {
00248     PRInt64 test;
00249     PRInt32 rv, off;
00250     LL_SHR(test, offset, 32);
00251     if (!LL_IS_ZERO(test))
00252     {
00253         PR_SetError(PR_FILE_TOO_BIG_ERROR, 0);
00254         LL_I2L(test, -1);
00255         return test;
00256     }
00257     LL_L2I(off, offset);
00258     rv = _PR_MD_LSEEK(fd, off, whence);
00259     LL_I2L(test, rv);
00260     return test;
00261 } /* end _PR_MD_LSEEK64() */
00262 
00263 /*
00264 ** _PR_MD_FSYNC() - Flush file buffers.
00265 **
00266 ** Returns:
00267 **
00268 **
00269 */
00270 PRInt32
00271 _PR_MD_FSYNC(PRFileDesc *fd)
00272 {
00273     PRInt32     rv;
00274     
00275     rv = (PRInt32) fsync( fd->secret->md.osfd );
00276     if ( rv == -1 )
00277     {
00278         _PR_MD_MAP_FSYNC_ERROR( errno );
00279     }
00280     PR_Sleep( _PR_MD_WIN16_DELAY );    
00281     return(rv);
00282 }
00283 
00284 /*
00285 ** _PR_MD_CLOSE() - Close an open file handle
00286 **
00287 ** Returns:
00288 **
00289 **
00290 */
00291 PRInt32
00292 _PR_MD_CLOSE_FILE(PRInt32 osfd)
00293 {
00294     PRInt32     rv;
00295     
00296     rv = (PRInt32) close( osfd );
00297     if ( rv == -1 )
00298     {
00299         _PR_MD_MAP_CLOSE_ERROR( errno );
00300     }
00301     PR_Sleep( _PR_MD_WIN16_DELAY );    
00302     return(rv);
00303 } /* --- end _MD_CloseFile() --- */
00304 
00305 
00306 /* --- DIR IO ------------------------------------------------------------ */
00307 #define GetFileFromDIR(d)       (d)->d_entry.cFileName
00308 
00309 /*
00310 ** FlipSlashes() - Make forward slashes ('/') into backslashes
00311 **
00312 ** Returns: void
00313 **
00314 **
00315 */
00316 void FlipSlashes(char *cp, int len)
00317 {
00318     while (--len >= 0) {
00319     if (cp[0] == '/') {
00320         cp[0] = PR_DIRECTORY_SEPARATOR;
00321     }
00322     cp++;
00323     }
00324 }
00325 
00326 
00327 /*
00328 ** _PR_MD_OPEN_DIR() - Open a Directory.
00329 **
00330 ** Returns:
00331 **
00332 **
00333 */
00334 PRStatus
00335 _PR_MD_OPEN_DIR(_MDDir *d, const char *name)
00336 {
00337     d->dir = opendir( name );
00338     
00339     if ( d->dir == NULL )
00340     {
00341         _PR_MD_MAP_OPENDIR_ERROR( errno );
00342         return( PR_FAILURE );
00343     }
00344     PR_Sleep( _PR_MD_WIN16_DELAY );    
00345     return( PR_SUCCESS );
00346 }
00347 
00348 
00349 /*
00350 ** _PR_MD_READ_DIR() - read next directory entry
00351 **
00352 **
00353 */
00354 char *
00355 _PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
00356 {
00357     struct dirent *de;
00358     int err;
00359 
00360        for (;;) 
00361     {
00362               de = readdir( d->dir );
00363               if ( de == NULL ) {
00364                      _PR_MD_MAP_READDIR_ERROR( errno);
00365                      return 0;
00366               }             
00367               if ((flags & PR_SKIP_DOT) &&
00368                   (de->d_name[0] == '.') && (de->d_name[1] == 0))
00369                      continue;
00370               if ((flags & PR_SKIP_DOT_DOT) &&
00371                   (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
00372                   (de->d_name[2] == 0))
00373                      continue;
00374               break;
00375        }
00376     PR_Sleep( _PR_MD_WIN16_DELAY );    
00377        return de->d_name;
00378 }
00379 
00380 /*
00381 ** _PR_MD_CLOSE_DIR() - Close a directory.
00382 **
00383 **
00384 */
00385 PRInt32
00386 _PR_MD_CLOSE_DIR(_MDDir *d)
00387 {
00388     PRInt32     rv;
00389     
00390     if ( d->dir ) 
00391     {
00392         rv = closedir( d->dir );
00393         if (rv != 0) 
00394         {
00395             _PR_MD_MAP_CLOSEDIR_ERROR( errno );
00396         }
00397     }
00398     PR_Sleep( _PR_MD_WIN16_DELAY );    
00399     return rv;
00400 }
00401 
00402 
00403 /*
00404 ** _PR_MD_DELETE() - Delete a file.
00405 **
00406 ** Returns:
00407 **
00408 **
00409 */
00410 PRInt32
00411 _PR_MD_DELETE(const char *name)
00412 {
00413     PRInt32     rv;
00414     
00415     rv = (PRInt32) remove( name );
00416     if ( rv != 0 )
00417     {
00418         _PR_MD_MAP_DELETE_ERROR( errno );
00419     }
00420     PR_Sleep( _PR_MD_WIN16_DELAY );    
00421     return(rv);
00422 }
00423 
00424 
00425 /*
00426 ** _PR_MD_STAT() - Get file attributes by filename
00427 **
00428 ** Returns:
00429 **
00430 **
00431 */
00432 PRInt32
00433 _PR_MD_STAT(const char *fn, struct stat *info)
00434 {
00435     PRInt32     rv;
00436     
00437     rv = _stat(fn, (struct _stat *)info);
00438     if ( rv == -1 )
00439     {
00440         _PR_MD_MAP_STAT_ERROR( errno );
00441     }
00442     PR_Sleep( _PR_MD_WIN16_DELAY );    
00443     return( rv );
00444 }
00445 
00446 /*
00447 ** _PR_MD_GETFILEINFO() - Get file attributes by filename
00448 **
00449 ** Returns:
00450 **
00451 **
00452 */
00453 PRInt32
00454 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
00455 {
00456     struct _stat sb;
00457     PRInt32 rv;
00458  
00459     if ( (rv = _stat(fn, &sb)) == 0 ) {
00460         if (info) {
00461             if (S_IFREG & sb.st_mode)
00462                 info->type = PR_FILE_FILE ;
00463             else if (S_IFDIR & sb.st_mode)
00464                 info->type = PR_FILE_DIRECTORY;
00465             else
00466                 info->type = PR_FILE_OTHER;
00467             info->size = sb.st_size;
00468             LL_I2L(info->modifyTime, sb.st_mtime);
00469             LL_I2L(info->creationTime, sb.st_ctime);
00470         }
00471     }
00472     else
00473     {
00474         _PR_MD_MAP_STAT_ERROR( errno );
00475     }
00476     PR_Sleep( _PR_MD_WIN16_DELAY );    
00477     return rv;
00478 }
00479 
00480 PRInt32
00481 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
00482 {
00483     PRFileInfo info32;
00484     
00485     PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32);
00486     if (0 == rv)
00487     {
00488         info->type = info32.type;
00489         info->modifyTime = info32.modifyTime;
00490         info->creationTime = info32.creationTime;
00491         LL_I2L(info->size, info32.size);
00492     }
00493     return(rv);
00494 }
00495 
00496 /*
00497 ** _PR_MD_GETOPENFILEINFO() - Get file attributes from an open file handle
00498 **
00499 ** Returns:
00500 **
00501 **
00502 */
00503 PRInt32
00504 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
00505 {
00506     struct stat statBuf;
00507     PRInt32 rv = PR_SUCCESS;
00508     
00509     rv = fstat( fd->secret->md.osfd, &statBuf );
00510     if ( rv == 0)
00511     {
00512         if (statBuf.st_mode & S_IFREG )
00513             info->type = PR_FILE_FILE;
00514         else if ( statBuf.st_mode & S_IFDIR )
00515             info->type = PR_FILE_DIRECTORY;
00516         else
00517             info->type = PR_FILE_OTHER;
00518         info->size = statBuf.st_size;
00519         LL_I2L(info->modifyTime, statBuf.st_mtime);
00520         LL_I2L(info->creationTime, statBuf.st_ctime);
00521         
00522     }
00523     else
00524     {
00525         _PR_MD_MAP_FSTAT_ERROR( errno );
00526     }
00527     PR_Sleep( _PR_MD_WIN16_DELAY );    
00528     return(rv);
00529 }
00530 
00531 PRInt32
00532 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
00533 {
00534     PRFileInfo info32;
00535     
00536     PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32);
00537     if (0 == rv)
00538     {
00539         info->type = info32.type;
00540         info->modifyTime = info32.modifyTime;
00541         info->creationTime = info32.creationTime;
00542         LL_I2L(info->size, info32.size);
00543     }
00544     return(rv);
00545 }
00546 
00547 /*
00548 ** _PR_MD_RENAME() - Rename a file
00549 **
00550 ** Returns:
00551 **
00552 **
00553 */
00554 PRInt32
00555 _PR_MD_RENAME(const char *from, const char *to)
00556 {
00557     PRInt32 rv;
00558     
00559     rv = rename( from, to );
00560     if ( rv == -1 )
00561     {
00562         _PR_MD_MAP_RENAME_ERROR( errno );
00563     }
00564     PR_Sleep( _PR_MD_WIN16_DELAY );    
00565     return( rv );
00566 }
00567 
00568 /*
00569 ** _PR_MD_ACCESS() - Return file acesss attribute.
00570 **
00571 ** Returns:
00572 **
00573 **
00574 */
00575 PRInt32
00576 _PR_MD_ACCESS(const char *name, PRIntn how)
00577 {
00578     PRInt32     rv;
00579     int         mode = 0;
00580     
00581     if ( how & PR_ACCESS_WRITE_OK )
00582         mode |= W_OK;
00583     if ( how & PR_ACCESS_READ_OK )
00584         mode |= R_OK;
00585         
00586     rv = (PRInt32) access( name, mode );        
00587     if ( rv == -1 )
00588     {
00589         _PR_MD_MAP_ACCESS_ERROR( errno );
00590     }
00591     PR_Sleep( _PR_MD_WIN16_DELAY );    
00592     return(rv);
00593 }
00594 
00595 /*
00596 ** _PR_MD_MKDIR() - Make a directory
00597 **
00598 ** Returns:
00599 **
00600 **
00601 */
00602 PRInt32
00603 _PR_MD_MKDIR(const char *name, PRIntn mode)
00604 {
00605     PRInt32 rv;
00606         
00607     rv = mkdir( name );
00608     if ( rv == 0 )
00609     {
00610         PR_Sleep( _PR_MD_WIN16_DELAY );    
00611         return PR_SUCCESS;
00612     }
00613     else
00614     {
00615         _PR_MD_MAP_MKDIR_ERROR( errno );
00616         PR_Sleep( _PR_MD_WIN16_DELAY );    
00617         return PR_FAILURE;
00618     }
00619 }
00620 
00621 /*
00622 ** _PR_MD_RMDIR() - Delete a directory
00623 **
00624 ** Returns:
00625 **
00626 **
00627 */
00628 PRInt32
00629 _PR_MD_RMDIR(const char *name)
00630 {
00631     PRInt32 rv;
00632     
00633     rv = (PRInt32) rmdir( name );
00634     if ( rv == -1 )
00635     {
00636         _PR_MD_MAP_RMDIR_ERROR( errno );
00637     }
00638     PR_Sleep( _PR_MD_WIN16_DELAY );    
00639     return(rv);
00640 }
00641 
00642 /*
00643 ** _PR_MD_LOCKFILE() - Lock a file.
00644 **
00645 ** The _locking() call locks relative to the current file pointer.
00646 ** This function is required to lock all of the file, so,
00647 ** 1. Seek to the beginning of the file, preserving the original position.
00648 ** 2. Lock the file, pausing if it is locked by someone else, and
00649 **    try again.
00650 ** 3. Re-position to the original position in the file.
00651 **
00652 ** For unlocking, a similar protocol of positioning is required.
00653 **
00654 */
00655 PRStatus
00656 _PR_MD_LOCKFILE(PRInt32 f)
00657 {
00658     PRInt32 rv = PR_SUCCESS;    /* What we return to our caller */
00659     long    seekOrigin;         /* original position in file */
00660     PRInt32 rc;                 /* what the system call returns to us */
00661 
00662     /*
00663     ** Seek to beginning of file, saving original position.
00664     */    
00665     seekOrigin = lseek( f, 0l, SEEK_SET );
00666     if ( rc == -1 )
00667     {
00668         _PR_MD_MAP_LSEEK_ERROR( errno );
00669         return( PR_FAILURE );
00670     }
00671     
00672     /*
00673     ** Attempt to lock the file.
00674     ** If someone else has it, Sleep-a-while and try again.
00675     */
00676     for( rc = -1; rc != 0; )
00677     {
00678         rc = _locking( f, _LK_NBLCK , 0x7fffffff );
00679         if ( rc == -1 )
00680         {
00681             if ( errno == EACCES )
00682             {
00683                 PR_Sleep( 100 );
00684                 continue;
00685             }
00686             else
00687             {
00688                 _PR_MD_MAP_LOCKF_ERROR( errno );
00689                 rv = PR_FAILURE;
00690                 break;
00691             }
00692         }
00693     } /* end for() */
00694     
00695     /*
00696     ** Now that the file is locked, re-position to
00697     ** the original file position.
00698     **
00699     */
00700     rc = lseek( f, seekOrigin, SEEK_SET );
00701     if ( rc == -1 )
00702     {
00703         _PR_MD_MAP_LSEEK_ERROR( errno );
00704         rv = PR_FAILURE;
00705     }
00706     PR_Sleep( _PR_MD_WIN16_DELAY );    
00707     return PR_SUCCESS;
00708 } /* end _PR_MD_LOCKFILE() */
00709 
00710 /*
00711 ** _PR_MD_TLOCKFILE() - Test and Lock file.
00712 **
00713 ** The _locking() call locks relative to the current file pointer.
00714 ** This function is required to lock all of the file, so,
00715 ** 1. Seek to the beginning of the file, preserving the original position.
00716 ** 2. Attempt to Lock the file.
00717 **    If the file is locked by someone else, try NO MORE.
00718 ** 3. Re-position to the original position in the file.
00719 **
00720 ** See the discussion of _PR_MD_LOCKFILE
00721 **
00722 **
00723 */
00724 PRStatus
00725 _PR_MD_TLOCKFILE(PRInt32 f)
00726 {
00727     PRInt32 rv = PR_SUCCESS;    /* What we return */
00728     long    seekOrigin;         /* original position in file */
00729     PRInt32 rc;                 /* return value from system call */
00730 
00731     /*
00732     ** Seek to beginning of file, saving original position.
00733     */    
00734     seekOrigin = lseek( f, 0l, SEEK_SET );
00735     if ( rc == -1 )
00736     {
00737         _PR_MD_MAP_LSEEK_ERROR( errno );
00738         return( PR_FAILURE );
00739     }
00740     
00741     /*
00742     ** Attempt to lock the file. One ping; one ping only, Vasily.
00743     ** If someone else has it, Reposition and return failure.
00744     */
00745     rc = _locking( f, _LK_NBLCK , 0x7fffffff );
00746     if ( rc == -1 )
00747     {
00748         if ( errno != EACCES )
00749             _PR_MD_MAP_LOCKF_ERROR( errno );
00750         rv = PR_FAILURE;
00751     }
00752     
00753     /*
00754     ** Now that the file is locked, maybe, re-position to
00755     ** the original file position.
00756     */
00757     rc = lseek( f, seekOrigin, SEEK_SET );
00758     if ( rc == -1 )
00759     {
00760         _PR_MD_MAP_LSEEK_ERROR( errno );
00761         rv = PR_FAILURE;
00762     }
00763     
00764     PR_Sleep( _PR_MD_WIN16_DELAY );    
00765     return rv;
00766 } /* end _PR_MD_TLOCKFILE() */
00767 
00768 
00769 /*
00770 ** _PR_MD_UNLOCKFILE() - Unlock a file.
00771 **
00772 ** See the discussion of _PR_MD_LOCKFILE
00773 **
00774 */
00775 PRStatus
00776 _PR_MD_UNLOCKFILE(PRInt32 f)
00777 {
00778     PRInt32 rv = PR_SUCCESS;    /* What we return */
00779     long    seekOrigin;         /* original position in file */
00780     PRInt32 rc;                 /* return value from system call */
00781 
00782     /*
00783     ** Seek to beginning of file, saving original position.
00784     */    
00785     seekOrigin = lseek( f, 0l, SEEK_SET );
00786     if ( rc == -1 )
00787     {
00788         _PR_MD_MAP_LSEEK_ERROR( errno );
00789         return( PR_FAILURE );
00790     }
00791     
00792     /*
00793     ** Unlock the file.
00794     */
00795     rc = _locking( f, _LK_UNLCK , 0x7fffffff );
00796     if ( rc == -1 )
00797     {
00798         _PR_MD_MAP_LOCKF_ERROR( errno );
00799         rv = PR_FAILURE;
00800     }
00801     
00802     /*
00803     ** Now that the file is unlocked, re-position to
00804     ** the original file position.
00805     */
00806     rc = lseek( f, seekOrigin, SEEK_SET );
00807     if ( rc == -1 )
00808     {
00809         _PR_MD_MAP_LSEEK_ERROR( errno );
00810         rv = PR_FAILURE;
00811     }
00812     PR_Sleep( _PR_MD_WIN16_DELAY );    
00813     return rv;
00814 } /* end _PR_MD_UNLOCKFILE() */
00815 
00816 /*
00817 ** PR_Stat() -- Return status on a file
00818 **
00819 ** This is a hack! ... See BugSplat: 98516 
00820 ** Basically, this hack takes a name and stat buffer as input.
00821 ** The input stat buffer is presumed to be a Microsoft stat buffer.
00822 ** The functions does a Watcom stat() then maps the result to
00823 ** the MS stat buffer. ...
00824 **
00825 */
00826 PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
00827 {
00828     PRInt32     rv;
00829     _MDMSStat   *mssb = (_MDMSStat*) buf; /* this is Microsoft's stat buffer */
00830     struct stat statBuf;   /* this is Watcom's stat buffer */
00831 
00832     /* First, get Watcom's idea of stat
00833     ** then reformat it into a Microsoft idea of stat
00834     */
00835     rv = (PRInt32) _stat( name, &statBuf);
00836     if (rv == 0l )
00837     {
00838         mssb->st_dev = statBuf.st_dev;
00839         mssb->st_ino = statBuf.st_ino; /* not used, really */
00840         mssb->st_mode = statBuf.st_mode;
00841         mssb->st_nlink = 1; /* always 1, says MS */
00842         mssb->st_uid = statBuf.st_uid;
00843         mssb->st_gid = statBuf.st_gid;
00844         mssb->st_rdev = statBuf.st_rdev; /* please Gh0d! Let these be the same */
00845         mssb->st_size = statBuf.st_size;
00846         mssb->st_atime = statBuf.st_atime;
00847         mssb->st_mtime = statBuf.st_mtime;
00848         mssb->st_ctime = statBuf.st_ctime;
00849     }
00850     return rv;
00851 } /* end PR_Stat() */
00852 
00853 
00854 
00855 /* $$ end W16io.c */