[comp.unix.wizards] Wanted: lockf system call source

dave@dvm.UUCP (David Brand) (11/12/86)

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.

If anyone knows of a version that has support for shared locks, that would be
even better.
-- 

					- Dave

...{decvax,ihnp4,ucbvax}!allegra!phri!orville!dvm!dave

gwyn@brl-smoke.ARPA (Doug Gwyn ) (11/13/86)

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	<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;
	}

davel@hpisoa1.HP.COM (Dave Lennert) (11/24/86)

One interesting thing I noticed about implementing lockf() on top of SysV
fcntl() file locking is that (it appears) fcntl() requires that the file
be opened with write permission even for read locking.  Lockf() does not
require this.

I'm I correctly stating the situation?  If so, is this regarded as a 
deficiency in SysV's lockf()?

    Dave Lennert                ucbvax!hpda!davel               [UUCP]
    Hewlett-Packard - 47UX      ihnp4!hplabs!hpda!davel         [UUCP]
    19447 Pruneridge Ave.       
    Cupertino, CA  95014        (408) 447-6325                  [AT&T]

gwyn@brl-smoke.ARPA (Doug Gwyn ) (11/28/86)

In article <2200003@hpisoa1.HP.COM> davel@hpisoa1.HP.COM (Dave Lennert) writes:
>One interesting thing I noticed about implementing lockf() on top of SysV
>fcntl() file locking is that (it appears) fcntl() requires that the file
>be opened with write permission even for read locking.  Lockf() does not
>require this.
>I'm I correctly stating the situation?  If so, is this regarded as a 
>deficiency in SysV's lockf()?

Dave, our Goulds have System V fcntl() record locking and they require
(only) read permission to set a read lock, write permission to set a
write lock.  I think it's pretty clear that requiring write permission
for a read lock is poor design, whether intentional or not, and should
be fixed in H-P's fcntl() implementation.  Note also that the SVID
(Issue 2) states "The file-descriptor on which a read-lock is being
placed must have been opened with read-access" and "The file-descriptor
on which a write-lock is being placed must have been opened with write-
access", the implication being that such access is also sufficient.

davel@hpisoa1.HP.COM (Dave Lennert) (12/03/86)

Ooops...  What I meant to say was:

One interesting thing I noticed about implementing lockf() on top of SysV
fcntl() file locking is that (it appears) lockf() requires that the file
                                          ^^^^^
be opened with write permission even for read locking.  /usr/group lockf() 
                                                        ^^^^^^^^^^
does not require this.

I'm I correctly stating the situation?  If so, is this regarded as a 
deficiency in SysV's lockf()?

    Dave Lennert                ucbvax!hpda!davel               [UUCP]
    Hewlett-Packard - 47UX      ihnp4!hplabs!hpda!davel         [UUCP]
    19447 Pruneridge Ave.       
    Cupertino, CA  95014        (408) 447-6325                  [AT&T]