home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / CLIBSRC3.ZIP / LOCKING.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  5.2 KB  |  169 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - locking.c
  3.  *
  4.  * function(s)
  5.  *        wait1    - wait 1 second
  6.  *        locking  - sets or resets file sharing locks (MSC compatible)
  7.  *-----------------------------------------------------------------------*/
  8.  
  9. /*
  10.  *      C/C++ Run Time Library - Version 5.0
  11.  *
  12.  *      Copyright (c) 1991, 1992 by Borland International
  13.  *      All Rights Reserved.
  14.  *
  15.  */
  16.  
  17.  
  18. #include <io.h>
  19. #include <_io.h>
  20. #include <dos.h>
  21. #include <errno.h>
  22. #include <sys\locking.h>
  23.  
  24.  
  25. /*-----------------------------------------------------------------------*
  26.  
  27. Name            wait1 - wait 1 second
  28.  
  29. Usage           void wait1(void);
  30.  
  31. Prototype in    local
  32.  
  33. Description     wait1() uses _dos_gettime() in a spin loop to wait 1 second.
  34.  
  35. Return value    No value is returned.
  36.  
  37. Portability     Unique to MS-DOS. On multi-tasking operating systems
  38.                 this should be rewritten to do a wait.
  39.  
  40. *------------------------------------------------------------------------*/
  41.  
  42. static void pascal near wait1(void)
  43. {
  44.     struct dostime_t start, end;
  45.     unsigned char endsec;
  46.  
  47.     /* Get current time.
  48.      */
  49.     _dos_gettime(&start);
  50.     if (start.second == 59)
  51.         endsec = 0;
  52.     else
  53.         endsec = start.second + 1;
  54.  
  55.     /* Wait for second to change.
  56.      */
  57.     do {
  58.         _dos_gettime(&end);
  59.     } while (end.second == start.second);
  60.  
  61.     /* Wait for hundredths of seconds to catch up.
  62.      */
  63.     while (end.second == endsec && end.hsecond < start.hsecond) {
  64.         _dos_gettime(&end);
  65.     }
  66. }
  67.  
  68. /*-----------------------------------------------------------------------*
  69.  
  70. Name            locking - sets file sharing locks
  71.  
  72. Usage           int locking(int handle, int mode, long length);
  73.  
  74. Prototype in    io.h
  75.  
  76. Description     locking provides an interface to the MS-DOS
  77.                 3.x file-sharing mechanism.  The region to be locked
  78.                 or unlocked starts at the current file position;
  79.                 the size of the region is given by length.
  80.  
  81.                 The mode parameter specifies the action (values
  82.                 for mode are given in <sys\locking.h>):
  83.  
  84.                 LK_LOCK         lock the region; if unsuccessful, try
  85.                                 once a second for 10 seconds before
  86.                                 giving up.
  87.                 LK_NBLCK        lock the region, if unsuccessful, give
  88.                                 up immediately.
  89.                 LK_NBRLCK       Same as LK_NBLCK.
  90.                 LK_RCLK         Same as LK_LOCK.
  91.                 LK_UNLCK        Unlock the region, which must have
  92.                                 been previously locked.
  93.  
  94.                 Locks can be placed on arbitrary, non-overlapping regions of
  95.                 any file. A program attempting to read or write into a
  96.                 locked region will retry the operation three times. If all
  97.                 three retries fail, the call fails with an error.
  98.  
  99.                 unlock removes lock; to avoid error, lock must be removed
  100.                 before a file is closed. A program must release all lock(s)
  101.                 before completing.
  102.  
  103. Return value    Locking return 0 on success.  On failure, -1 is returned,
  104.                 and errno is set to one of the following:
  105.  
  106.                 EACCESS         File already locked or unlocked
  107.                 EBADF           Bad file number
  108.                 EDEADLOCK       File cannot be locked after 10 retries
  109.                                 (mode is LK_LOCK or LK_RLCK)
  110.                 EINVAL          Invalid mode
  111.  
  112.  
  113. Portability     Unique to MS-DOS 3.x. Older versions of MS-DOS do
  114.                 not support these calls.
  115.  
  116. Note            Compatible with Microsoft C.  Not the same as lock().
  117.  
  118.  
  119. *------------------------------------------------------------------------*/
  120.  
  121. int _FARFUNC locking(int handle, int mode, long length)
  122. {
  123.     int tries;
  124.     long offset;
  125.  
  126.     /* Get current file offset, which gives the start of
  127.      * the region to be locked or unlocked.  This also
  128.      * verifies the file handle.
  129.      */
  130.     if (_dos_seek(handle,0L,SEEK_CUR,&offset) != 0)
  131.             return (-1);
  132.  
  133.     switch (mode)
  134.     {
  135.     case LK_LOCK:
  136.     case LK_RLCK:
  137.  
  138.         /* Try 10 times, once every second, to lock the file.
  139.          */
  140.         for (tries = 1; tries <= 10; tries++)
  141.             {
  142.             if (_dos_lock(handle,offset,length) == 0)
  143.                     return (0);             /* success */
  144.             if (errno != EACCES)        /* not a locking violation? */
  145.                     return (-1);                /* return right away */
  146.             wait1();                        /* failed - try again 1 sec later */
  147.             }
  148.         errno = EDEADLOCK;                  /* give up */
  149.         return (-1);
  150.  
  151.     case LK_NBLCK:
  152.     case LK_NBRLCK:
  153.  
  154.         /* Lock the region, give up immediately if not sucessful.
  155.          */
  156.         return (_dos_lock(handle,offset,length) == 0 ? 0 : -1);
  157.  
  158.     case LK_UNLCK:
  159.  
  160.         /* Unlock the region.
  161.          */
  162.         return (_dos_unlock(handle,offset,length) == 0 ? 0 : -1);
  163.  
  164.     default:
  165.         errno = EINVAL;
  166.         return (-1);
  167.     }
  168. }
  169.