Interlock functions to limit multiple invocations ...
Matt Crawford
matt at oddjob.UChicago.UUCP
Fri Jan 25 07:37:08 AEST 1985
# unpack with sh (or ex -- its short!)
sed 's/.//' >README << '7-8-9 EOF'
@Here are some subroutines which a program can call to limit
@multiple invocations of itself to one per user and/or N total
@invocations. I hope the usage is clear from the comments.
@As an example, I added
@
@ #ifndef NROFF
@ (void)ublock(".tru");
@ (void)nblock(".trn");
@ #endif
@
@To the troff source file n1.c just before the setjmp. (If you use both
@ublock() and nblock(), use them in that order!) Then I created empty
@public-write files called /usr/spool/locks/trn.{1,2,...} to determine
@how many troff's would be allowed to run simultaneously.
@_____________________________________________________
@Matt University crawford at anl-mcs.arpa
@Crawford of Chicago ihnp4!oddjob!matt
7-8-9 EOF
sed 's/.//' >lockout.c << '7-8-9 EOF'
@#include <sys/file.h>
@#include <sys/param.h>
@#include <sys/errno.h>
@
@#define LOCKDIR "/usr/spool/locks/"
@#define INITSLEEPTIME ((unsigned)10)
@#define MAXSLEEPTIME ((unsigned)30)
@
@extern int errno;
@extern char *strcpy(), *strcat(), *sprintf();
@
@/* mkblockf():
@** Make a lock file name for nblock() or ublock().
@** This is not declared static because the user might want to
@** use it to look at the contents of some other lock file.
@*/
@char *
@mkblockf( buf, pref )
@char *buf, *pref;
@{
@ if ( *pref == '/' )
@ *buf = '\0';
@ else
@ (void)strcpy(buf, LOCKDIR);
@ return strcat(strcat(buf, pref), ".");
@}
@
@/* nblock():
@** Block the current process until an existing lock file is
@** opened and an exclusive lock obtained on it. The name of
@** the lock file is given by the concatenation of LOCKDIR
@** (only if prefix does not begin with "/"), the argument
@** string prefix, and a dot followed by a positive integer.
@** PURPOSE:
@** To limit the number of instance of a given program which
@** can be running simultaneously.
@** RETURN VALUE:
@** >= 0 An fd open for writing. The referenced file will
@** have been truncated to zero length.
@** < 0 Errno will be set if the operation cannot be done.
@** The calling process should probably go ahead.
@*/
@nblock( prefix )
@char *prefix;
@{
@ char namebuf[MAXPATHLEN];
@ char *numptr;
@
@ (void)mkblockf(namebuf, prefix);
@ numptr = namebuf + strlen(namebuf);
@ for ( ; ; ) {
@ int sufnum, fd = -1;
@ unsigned sleeptime = INITSLEEPTIME;
@
@ for ( sufnum=1; fd<0; sufnum++ ) {
@ (void)sprintf(numptr, "%d", sufnum);
@ if ( (fd=open(namebuf, O_RDWR, 0666)) < 0 )
@ if ( errno == ENOENT || sufnum == 1 )
@ break;
@ else
@ continue;
@ if ( flock(fd, LOCK_EX|LOCK_NB) )
@ (void)close(fd), fd = -1;
@ errno=0;
@ }
@ if ( fd >= 0 )
@ return fd;
@ if ( errno && sufnum == 1 )
@ return -1;
@ sleep(sleeptime);
@ if ( sleeptime < MAXSLEEPTIME )
@ sleeptime += INITSLEEPTIME;
@ }
@ /* NOTREACHED */
@}
@
@/* ublock():
@** Block the current process until a lock file is opened
@** and an exclusive lock obtained on it. The file will
@** be created if it does not already exist. The name of
@** the lock file is given by the concatenation of LOCKDIR
@** (only if prefix does not begin with "/"), the argument
@** string prefix, and a dot followed by the current ruid.
@** (It would have been the username, but troff has it's
@** own atoi() that was messing up getpwuid().)
@** PURPOSE:
@** To limit users to one instance of a given program
@** running at a time.
@** RETURN VALUE:
@** >= 0 An fd open for writing. The referenced file will
@** have been truncated to zero length.
@** < 0 Errno will be set if the operation cannot be done.
@** The calling process should probably go ahead.
@*/
@ublock( prefix )
@char *prefix;
@{
@ char namebuf[MAXPATHLEN],
@ uidbuf[16];
@ int fd;
@
@ (void)strcat(mkblockf(namebuf, prefix),
@ sprintf(uidbuf, "%d", getuid()));
@ fd = open(namebuf, O_RDWR|O_CREAT, 0644);
@ if ( fd >= 0 ) {
@ do
@ errno = 0;
@ while ( flock(fd, LOCK_EX) && errno == EINTR );
@ if ( errno )
@ (void)close(fd), fd = -1;
@ }
@ return fd;
@}
7-8-9 EOF
exit
More information about the Comp.sources.unix
mailing list