home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CBASE101.ZIP / BLKIO112.ZIP / LOCKB.C < prev    next >
Text File  |  1990-06-20  |  5KB  |  219 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "@(#)lockb.c    1.4 - 90/06/20" */
  5.  
  6. /* ansi headers */
  7. #include <errno.h>
  8. /*#include <stddef.h>*/
  9.  
  10. /* local headers */
  11. #include "blkio_.h"
  12.  
  13. /* function declarations */
  14. #if HOST == UNIX
  15. #include <fcntl.h>
  16. #ifdef AC_PROTO
  17. int fcntl(int fd, int cmd, ...);
  18. #else
  19. int fcntl();
  20. #endif
  21. #elif HOST == MS_DOS
  22.  
  23. #endif
  24.  
  25. /*man---------------------------------------------------------------------------
  26. NAME
  27.      lockb - block file record locking
  28.  
  29. SYNOPSIS
  30.      #include <blkio.h>
  31.  
  32.      int lockb(bp, ltype, start, len)
  33.      BLKFILE *bp;
  34.      int ltype;
  35.      bpos_t start;
  36.      bpos_t len;
  37.  
  38. DESCRIPTION
  39.      The lockb function will allow segments of a block file to be
  40.      locked.  bp is the BLKFILE pointer for the file to be locked.
  41.  
  42.      ltype indicates the target status of the lock.  The lock types
  43.      available are:
  44.  
  45.        B_UNLCK unlock block file segment
  46.        B_RDLCK lock block file segment for reading
  47.        B_WRLCK lock block file segment for reading and writing
  48.        B_RDLKW lock block file segment for reading (wait)
  49.        B_WRLKW lock block file segment for reading and writing (wait)
  50.  
  51.      For the lock types which wait, lockb will not return until the
  52.      lock is available.  For the lock types which do not wait, if the
  53.      lock is unavailable because of a lock held by another process  a
  54.      value of -1 is returned and errno set to EAGAIN.
  55.  
  56.      start is the first block to lock.  len is the number of
  57.      contiguous blocks including and following block start to be
  58.      locked or unlocked.  A lock may be set to extend to the end of
  59.      the file by setting len to zero.
  60.  
  61.      The buffers are flushed before unlocking.
  62.  
  63.      lockb will fail if one or more of the following is true:
  64.  
  65.      [EAGAIN]       ltype is B_RDLCK and the file segment to be locked
  66.                     is already write locked by another process, or
  67.                     ltype is B_WRLCK and the file segment to be locked
  68.                     is already read or write locked by another
  69.                     process.
  70.      [EINVAL]       bp is is not a valid BLKFILE pointer.
  71.      [EINVAL]       ltype is not one of the valid lock types.
  72.      [BENOPEN]      bp is not open.
  73.      [BENOPEN]      ltype is B_RDLCK or B_RDLKW and bp is not opened
  74.                     for reading or ltype is B_WRLCK or B_WRLKW and bp
  75.                     is not open for writing.
  76.  
  77. DIAGNOSTICS
  78.      Upon successful completion, a value of 0 is returned.  Otherwise,
  79.      a value of -1 is returned, and errno set to indicate the error.
  80.  
  81. ------------------------------------------------------------------------------*/
  82. int lockb(bp, ltype, start, len)
  83. BLKFILE *bp;
  84. int ltype;
  85. bpos_t start;
  86. bpos_t len;
  87. {
  88. #if HOST == UNIX
  89.     int cmd = 0;
  90.     struct flock lck;
  91. #elif HOST == MS_DOS
  92.     /* There is no standard mechanism for file locking in MS-DOS.  If
  93.        using a multiuser version of MS_DOS (e.g., Digital Research
  94.        Concurrent DOS) or networking extensions which provide file
  95.        locking, then the file locking calls should be added to this file.
  96.        No other file needs to be modified to use file locking in blkio. */
  97. #endif
  98.     /* validate arguments */
  99.     if (!b_valid(bp)) {
  100.         errno = EINVAL;
  101.         return -1;
  102.     }
  103.  
  104.     /* check if not open */
  105.     if (!(bp->flags & BIOOPEN)) {
  106.         errno = BENOPEN;
  107.         return -1;
  108.     }
  109.  
  110.     /* set lock flags */
  111.     switch (ltype) {
  112.     case B_RDLCK:
  113.         if (!(bp->flags & BIOREAD)) {
  114.             errno = BENOPEN;
  115.             return -1;
  116.         }
  117. #if HOST == UNIX
  118.         cmd = F_SETLK;
  119.         lck.l_type = F_RDLCK;
  120. #elif HOST == MS_DOS
  121.  
  122. #endif
  123.         break;
  124.     case B_RDLKW:
  125.         if (!(bp->flags & BIOREAD)) {
  126.             errno = BENOPEN;
  127.             return -1;
  128.         }
  129. #if HOST == UNIX
  130.         cmd = F_SETLKW;
  131.         lck.l_type = F_RDLCK;
  132. #elif HOST == MS_DOS
  133.  
  134. #endif
  135.         break;
  136.     case B_WRLCK:
  137.         if (!(bp->flags & BIOWRITE)) {
  138.             errno = BENOPEN;
  139.             return -1;
  140.         }
  141. #if HOST == UNIX
  142.         cmd = F_SETLK;
  143.         lck.l_type = F_WRLCK;
  144. #elif HOST == MS_DOS
  145.  
  146. #endif
  147.         break;
  148.     case B_WRLKW:
  149.         if (!(bp->flags & BIOWRITE)) {
  150.             errno = BENOPEN;
  151.             return -1;
  152.         }
  153. #if HOST == UNIX
  154.         cmd = F_SETLKW;
  155.         lck.l_type = F_WRLCK;
  156. #elif HOST == MS_DOS
  157.  
  158. #endif
  159.         break;
  160.     case B_UNLCK:
  161.         /* flush buffers */
  162.         if (bflush(bp) == -1) {
  163.             BEPRINT;
  164.             return -1;
  165.         }
  166. #if HOST == UNIX
  167.         cmd = F_SETLK;
  168.         lck.l_type = F_UNLCK;
  169. #elif HOST == MS_DOS
  170.  
  171. #endif
  172.         break;
  173.     default:
  174.         errno = EINVAL;
  175.         return -1;
  176.         break;
  177.     }
  178.  
  179.     /* lock block file */
  180. #if HOST == UNIX
  181.     if (start == 0) {
  182.         lck.l_whence = 0;
  183.         if (len == 0) {
  184.             lck.l_len = 0;
  185.         } else {
  186.             lck.l_len = bp->hdrsize + (len - 1) * bp->blksize;
  187.         }
  188.     } else {
  189.         lck.l_whence = bp->hdrsize + (start - 1) * bp->blksize;
  190.         if (len == 0) {
  191.             lck.l_len = 0;
  192.         } else {
  193.             lck.l_len = len * bp->blksize;
  194.         }
  195.     }
  196.     lck.l_start = 0;
  197.     lck.l_sysid = 0;
  198.     lck.l_pid = 0;
  199.     if (fcntl(bp->fd.ifd, cmd, &lck) == -1) {
  200.         /* new versions of fcntl will use EAGAIN */
  201.         if (errno == EACCES) errno = EAGAIN;
  202.         if (errno != EAGAIN) BEPRINT;
  203.         return -1;
  204.     }
  205. #elif HOST == MS_DOS
  206.  
  207. #endif
  208.     /* if locking, load endblk */
  209.     if (ltype != B_UNLCK) {
  210.         if (b_uendblk(bp, &bp->endblk) == -1) {
  211.             BEPRINT;
  212.             return -1;
  213.         }
  214.     }
  215.  
  216.     errno = 0;
  217.     return 0;
  218. }
  219.