home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / DOOG / CBASE09.ZIP / BLKIO10.ZIP / LOCKB.C < prev    next >
Text File  |  1989-08-30  |  4KB  |  181 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "lockb.c    1.1 - 89/07/03" */
  5.  
  6. #include "blkio_.h"
  7.  
  8. #include <errno.h>
  9. #if HOST == UNIX
  10. #include <fcntl.h>
  11. #elif HOST == MSDOS
  12. #endif
  13.  
  14. /*man---------------------------------------------------------------------------
  15. NAME
  16.      lockb - block file record locking
  17.  
  18. SYNOPSIS
  19.      #include <blkio.h>
  20.  
  21.      int lockb(bp, l_type, bn, size)
  22.      BLKFILE *bp;
  23.      int l_type;
  24.      bpos_t bn;
  25.      size_t size;
  26.  
  27. DESCRIPTION
  28.      The lockb function will allow segments of a block file to be locked.  bp
  29.      is the BLKFILE pointer for the file to be locked.
  30.  
  31.      l_type indicates the target status of the lock.  The lock types available
  32.      are:
  33.  
  34.           B_UNLCK     unlock block file segment
  35.           B_RDLCK     lock block file segment for reading
  36.           B_WRLCK     lock block file segment for reading and writing
  37.           B_RDLKW     lock block file segment for reading (wait)
  38.           B_WRLKW     lock block file segment for reading and writing (wait)
  39.  
  40.      For the lock types which wait, lockb will not return until the
  41.      lock is available.  For the lock types which do not wait, if the
  42.      lock is unavailable because of a lock held by another process  a
  43.      value of -1 is returned and errno set to EAGAIN.
  44.  
  45.      bn is the first block to lock.  size is the number of contiguous blocks
  46.      including and following block bn to be locked or unlocked.
  47.  
  48.      lockb will fail if one or more of the following is true:
  49.  
  50.      [EAGAIN]       l_type is B_RDLCK and the file segment to
  51.                     be locked is already write locked by another
  52.                     process, or l_type is B_WRLCK and the file
  53.                     segment to be locked is already read or write
  54.                     locked by another process.
  55.      [EINVAL]       bp is is not a valid BLKFILE pointer.
  56.      [EINVAL]       l_type is not one of the valid lock types.
  57.      [BENOPEN]      bp is not open.
  58.      [BENOPEN]      l_type is B_RDLCK or B_RDLKW and bp is not
  59.                     opened for reading or l_type is B_WRLCK or
  60.                     B_WRLKW and bp is not open for writing.
  61.  
  62. DIAGNOSTICS
  63.      Upon successful completion, a value of 0 is returned.  Otherwise, a
  64.      value of -1 is returned, and errno set to indicate the error.
  65.  
  66. ------------------------------------------------------------------------------*/
  67. int lockb(bp, l_type, bn, size)
  68. BLKFILE * bp;
  69. int       l_type;
  70. bpos_t    bn;
  71. size_t    size;
  72. {
  73.     int        rs    = 0;
  74. #if HOST == UNIX
  75.     int        cmd    = 0;
  76.     struct flock    lck    /*= {0}*/;
  77. #elif HOST == MSDOS
  78. #endif
  79.  
  80.     /* validate arguments */
  81.     if (!b_valid(bp)) {
  82.         errno = EINVAL;
  83.         return -1;
  84.     }
  85.  
  86.     /* check if not open */
  87.     if (!(bp->flags & BIOOPEN)) {
  88.         errno = BENOPEN;
  89.         return -1;
  90.     }
  91.  
  92.     /* set lock flags */
  93.     switch (l_type) {
  94.     case B_RDLCK:
  95.         if (!(bp->flags & BIOREAD)) {
  96.             errno = BENOPEN;
  97.             return -1;
  98.         }
  99. #if HOST == UNIX
  100.         cmd = F_SETLK;
  101.         lck.l_type = F_RDLCK;
  102. #elif HOST == MSDOS
  103. #endif
  104.         break;
  105.     case B_RDLKW:
  106.         if (!(bp->flags & BIOREAD)) {
  107.             errno = BENOPEN;
  108.             return -1;
  109.         }
  110. #if HOST == UNIX
  111.         cmd = F_SETLKW;
  112.         lck.l_type = F_RDLCK;
  113. #elif HOST == MSDOS
  114. #endif
  115.         break;
  116.     case B_WRLCK:
  117.         if (!(bp->flags & BIOWRITE)) {
  118.             errno = BENOPEN;
  119.             return -1;
  120.         }
  121. #if HOST == UNIX
  122.         cmd = F_SETLK;
  123.         lck.l_type = F_WRLCK;
  124. #elif HOST == MSDOS
  125. #endif
  126.         break;
  127.     case B_WRLKW:
  128.         if (!(bp->flags & BIOWRITE)) {
  129.             errno = BENOPEN;
  130.             return -1;
  131.         }
  132. #if HOST == UNIX
  133.         cmd = F_SETLKW;
  134.         lck.l_type = F_WRLCK;
  135. #elif HOST == MSDOS
  136. #endif
  137.         break;
  138.     case B_UNLCK:
  139.         /* flush buffers */
  140.         rs = bflush(bp);
  141.         if (rs == -1) {
  142.             BEPRINT;
  143.             return -1;
  144.         }
  145. #if HOST == UNIX
  146.         cmd = F_SETLK;
  147.         lck.l_type = F_UNLCK;
  148. #elif HOST == MSDOS
  149. #endif
  150.         break;
  151.     default:
  152.         errno = EINVAL;
  153.         return -1;
  154.         break;
  155.     }
  156.  
  157.     /* lock block file */
  158. #if HOST == UNIX
  159.     if (bn == 0) {
  160.         lck.l_whence = 0;
  161.     } else {
  162.         lck.l_whence = bp->hdrsize + (bn - 1) * bp->blksize;
  163.     }
  164.     lck.l_start = 0;
  165.     lck.l_len = bp->blksize * size;
  166.     lck.l_sysid = 0;
  167.     lck.l_pid = 0;
  168.     rs = fcntl(bp->fd.ifd, cmd, &lck);
  169.     if (rs == -1) {
  170.         /* new versions of fcntl will use EAGAIN */
  171.         if (errno == EACCES) errno = EAGAIN;
  172.         if (errno != EAGAIN) BEPRINT;
  173.         return -1;
  174.     }
  175. #elif HOST == MSDOS
  176. #endif
  177.  
  178.     errno = 0;
  179.     return 0;
  180. }
  181.