NAME
pidlock,
ttylock,
ttyunlock —
locks based on files
containing PIDs
LIBRARY
System Utilities Library (libutil, -lutil)
SYNOPSIS
#include <util.h>
int
pidlock(
const
char *lockfile,
int
flags,
pid_t *locker,
const char *info);
int
ttylock(
const
char *tty,
int flags,
pid_t *locker);
int
ttyunlock(
const
char *tty);
DESCRIPTION
The
pidlock()
ttylock(), and
ttyunlock() functions attempt to create a lockfile for an
arbitrary resource that only one program may hold at a time. (In the case of
ttylock(), this is access to a tty device.) If the function
succeeds in creating the lockfile, it will succeed for no other program
calling it with the same lockfile until the original calling program has
removed the lockfile or exited. The
ttyunlock() function
will remove the lockfile created by
ttylock().
These functions use the method of creating a lockfile traditionally used by UUCP
software. This is described as follows in the documentation for Taylor UUCP:
The lock file normally contains the
process ID of the locking process. This makes it easy to determine whether a
lock is still valid. The algorithm is to create a temporary file and then link
it to the name that must be locked. If the link fails because a file with that
name already exists, the existing file is read to get the process ID. If the
process still exists, the lock attempt fails. Otherwise the lock file is
deleted and the locking algorithm is retried.
The PID is stored in ASCII format, with leading spaces to pad it out to ten
characters, and a terminating newline. This implementation has been extended
to put the hostname on the second line of the file, terminated with a newline,
and optionally an arbitrary comment on the third line of the file, also
terminated with a newline. If a comment is given, but
PIDLOCK_NONBLOCK
is not, a blank line will be written
as the second line of the file.
The
pidlock() function will attempt to create the file
lockfile and put the current process's pid in it. The
ttylock() function will do the same, but should be passed
only the base name (with no leading directory prefix) of the
tty to be locked; it will test that the tty exists in
/dev and is a character device, and then create the file in
the
/var/spool/lock directory and prefix the filename with
LCK... Use the
ttyunlock() function to
remove this lock.
The following flags may be passed in
flags:
-
-
PIDLOCK_NONBLOCK
- The function should return immediately when a lock is held
by another active process. Otherwise the function will wait (forever, if
necessary) for the lock to be freed.
-
-
PIDLOCK_USEHOSTNAME
- The hostname should be compared against the hostname in the
second line of the file (if present), and if they differ, no attempt at
checking for a living process holding the lock will be made, and the
lockfile will never be deleted. (The process is assumed to be alive.) This
is used for locking on NFS or other remote filesystems. (The function will
never create a lock if
PIDLOCK_USEHOSTNAME
is
specified and no hostname is present.)
If
locker is non-null, it will contain the PID of the locking
process, if there is one, on return.
If
info is non-null and the lock succeeds, the string it
points to will be written as the third line of the lock file.
RETURN VALUES
Zero is returned if the operation was successful; on an error a -1 is returned
and a standard error code is left in the global location
errno.
ERRORS
In addition to the errors that are returned from
stat(2),
open(2),
read(2),
write(2), and
link(2),
pidlock() or
ttylock() can set
errno to the following values on failure:
-
-
- [
EWOULDBLOCK
]
- Another running process has a lock and the
PIDLOCK_NONBLOCK
flag was specified.
-
-
- [
EFTYPE
]
- The tty specified in
ttylock() is not a character special device.
HISTORY
The
pidlock() and
ttylock() functions
appeared in
NetBSD 1.3.
AUTHORS
Curt Sampson ⟨cjs@NetBSD.org⟩.
BUGS
The lockfile format breaks if a pid is longer than ten digits when printed in
decimal form.
The PID returned will be the pid of the locker on the remote machine if
PIDLOCK_USEHOSTNAME
is specified, but there is no
indication that this is not on the local machine.