From 10839f021938ebb1f41764e4c36e87b88dae4320 Mon Sep 17 00:00:00 2001 From: brian Date: Sun, 30 Mar 1997 12:12:20 +0000 Subject: Move uucplock into libutil and create a manual page. --- lib/libutil/Makefile | 6 +- lib/libutil/libutil.h | 4 +- lib/libutil/uucplock.3 | 108 +++++++++++++++++++++++++++++++++ lib/libutil/uucplock.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 lib/libutil/uucplock.3 create mode 100644 lib/libutil/uucplock.c (limited to 'lib/libutil') diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile index 1f05dfd..2207317 100644 --- a/lib/libutil/Makefile +++ b/lib/libutil/Makefile @@ -5,9 +5,10 @@ SHLIB_MAJOR= 2 SHLIB_MINOR= 2 CFLAGS+=-Wall -DLIBC_SCCS -I${.CURDIR} -I/sys SRCS= login.c login_tty.c logout.c logwtmp.c pty.c setproctitle.c \ - login_cap.c login_class.c login_auth.c login_times.c login_ok.c + login_cap.c login_class.c login_auth.c login_times.c login_ok.c \ + uucplock.c MAN3+= login.3 login_tty.3 logout.3 logwtmp.3 pty.3 setproctitle.3 \ - login_cap.3 login_class.3 login_times.3 login_ok.3 + login_cap.3 login_class.3 login_times.3 login_ok.3 uucplock.3 MAN5+= login.conf.5 MLINKS+= pty.3 openpty.3 pty.3 forkpty.3 MLINKS+=login_cap.3 login_getclassbyname.3 login_cap.3 login_close.3 \ @@ -23,6 +24,7 @@ MLINKS+=login_times.3 parse_lt.3 login_times.3 in_ltm.3 \ login_times.3 in_lts.3 MLINKS+=login_ok.3 auth_ttyok.3 login_ok.3 auth_hostok.3 \ login_ok.3 auth_timeok.3 +MLINKS+=uucplock.3 uu_lock.3 uucplock.3 uu_unlock.3 beforeinstall: ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/libutil.h \ diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index bcaf0d9..695a8cb 100644 --- a/lib/libutil/libutil.h +++ b/lib/libutil/libutil.h @@ -18,7 +18,7 @@ * 5. Modifications may be freely made to this file providing the above * conditions are met. * - * $Id$ + * $Id: libutil.h,v 1.4 1997/02/22 15:08:14 peter Exp $ */ #ifndef _LIBUTIL_H_ @@ -41,6 +41,8 @@ int openpty __P((int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp)); int forkpty __P((int *amaster, char *name, struct termios *termp, struct winsize *winp)); +int uu_lock __P((char *ttyname)); +int uu_unlock __P((char *ttyname)); __END_DECLS #endif /* !_LIBUTIL_H_ */ diff --git a/lib/libutil/uucplock.3 b/lib/libutil/uucplock.3 new file mode 100644 index 0000000..a8b5df8 --- /dev/null +++ b/lib/libutil/uucplock.3 @@ -0,0 +1,108 @@ +.\" +.\" Copyright (c) 1996 Brian Somers +.\" +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id$ +.\" " +.Dd March 30, 1997 +.Os +.Dt uucplock 3 +.Sh NAME +.Nm uu_lock , +.Nm uu_unlock +.Nd acquire and release control of a serial device +.Sh SYNOPSIS +.Fd #include +.Ft int +.Fn uu_lock "char *ttyname" +.Ft int +.Fn uu_unlock "char *ttyname" +.Pp +Link with +.Va -lutil +on the +.Xr cc 1 +command line. +.Sh DESCRIPTION +The +.Fn uu_lock +function attempts to create a lock file called +.Dq /var/spool/lock/LCK.. +with a suffix given by the passed +.Fa ttyname . +If the file already exists, it is expected to contain the process +id of the locking program. +.Pp +If the file does not already exist, or the owning process given by +the process id found in the lock file is no longer running, +.Fn uu_lock +will write its own process id into the file and return success. +.Pp +.Fn uu_unlock +removes the lockfile created by +.Fn uu_lock +for the given +.Fa ttyname . +Care should be taken that +.Fn uu_lock +was successful before calling +.Fn uu_unlock . +.Sh RETURN VALUES +Both +.Fn uu_lock +and +.Fn uu_unlock +return 0 on success and -1 on failure. +.Sh ERRORS +On failure, +.Fn uu_lock +will log any unexpected errors using +.Xr syslog 2 . +If the lock already exists and contains the process id of a running +process, +.Fn uu_lock +will silently fail. The value of +.Dv errno +can not be used to determine the cause of failure. +.Pp +.Fn uu_unlock +will set the global variable +.Dv errno +to reflect the reason that the lock file could not be removed. +Refer to the description of +.Xr unlink 2 +for further details. +.Sh BUGS +Locking is not atomic. Should a race condition occur, it's entirely +possible that both processes obtain the lock. +.Pp +It is possible that a stale lock is not recognised as such if a new +processes is assigned the same processes id as the program that left +the stale lock. +.Pp +The calling process must have write permissions to the +.Dq /var/spool/lock +directory. There is no mechanism in place to ensure that the +permissions of this directory are the same as those of the +serial devices that might be locked. diff --git a/lib/libutil/uucplock.c b/lib/libutil/uucplock.c new file mode 100644 index 0000000..20eafe4 --- /dev/null +++ b/lib/libutil/uucplock.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char sccsid[] = "@(#)uucplock.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#ifndef USE_PERROR +#include +#endif +#include +#include +#include +#include +#include + +#define LOCKFMT "LCK..%s" + +/* Forward declarations */ +static int put_pid (int fd, pid_t pid); +static pid_t get_pid (int fd); + +/* + * uucp style locking routines + * return: 0 - success + * -1 - failure + */ + +int uu_lock (char *ttyname) +{ + int fd; + pid_t pid; + char tbuf[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN]; + + (void)sprintf(tbuf, _PATH_UUCPLOCK LOCKFMT, ttyname); + fd = open(tbuf, O_RDWR|O_CREAT|O_EXCL, 0660); + if (fd < 0) { + /* + * file is already locked + * check to see if the process holding the lock still exists + */ + fd = open(tbuf, O_RDWR, 0); + if (fd < 0) { +#ifndef USE_PERROR + syslog(LOG_ERR, "lock open: %m"); +#else + perror("lock open"); +#endif + return(-1); + } + if ((pid = get_pid (fd)) == -1) { +#ifndef USE_PERROR + syslog(LOG_ERR, "lock read: %m"); +#else + perror("lock read"); +#endif + (void)close(fd); + return(-1); + } + + if (kill(pid, 0) == 0 || errno != ESRCH) { + (void)close(fd); /* process is still running */ + return(-1); + } + /* + * The process that locked the file isn't running, so + * we'll lock it ourselves + */ + if (lseek(fd, (off_t) 0, L_SET) < 0) { +#ifndef USE_PERROR + syslog(LOG_ERR, "lock lseek: %m"); +#else + perror("lock lseek"); +#endif + (void)close(fd); + return(-1); + } + /* fall out and finish the locking process */ + } + pid = getpid(); + if (!put_pid (fd, pid)) { +#ifndef USE_PERROR + syslog(LOG_ERR, "lock write: %m"); +#else + perror("lock write"); +#endif + (void)close(fd); + (void)unlink(tbuf); + return(-1); + } + (void)close(fd); + return(0); +} + +int uu_unlock (char *ttyname) +{ + char tbuf[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN]; + + (void)sprintf(tbuf, _PATH_UUCPLOCK LOCKFMT, ttyname); + return(unlink(tbuf)); +} + +static int put_pid (int fd, pid_t pid) +{ + char buf[32]; + int len; + + len = sprintf (buf, "%10d\n", pid); + return write (fd, buf, len) == len; +} + +static pid_t get_pid (int fd) +{ + int bytes_read; + char buf[32]; + pid_t pid; + + bytes_read = read (fd, buf, sizeof (buf) - 1); + if (bytes_read > 0) { + buf[bytes_read] = '\0'; + pid = strtol (buf, (char **) NULL, 10); + } else + pid = -1; + return pid; +} + +/* end of uucplock.c */ -- cgit v1.1