home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / src / md / windows / w16io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  18.8 KB  |  837 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "primpl.h"
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <share.h>
  23. #include <sys/locking.h>
  24.  
  25.  
  26. /*
  27. ** Sleep this many milliseconds on each I/O operation
  28. ** to cause an intentional thread switch. 
  29. */
  30. #define _PR_MD_WIN16_DELAY 1
  31.  
  32.  
  33. /*
  34. ** PR_MD_RegisterW16StdioCallbacks() -- Register Win16 stdio callback functions
  35. **
  36. ** This public function call is unique to Win16. 
  37. ** ... Sigh ... So much for platform independence.
  38. ** 
  39. ** To get stdio to work from a command line executable, the stdio stream
  40. ** calls must be issued from the .EXE file; calling them from the .DLL
  41. ** sends the output to the bit-bucket. Therefore, the .EXE wanting to
  42. ** do stdio to the console window (must be built as a "quickwin" application)
  43. ** must have the wrapper functions defined in this module statically linked
  44. ** into the .EXE.
  45. **
  46. ** There appears to be nothing you can do to get stdio to work from a
  47. ** Win16 GUI application. Oh Well!
  48. **
  49. */
  50. PRStdinRead   _pr_md_read_stdin = 0;
  51. PRStdoutWrite _pr_md_write_stdout = 0;
  52. PRStderrWrite _pr_md_write_stderr = 0;
  53.  
  54. PRStatus
  55. PR_MD_RegisterW16StdioCallbacks( PRStdinRead inReadf, PRStdoutWrite outWritef, PRStderrWrite errWritef )
  56. {
  57.     _pr_md_write_stdout = outWritef;
  58.     _pr_md_write_stderr = errWritef;
  59.     _pr_md_read_stdin   = inReadf;
  60.     
  61.     return(PR_SUCCESS);
  62. } /* end PR_MD_RegisterW16StdioCallbacks() */
  63.  
  64.  
  65. /*
  66. ** _PR_MD_OPEN() -- Open a file
  67. **
  68. ** Returns: a fileHandle or -1
  69. **
  70. **
  71. */
  72. PRInt32
  73. _PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
  74. {
  75.     PRInt32 file;
  76.     int     access = O_BINARY;
  77.     int     rights = 0;
  78.     
  79.     
  80.     /*
  81.     ** Map NSPR open flags to os open flags
  82.     */
  83.     if (osflags & PR_RDONLY )
  84.         access |= O_RDONLY;
  85.     if (osflags & PR_WRONLY )
  86.         access |= O_WRONLY;
  87.     if (osflags & PR_RDWR )
  88.         access |= O_RDWR;
  89.     if (osflags & PR_CREATE_FILE )
  90.     {
  91.         access |= O_CREAT;
  92.         rights |= S_IRWXU;
  93.     }
  94.     if (osflags & PR_TRUNCATE)
  95.         access |= O_TRUNC;
  96.     if (osflags & PR_APPEND)
  97.         access |= O_APPEND;
  98.     else
  99.         access |= O_RDONLY;
  100.         
  101.     /*
  102.     ** Open the file
  103.     */        
  104.     file = (PRInt32) sopen( name, access, SH_DENYNO, rights );
  105.     if ( -1 == (PRInt32)file )
  106.     {
  107.         _PR_MD_MAP_OPEN_ERROR( errno );
  108.     }
  109.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  110.     return file;
  111. }
  112.  
  113. /*
  114. ** _PR_MD_READ() - Read something
  115. **
  116. ** Returns: bytes read or -1
  117. **
  118. */
  119. PRInt32
  120. _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
  121. {
  122.     PRInt32     rv;
  123.     
  124.     if ( (PR_GetDescType(fd) == PR_DESC_FILE) &&
  125.          ( fd->secret->md.osfd == PR_StandardInput ) &&
  126.          ( _pr_md_write_stdout ))
  127.     {
  128.         rv = (*_pr_md_read_stdin)( buf, len);    
  129.     }
  130.     else
  131.     {
  132.         rv = read( fd->secret->md.osfd, buf, len );
  133.     }
  134.     
  135.     if ( rv == -1)
  136.     {
  137.         _PR_MD_MAP_READ_ERROR( errno );
  138.     }
  139.     
  140.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  141.     return rv;
  142. }
  143.  
  144. /*
  145. ** _PR_MD_WRITE() - Write something
  146. **
  147. ** Returns:  bytes written or -1
  148. **
  149. ** Note: for file handles 1 and 2 (stdout and stderr)
  150. ** call the Win16 NSPR stdio callback functions, if they are 
  151. ** registered.
  152. **
  153. */
  154. PRInt32
  155. _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
  156. {
  157.     PRInt32     rv;
  158.  
  159.     if ( (PR_GetDescType(fd) == PR_DESC_FILE))
  160.     {
  161.         switch ( fd->secret->md.osfd )
  162.         {
  163.             case  PR_StandardOutput :
  164.                 if ( _pr_md_write_stdout )
  165.                     rv = (*_pr_md_write_stdout)( (void *)buf, len);
  166.                 else
  167.                     rv = len; /* fake success */
  168.                 break;
  169.                 
  170.             case  PR_StandardError  :
  171.                 if ( _pr_md_write_stderr )
  172.                     rv = (*_pr_md_write_stderr)( (void *)buf, len);    
  173.                 else
  174.                     rv = len; /* fake success */
  175.                 break;
  176.                 
  177.             default:
  178.                 rv = write( fd->secret->md.osfd, buf, len );
  179.                 if ( rv == -1 )
  180.                 {
  181.                     _PR_MD_MAP_WRITE_ERROR( errno );
  182.                 }
  183.                 break;
  184.         }
  185.     }
  186.     else
  187.     {
  188.         rv = write( fd->secret->md.osfd, buf, len );
  189.         if ( rv == -1 )
  190.         {
  191.             _PR_MD_MAP_WRITE_ERROR( errno );
  192.         }
  193.     }
  194.     
  195.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  196.     return rv;
  197. } /* --- end _PR_MD_WRITE() --- */
  198.  
  199. /*
  200. ** _PR_MD_LSEEK() - Seek to position in a file
  201. **
  202. ** Note: 'whence' maps directly to PR_...
  203. **
  204. ** Returns:
  205. **
  206. */
  207. PRInt32
  208. _PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, int whence)
  209. {
  210.     PRInt32     rv;
  211.     
  212.     rv = lseek( fd->secret->md.osfd, offset, whence );
  213.     if ( rv == -1 )
  214.     {
  215.         _PR_MD_MAP_LSEEK_ERROR( errno );
  216.         
  217.     }
  218.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  219.     return( rv );
  220. }
  221.  
  222. /*
  223. ** _PR_MD_LSEEK64() -- Seek to position in file, 64bit offset.
  224. **
  225. */
  226. PRInt64
  227. _PR_MD_LSEEK64( PRFileDesc *fd, PRInt64 offset, int whence )
  228. {
  229.     PRInt64 test;
  230.     PRInt32 rv, off;
  231.     LL_SHR(test, offset, 32);
  232.     if (!LL_IS_ZERO(test))
  233.     {
  234.         PR_SetError(PR_FILE_TOO_BIG_ERROR, 0);
  235.         LL_I2L(test, -1);
  236.         return test;
  237.     }
  238.     LL_L2I(off, offset);
  239.     rv = _PR_MD_LSEEK(fd, off, whence);
  240.     LL_I2L(test, rv);
  241.     return test;
  242. } /* end _PR_MD_LSEEK64() */
  243.  
  244. /*
  245. ** _PR_MD_FSYNC() - Flush file buffers.
  246. **
  247. ** Returns:
  248. **
  249. **
  250. */
  251. PRInt32
  252. _PR_MD_FSYNC(PRFileDesc *fd)
  253. {
  254.     PRInt32     rv;
  255.     
  256.     rv = (PRInt32) fsync( fd->secret->md.osfd );
  257.     if ( rv == -1 )
  258.     {
  259.         _PR_MD_MAP_FSYNC_ERROR( errno );
  260.     }
  261.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  262.     return(rv);
  263. }
  264.  
  265. /*
  266. ** _PR_MD_CLOSE() - Close an open file handle
  267. **
  268. ** Returns:
  269. **
  270. **
  271. */
  272. PRInt32
  273. _PR_MD_CLOSE_FILE(PRInt32 osfd)
  274. {
  275.     PRInt32     rv;
  276.     
  277.     rv = (PRInt32) close( osfd );
  278.     if ( rv == -1 )
  279.     {
  280.         _PR_MD_MAP_CLOSE_ERROR( errno );
  281.     }
  282.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  283.     return(rv);
  284. } /* --- end _MD_CloseFile() --- */
  285.  
  286.  
  287. /* --- DIR IO ------------------------------------------------------------ */
  288. #define GetFileFromDIR(d)       (d)->d_entry.cFileName
  289.  
  290. /*
  291. ** FlipSlashes() - Make forward slashes ('/') into backslashes
  292. **
  293. ** Returns: void
  294. **
  295. **
  296. */
  297. void FlipSlashes(char *cp, int len)
  298. {
  299.     while (--len >= 0) {
  300.     if (cp[0] == '/') {
  301.         cp[0] = PR_DIRECTORY_SEPARATOR;
  302.     }
  303.     cp++;
  304.     }
  305. }
  306.  
  307.  
  308. /*
  309. ** _PR_MD_OPEN_DIR() - Open a Directory.
  310. **
  311. ** Returns:
  312. **
  313. **
  314. */
  315. PRStatus
  316. _PR_MD_OPEN_DIR(_MDDir *d, const char *name)
  317. {
  318.     d->dir = opendir( name );
  319.     
  320.     if ( d->dir == NULL )
  321.     {
  322.         _PR_MD_MAP_OPENDIR_ERROR( errno );
  323.         return( PR_FAILURE );
  324.     }
  325.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  326.     return( PR_SUCCESS );
  327. }
  328.  
  329.  
  330. /*
  331. ** _PR_MD_READ_DIR() - read next directory entry
  332. **
  333. **
  334. */
  335. char *
  336. _PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
  337. {
  338.     struct dirent *de;
  339.     int err;
  340.  
  341.     for (;;) 
  342.     {
  343.         de = readdir( d->dir );
  344.         if ( de == NULL ) {
  345.             _PR_MD_MAP_READDIR_ERROR( errno);
  346.             return 0;
  347.         }        
  348.         if ((flags & PR_SKIP_DOT) &&
  349.             (de->d_name[0] == '.') && (de->d_name[1] == 0))
  350.             continue;
  351.         if ((flags & PR_SKIP_DOT_DOT) &&
  352.             (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
  353.             (de->d_name[2] == 0))
  354.             continue;
  355.         break;
  356.     }
  357.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  358.     return de->d_name;
  359. }
  360.  
  361. /*
  362. ** _PR_MD_CLOSE_DIR() - Close a directory.
  363. **
  364. **
  365. */
  366. PRInt32
  367. _PR_MD_CLOSE_DIR(_MDDir *d)
  368. {
  369.     PRInt32     rv;
  370.     
  371.     if ( d->dir ) 
  372.     {
  373.         rv = closedir( d->dir );
  374.         if (rv != 0) 
  375.         {
  376.             _PR_MD_MAP_CLOSEDIR_ERROR( errno );
  377.         }
  378.     }
  379.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  380.     return rv;
  381. }
  382.  
  383.  
  384. /*
  385. ** _PR_MD_DELETE() - Delete a file.
  386. **
  387. ** Returns:
  388. **
  389. **
  390. */
  391. PRInt32
  392. _PR_MD_DELETE(const char *name)
  393. {
  394.     PRInt32     rv;
  395.     
  396.     rv = (PRInt32) remove( name );
  397.     if ( rv != 0 )
  398.     {
  399.         _PR_MD_MAP_DELETE_ERROR( errno );
  400.     }
  401.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  402.     return(rv);
  403. }
  404.  
  405.  
  406. /*
  407. ** _PR_MD_STAT() - Get file attributes by filename
  408. **
  409. ** Returns:
  410. **
  411. **
  412. */
  413. PRInt32
  414. _PR_MD_STAT(const char *fn, struct stat *info)
  415. {
  416.     PRInt32     rv;
  417.     
  418.     rv = _stat(fn, (struct _stat *)info);
  419.     if ( rv == -1 )
  420.     {
  421.         _PR_MD_MAP_STAT_ERROR( errno );
  422.     }
  423.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  424.     return( rv );
  425. }
  426.  
  427. /*
  428. ** _PR_MD_GETFILEINFO() - Get file attributes by filename
  429. **
  430. ** Returns:
  431. **
  432. **
  433. */
  434. PRInt32
  435. _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
  436. {
  437.     struct _stat sb;
  438.     PRInt32 rv;
  439.  
  440.     if ( (rv = _stat(fn, &sb)) == 0 ) {
  441.         if (info) {
  442.             if (S_IFREG & sb.st_mode)
  443.                 info->type = PR_FILE_FILE ;
  444.             else if (S_IFDIR & sb.st_mode)
  445.                 info->type = PR_FILE_DIRECTORY;
  446.             else
  447.                 info->type = PR_FILE_OTHER;
  448.             info->size = sb.st_size;
  449.             LL_I2L(info->modifyTime, sb.st_mtime);
  450.             LL_I2L(info->creationTime, sb.st_ctime);
  451.         }
  452.     }
  453.     else
  454.     {
  455.         _PR_MD_MAP_STAT_ERROR( errno );
  456.     }
  457.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  458.     return rv;
  459. }
  460.  
  461. PRInt32
  462. _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
  463. {
  464.     PRFileInfo info32;
  465.     
  466.     PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32);
  467.     if (0 == rv)
  468.     {
  469.         info->type = info32.type;
  470.         info->modifyTime = info32.modifyTime;
  471.         info->creationTime = info32.creationTime;
  472.         LL_I2L(info->size, info32.size);
  473.     }
  474.     return(rv);
  475. }
  476.  
  477. /*
  478. ** _PR_MD_GETOPENFILEINFO() - Get file attributes from an open file handle
  479. **
  480. ** Returns:
  481. **
  482. **
  483. */
  484. PRInt32
  485. _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
  486. {
  487.     struct stat statBuf;
  488.     PRInt32 rv = PR_SUCCESS;
  489.     
  490.     rv = fstat( fd->secret->md.osfd, &statBuf );
  491.     if ( rv == 0)
  492.     {
  493.         if (statBuf.st_mode & S_IFREG )
  494.             info->type = PR_FILE_FILE;
  495.         else if ( statBuf.st_mode & S_IFDIR )
  496.             info->type = PR_FILE_DIRECTORY;
  497.         else
  498.             info->type = PR_FILE_OTHER;
  499.         info->size = statBuf.st_size;
  500.         LL_I2L(info->modifyTime, statBuf.st_mtime);
  501.         LL_I2L(info->creationTime, statBuf.st_ctime);
  502.         
  503.     }
  504.     else
  505.     {
  506.         _PR_MD_MAP_FSTAT_ERROR( errno );
  507.     }
  508.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  509.     return(rv);
  510. }
  511.  
  512. PRInt32
  513. _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
  514. {
  515.     PRFileInfo info32;
  516.     
  517.     PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32);
  518.     if (0 == rv)
  519.     {
  520.         info->type = info32.type;
  521.         info->modifyTime = info32.modifyTime;
  522.         info->creationTime = info32.creationTime;
  523.         LL_I2L(info->size, info32.size);
  524.     }
  525.     return(rv);
  526. }
  527.  
  528. /*
  529. ** _PR_MD_RENAME() - Rename a file
  530. **
  531. ** Returns:
  532. **
  533. **
  534. */
  535. PRInt32
  536. _PR_MD_RENAME(const char *from, const char *to)
  537. {
  538.     PRInt32 rv;
  539.     
  540.     rv = rename( from, to );
  541.     if ( rv == -1 )
  542.     {
  543.         _PR_MD_MAP_RENAME_ERROR( errno );
  544.     }
  545.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  546.     return( rv );
  547. }
  548.  
  549. /*
  550. ** _PR_MD_ACCESS() - Return file acesss attribute.
  551. **
  552. ** Returns:
  553. **
  554. **
  555. */
  556. PRInt32
  557. _PR_MD_ACCESS(const char *name, PRIntn how)
  558. {
  559.     PRInt32     rv;
  560.     int         mode = 0;
  561.     
  562.     if ( how & PR_ACCESS_WRITE_OK )
  563.         mode |= W_OK;
  564.     if ( how & PR_ACCESS_READ_OK )
  565.         mode |= R_OK;
  566.         
  567.     rv = (PRInt32) access( name, mode );        
  568.     if ( rv == -1 )
  569.     {
  570.         _PR_MD_MAP_ACCESS_ERROR( errno );
  571.     }
  572.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  573.     return(rv);
  574. }
  575.  
  576. /*
  577. ** _PR_MD_MKDIR() - Make a directory
  578. **
  579. ** Returns:
  580. **
  581. **
  582. */
  583. PRInt32
  584. _PR_MD_MKDIR(const char *name, PRIntn mode)
  585. {
  586.     PRInt32 rv;
  587.         
  588.     rv = mkdir( name );
  589.     if ( rv == 0 )
  590.     {
  591.         PR_Sleep( _PR_MD_WIN16_DELAY );    
  592.         return PR_SUCCESS;
  593.     }
  594.     else
  595.     {
  596.         _PR_MD_MAP_MKDIR_ERROR( errno );
  597.         PR_Sleep( _PR_MD_WIN16_DELAY );    
  598.         return PR_FAILURE;
  599.     }
  600. }
  601.  
  602. /*
  603. ** _PR_MD_RMDIR() - Delete a directory
  604. **
  605. ** Returns:
  606. **
  607. **
  608. */
  609. PRInt32
  610. _PR_MD_RMDIR(const char *name)
  611. {
  612.     PRInt32 rv;
  613.     
  614.     rv = (PRInt32) rmdir( name );
  615.     if ( rv == -1 )
  616.     {
  617.         _PR_MD_MAP_RMDIR_ERROR( errno );
  618.     }
  619.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  620.     return(rv);
  621. }
  622.  
  623. /*
  624. ** _PR_MD_LOCKFILE() - Lock a file.
  625. **
  626. ** The _locking() call locks relative to the current file pointer.
  627. ** This function is required to lock all of the file, so,
  628. ** 1. Seek to the beginning of the file, preserving the original position.
  629. ** 2. Lock the file, pausing if it is locked by someone else, and
  630. **    try again.
  631. ** 3. Re-position to the original position in the file.
  632. **
  633. ** For unlocking, a similar protocol of positioning is required.
  634. **
  635. */
  636. PRStatus
  637. _PR_MD_LOCKFILE(PRInt32 f)
  638. {
  639.     PRInt32 rv = PR_SUCCESS;    /* What we return to our caller */
  640.     long    seekOrigin;         /* original position in file */
  641.     PRInt32 rc;                 /* what the system call returns to us */
  642.  
  643.     /*
  644.     ** Seek to beginning of file, saving original position.
  645.     */    
  646.     seekOrigin = lseek( f, 0l, SEEK_SET );
  647.     if ( rc == -1 )
  648.     {
  649.         _PR_MD_MAP_LSEEK_ERROR( errno );
  650.         return( PR_FAILURE );
  651.     }
  652.     
  653.     /*
  654.     ** Attempt to lock the file.
  655.     ** If someone else has it, Sleep-a-while and try again.
  656.     */
  657.     for( rc = -1; rc != 0; )
  658.     {
  659.         rc = _locking( f, _LK_NBLCK , 0x7fffffff );
  660.         if ( rc == -1 )
  661.         {
  662.             if ( errno == EACCES )
  663.             {
  664.                 PR_Sleep( 100 );
  665.                 continue;
  666.             }
  667.             else
  668.             {
  669.                 _PR_MD_MAP_LOCKF_ERROR( errno );
  670.                 rv = PR_FAILURE;
  671.                 break;
  672.             }
  673.         }
  674.     } /* end for() */
  675.     
  676.     /*
  677.     ** Now that the file is locked, re-position to
  678.     ** the original file position.
  679.     **
  680.     */
  681.     rc = lseek( f, seekOrigin, SEEK_SET );
  682.     if ( rc == -1 )
  683.     {
  684.         _PR_MD_MAP_LSEEK_ERROR( errno );
  685.         rv = PR_FAILURE;
  686.     }
  687.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  688.     return PR_SUCCESS;
  689. } /* end _PR_MD_LOCKFILE() */
  690.  
  691. /*
  692. ** _PR_MD_TLOCKFILE() - Test and Lock file.
  693. **
  694. ** The _locking() call locks relative to the current file pointer.
  695. ** This function is required to lock all of the file, so,
  696. ** 1. Seek to the beginning of the file, preserving the original position.
  697. ** 2. Attempt to Lock the file.
  698. **    If the file is locked by someone else, try NO MORE.
  699. ** 3. Re-position to the original position in the file.
  700. **
  701. ** See the discussion of _PR_MD_LOCKFILE
  702. **
  703. **
  704. */
  705. PRStatus
  706. _PR_MD_TLOCKFILE(PRInt32 f)
  707. {
  708.     PRInt32 rv = PR_SUCCESS;    /* What we return */
  709.     long    seekOrigin;         /* original position in file */
  710.     PRInt32 rc;                 /* return value from system call */
  711.  
  712.     /*
  713.     ** Seek to beginning of file, saving original position.
  714.     */    
  715.     seekOrigin = lseek( f, 0l, SEEK_SET );
  716.     if ( rc == -1 )
  717.     {
  718.         _PR_MD_MAP_LSEEK_ERROR( errno );
  719.         return( PR_FAILURE );
  720.     }
  721.     
  722.     /*
  723.     ** Attempt to lock the file. One ping; one ping only, Vasily.
  724.     ** If someone else has it, Reposition and return failure.
  725.     */
  726.     rc = _locking( f, _LK_NBLCK , 0x7fffffff );
  727.     if ( rc == -1 )
  728.     {
  729.         if ( errno != EACCES )
  730.             _PR_MD_MAP_LOCKF_ERROR( errno );
  731.         rv = PR_FAILURE;
  732.     }
  733.     
  734.     /*
  735.     ** Now that the file is locked, maybe, re-position to
  736.     ** the original file position.
  737.     */
  738.     rc = lseek( f, seekOrigin, SEEK_SET );
  739.     if ( rc == -1 )
  740.     {
  741.         _PR_MD_MAP_LSEEK_ERROR( errno );
  742.         rv = PR_FAILURE;
  743.     }
  744.     
  745.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  746.     return rv;
  747. } /* end _PR_MD_TLOCKFILE() */
  748.  
  749.  
  750. /*
  751. ** _PR_MD_UNLOCKFILE() - Unlock a file.
  752. **
  753. ** See the discussion of _PR_MD_LOCKFILE
  754. **
  755. */
  756. PRStatus
  757. _PR_MD_UNLOCKFILE(PRInt32 f)
  758. {
  759.     PRInt32 rv = PR_SUCCESS;    /* What we return */
  760.     long    seekOrigin;         /* original position in file */
  761.     PRInt32 rc;                 /* return value from system call */
  762.  
  763.     /*
  764.     ** Seek to beginning of file, saving original position.
  765.     */    
  766.     seekOrigin = lseek( f, 0l, SEEK_SET );
  767.     if ( rc == -1 )
  768.     {
  769.         _PR_MD_MAP_LSEEK_ERROR( errno );
  770.         return( PR_FAILURE );
  771.     }
  772.     
  773.     /*
  774.     ** Unlock the file.
  775.     */
  776.     rc = _locking( f, _LK_UNLCK , 0x7fffffff );
  777.     if ( rc == -1 )
  778.     {
  779.         _PR_MD_MAP_LOCKF_ERROR( errno );
  780.         rv = PR_FAILURE;
  781.     }
  782.     
  783.     /*
  784.     ** Now that the file is unlocked, re-position to
  785.     ** the original file position.
  786.     */
  787.     rc = lseek( f, seekOrigin, SEEK_SET );
  788.     if ( rc == -1 )
  789.     {
  790.         _PR_MD_MAP_LSEEK_ERROR( errno );
  791.         rv = PR_FAILURE;
  792.     }
  793.     PR_Sleep( _PR_MD_WIN16_DELAY );    
  794.     return rv;
  795. } /* end _PR_MD_UNLOCKFILE() */
  796.  
  797. /*
  798. ** PR_Stat() -- Return status on a file
  799. **
  800. ** This is a hack! ... See BugSplat: 98516 
  801. ** Basically, this hack takes a name and stat buffer as input.
  802. ** The input stat buffer is presumed to be a Microsoft stat buffer.
  803. ** The functions does a Watcom stat() then maps the result to
  804. ** the MS stat buffer. ...
  805. **
  806. */
  807. PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
  808. {
  809.     PRInt32     rv;
  810.     _MDMSStat   *mssb = (_MDMSStat*) buf; /* this is Microsoft's stat buffer */
  811.     struct stat statBuf;   /* this is Watcom's stat buffer */
  812.  
  813.     /* First, get Watcom's idea of stat
  814.     ** then reformat it into a Microsoft idea of stat
  815.     */
  816.     rv = (PRInt32) _stat( name, &statBuf);
  817.     if (rv == 0l )
  818.     {
  819.         mssb->st_dev = statBuf.st_dev;
  820.         mssb->st_ino = statBuf.st_ino; /* not used, really */
  821.         mssb->st_mode = statBuf.st_mode;
  822.         mssb->st_nlink = 1; /* always 1, says MS */
  823.         mssb->st_uid = statBuf.st_uid;
  824.         mssb->st_gid = statBuf.st_gid;
  825.         mssb->st_rdev = statBuf.st_rdev; /* please Gh0d! Let these be the same */
  826.         mssb->st_size = statBuf.st_size;
  827.         mssb->st_atime = statBuf.st_atime;
  828.         mssb->st_mtime = statBuf.st_mtime;
  829.         mssb->st_ctime = statBuf.st_ctime;
  830.     }
  831.     return rv;
  832. } /* end PR_Stat() */
  833.  
  834.  
  835.  
  836. /* $$ end W16io.c */
  837.