home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 295_01 / lockb.c < prev    next >
Text File  |  1989-12-30  |  5KB  |  194 lines

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