Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!brl-adm!brl-smoke!gwyn From: gwyn@brl-smoke.ARPA (Doug Gwyn ) Newsgroups: comp.unix.wizards Subject: Re: Wanted: lockf system call source Message-ID: <5360@brl-smoke.ARPA> Date: Thu, 13-Nov-86 10:54:19 EST Article-I.D.: brl-smok.5360 Posted: Thu Nov 13 10:54:19 1986 Date-Received: Thu, 13-Nov-86 21:26:40 EST References: <110@dvm.UUCP> Reply-To: gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) Distribution: na Organization: Ballistic Research Lab (BRL), APG, MD. Lines: 110 In article <110@dvm.UUCP> dave@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 #include #include extern int fcntl(); /*ARGSUSED*/ int lockf( fildes, function, size ) int fildes; /* file descriptor */ int function; /* F_* code from */ 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; }