home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1989 Citadel */
- /* All Rights Reserved */
-
- /* #ident "@(#)lockb.c 1.4 - 90/06/20" */
-
- /* ansi headers */
- #include <errno.h>
- /*#include <stddef.h>*/
-
- /* local headers */
- #include "blkio_.h"
-
- /* function declarations */
- #if HOST == UNIX
- #include <fcntl.h>
- #ifdef AC_PROTO
- int fcntl(int fd, int cmd, ...);
- #else
- int fcntl();
- #endif
- #elif HOST == MS_DOS
-
- #endif
-
- /*man---------------------------------------------------------------------------
- NAME
- lockb - block file record locking
-
- SYNOPSIS
- #include <blkio.h>
-
- int lockb(bp, ltype, start, len)
- BLKFILE *bp;
- int ltype;
- bpos_t start;
- bpos_t len;
-
- DESCRIPTION
- The lockb function will allow segments of a block file to be
- locked. bp is the BLKFILE pointer for the file to be locked.
-
- ltype indicates the target status of the lock. The lock types
- available are:
-
- B_UNLCK unlock block file segment
- B_RDLCK lock block file segment for reading
- B_WRLCK lock block file segment for reading and writing
- B_RDLKW lock block file segment for reading (wait)
- B_WRLKW lock block file segment for reading and writing (wait)
-
- For the lock types which wait, lockb will not return until the
- lock is available. For the lock types which do not wait, if the
- lock is unavailable because of a lock held by another process a
- value of -1 is returned and errno set to EAGAIN.
-
- start is the first block to lock. len is the number of
- contiguous blocks including and following block start to be
- locked or unlocked. A lock may be set to extend to the end of
- the file by setting len to zero.
-
- The buffers are flushed before unlocking.
-
- lockb will fail if one or more of the following is true:
-
- [EAGAIN] ltype is B_RDLCK and the file segment to be locked
- is already write locked by another process, or
- ltype is B_WRLCK and the file segment to be locked
- is already read or write locked by another
- process.
- [EINVAL] bp is is not a valid BLKFILE pointer.
- [EINVAL] ltype is not one of the valid lock types.
- [BENOPEN] bp is not open.
- [BENOPEN] ltype is B_RDLCK or B_RDLKW and bp is not opened
- for reading or ltype is B_WRLCK or B_WRLKW and bp
- is not open for writing.
-
- DIAGNOSTICS
- Upon successful completion, a value of 0 is returned. Otherwise,
- a value of -1 is returned, and errno set to indicate the error.
-
- ------------------------------------------------------------------------------*/
- int lockb(bp, ltype, start, len)
- BLKFILE *bp;
- int ltype;
- bpos_t start;
- bpos_t len;
- {
- #if HOST == UNIX
- int cmd = 0;
- struct flock lck;
- #elif HOST == MS_DOS
- /* There is no standard mechanism for file locking in MS-DOS. If
- using a multiuser version of MS_DOS (e.g., Digital Research
- Concurrent DOS) or networking extensions which provide file
- locking, then the file locking calls should be added to this file.
- No other file needs to be modified to use file locking in blkio. */
- #endif
- /* validate arguments */
- if (!b_valid(bp)) {
- errno = EINVAL;
- return -1;
- }
-
- /* check if not open */
- if (!(bp->flags & BIOOPEN)) {
- errno = BENOPEN;
- return -1;
- }
-
- /* set lock flags */
- switch (ltype) {
- case B_RDLCK:
- if (!(bp->flags & BIOREAD)) {
- errno = BENOPEN;
- return -1;
- }
- #if HOST == UNIX
- cmd = F_SETLK;
- lck.l_type = F_RDLCK;
- #elif HOST == MS_DOS
-
- #endif
- break;
- case B_RDLKW:
- if (!(bp->flags & BIOREAD)) {
- errno = BENOPEN;
- return -1;
- }
- #if HOST == UNIX
- cmd = F_SETLKW;
- lck.l_type = F_RDLCK;
- #elif HOST == MS_DOS
-
- #endif
- break;
- case B_WRLCK:
- if (!(bp->flags & BIOWRITE)) {
- errno = BENOPEN;
- return -1;
- }
- #if HOST == UNIX
- cmd = F_SETLK;
- lck.l_type = F_WRLCK;
- #elif HOST == MS_DOS
-
- #endif
- break;
- case B_WRLKW:
- if (!(bp->flags & BIOWRITE)) {
- errno = BENOPEN;
- return -1;
- }
- #if HOST == UNIX
- cmd = F_SETLKW;
- lck.l_type = F_WRLCK;
- #elif HOST == MS_DOS
-
- #endif
- break;
- case B_UNLCK:
- /* flush buffers */
- if (bflush(bp) == -1) {
- BEPRINT;
- return -1;
- }
- #if HOST == UNIX
- cmd = F_SETLK;
- lck.l_type = F_UNLCK;
- #elif HOST == MS_DOS
-
- #endif
- break;
- default:
- errno = EINVAL;
- return -1;
- break;
- }
-
- /* lock block file */
- #if HOST == UNIX
- if (start == 0) {
- lck.l_whence = 0;
- if (len == 0) {
- lck.l_len = 0;
- } else {
- lck.l_len = bp->hdrsize + (len - 1) * bp->blksize;
- }
- } else {
- lck.l_whence = bp->hdrsize + (start - 1) * bp->blksize;
- if (len == 0) {
- lck.l_len = 0;
- } else {
- lck.l_len = len * bp->blksize;
- }
- }
- lck.l_start = 0;
- lck.l_sysid = 0;
- lck.l_pid = 0;
- if (fcntl(bp->fd.ifd, cmd, &lck) == -1) {
- /* new versions of fcntl will use EAGAIN */
- if (errno == EACCES) errno = EAGAIN;
- if (errno != EAGAIN) BEPRINT;
- return -1;
- }
- #elif HOST == MS_DOS
-
- #endif
- /* if locking, load endblk */
- if (ltype != B_UNLCK) {
- if (b_uendblk(bp, &bp->endblk) == -1) {
- BEPRINT;
- return -1;
- }
- }
-
- errno = 0;
- return 0;
- }