Wanted: lockf system call source
Doug Gwyn
gwyn at brl-smoke.ARPA
Fri Nov 14 01:54:19 AEST 1986
In article <110 at dvm.UUCP> dave at dvm.UUCP (David Brand) writes:
>I am looking for a copy of the source to a /usr/group compatible implementation
>of the lockf system call. Is this available in the public domain? If so, do I
>need a Unix source license to look at it? I am interested in the table
>handling and deadlock detection code itself, not just the list of kernel
>modifications presented in the Bass article.
Code for the mods to 7th Edition UNIX is given in the "Reader's Guide
to the 1984 /usr/group Standard". It includes the deadlock detector
etc. I don't promise that it's bug-free. This document does not
require any source license. I assume /usr/group will sell you a copy.
Of course, UNIX System V has a more general record locking facility
accessible via fcntl(). You definitely need a source license for it.
If you're going to implement record locking, I recommend modeling it
after the System V facility, with lockf() just a library routine that
invokes the fcntl()s:
/*
lockf -- system call emulation for 4.2BSD
last edit: 21-Sep-1986 D A Gwyn
See fcntl.c source for NOTES about the quality of emulation.
*/
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
extern int fcntl();
/*ARGSUSED*/
int
lockf( fildes, function, size )
int fildes; /* file descriptor */
int function; /* F_* code from <unistd.h> */
long size; /* extent to be locked */
{
struct flock fl; /* data for fcntl() */
fl.l_whence = SEEK_CUR;
if ( size < 0L )
{ /* this section thanks to Gould */
fl.l_start = size;
fl.l_len = -size;
}
else {
fl.l_start = 0L;
fl.l_len = size;
}
switch ( function )
{
case F_ULOCK: /* unlock region */
fl.l_type = F_UNLCK;
if ( fcntl( fildes, F_SETLK, (int)&fl ) == 0 )
return 0;
break; /* EBADF | EINVAL */
case F_LOCK: /* lock region */
fl.l_type = F_WRLCK;
if ( fcntl( fildes, F_SETLKW, (int)&fl ) == 0 )
return 0;
break; /* EBADF | EINVAL */
case F_TLOCK: /* test & lock region */
fl.l_type = F_WRLCK;
if ( fcntl( fildes, F_SETLK, (int)&fl ) == 0 )
return 0;
break; /* EBADF | EINVAL | EAGAIN */
case F_TEST: /* test for lock */
fl.l_type = F_RDLCK; /* avoid spurious locking */
/* (really should be F_WRLCK) */
if ( fcntl( fildes, F_GETLK, (int)&fl ) == 0 )
if ( fl.l_type == F_UNLCK )
return 0; /* no lock */
else {
errno = EAGAIN; /* EACCES in UNIX System V */
return -1; /* lock exists */
}
break; /* EBADF | EINVAL */
default:
errno = EINVAL; /* (spec fails to mention this) */
return -1;
}
/* error return: */
/* deadlock error is given if we run out of resources,
in compliance with /usr/group standards (thanks to Gould) */
if ( errno == EMFILE || errno == ENOSPC || errno == ENOLCK )
errno = EDEADLK;
return -1;
}
More information about the Comp.unix.wizards
mailing list