From cb7f5ad55578fad7245152f0f9b7647830a53a2b Mon Sep 17 00:00:00 2001 From: brian Date: Mon, 31 Mar 1997 22:51:00 +0000 Subject: [PATCH] Remove the syslog stuff, and allow various return values in uu_lock(). Add uu_lockerr() for turning the results of uu_lock into something printable. Remove bogus section in man page about race conditions allowing both processes to get the lock. Include libutil.h and use uu_lock() correctly where it should. Suggested by: ache@freebsd.org --- lib/libutil/libutil.h | 10 ++++- lib/libutil/uucplock.3 | 91 +++++++++++++++++++++++++++++++------ lib/libutil/uucplock.c | 92 ++++++++++++++++++++++++-------------- sbin/slattach/slattach.c | 13 ++++-- sbin/startslip/startslip.c | 8 +++- usr.bin/tip/tip/Makefile | 1 - usr.bin/tip/tip/hunt.c | 7 ++- usr.sbin/ppp/Makefile | 4 +- usr.sbin/ppp/modem.c | 13 ++++-- 9 files changed, 178 insertions(+), 61 deletions(-) diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index 695a8cbc3f68..35c1163ed766 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: libutil.h,v 1.4 1997/02/22 15:08:14 peter Exp $ + * $Id: libutil.h,v 1.5 1997/03/30 12:11:27 brian Exp $ */ #ifndef _LIBUTIL_H_ @@ -41,8 +41,16 @@ 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)); +char *uu_lockerr __P((int uu_lockresult)); int uu_lock __P((char *ttyname)); int uu_unlock __P((char *ttyname)); __END_DECLS +#define UU_LOCK_INUSE (1) +#define UU_LOCK_OK (0) +#define UU_LOCK_OPEN_ERR (-1) +#define UU_LOCK_READ_ERR (-2) +#define UU_LOCK_SEEK_ERR (-3) +#define UU_LOCK_WRITE_ERR (-4) + #endif /* !_LIBUTIL_H_ */ diff --git a/lib/libutil/uucplock.3 b/lib/libutil/uucplock.3 index a8b5df8e0310..0c1ae7e498fc 100644 --- a/lib/libutil/uucplock.3 +++ b/lib/libutil/uucplock.3 @@ -23,7 +23,7 @@ .\" (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$ +.\" $Id: uucplock.3,v 1.1 1997/03/30 12:11:29 brian Exp $ .\" " .Dd March 30, 1997 .Os @@ -38,6 +38,8 @@ .Fn uu_lock "char *ttyname" .Ft int .Fn uu_unlock "char *ttyname" +.Ft char * +.Fn uu_lockerr "int uu_lockresult" .Pp Link with .Va -lutil @@ -68,23 +70,70 @@ Care should be taken that .Fn uu_lock was successful before calling .Fn uu_unlock . +.Pp +.Fn uu_lockerr +returns an error string representing the error +.Fa uu_lockresult , +as returned from +.Fn uu_lock . .Sh RETURN VALUES -Both +.Fn uu_unlock +returns 0 on success and -1 on failure. +.Pp +.Fn uu_lock +may return any of the following values: +.Pp +.Dv UU_LOCK_INUSE: +The lock is in use by another process. +.Pp +.Dv UU_LOCK_OK: +The lock was successfully created. +.Pp +.Dv UU_LOCK_OPEN_ERR: +The lock file could not be opened via +.Xr open 2 . +.Pp +.Dv UU_LOCK_READ_ERR: +The lock file could not be read via +.Xr read 2 . +.Pp +.Dv UU_LOCK_SEEK_ERR: +The lock file was +.Dq stale , +but the call to +.Xr lseek 2 +necessary to write the current process id failed. +.Pp +.Dv UU_LOCK_WRITE_ERR: +The current process id could not be written to the lock file via a call to +.Xr write 2 . +.Pp +If a value of +.Dv UU_LOCK_OK +is passed to +.Fn uu_lockerr , +a +.Dv NULL +pointer is returned. If a value of +.Dv UU_LOCK_INUSE +is passed, an empty string is returned. Otherwise, a string specifying +the reason for failure is returned. +.Fn uu_lockerr +uses the current value of +.Dv errno +to determine the exact error. Care should be made not to allow +.Dv errno +to be changed between calls to .Fn uu_lock and -.Fn uu_unlock -return 0 on success and -1 on failure. +.Fn uu_lockerr . .Sh ERRORS -On failure, +If .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 +returns one of the four error values above, the global value .Dv errno -can not be used to determine the cause of failure. +can be used to determine the cause. Refer to the respective manual pages +for further details. .Pp .Fn uu_unlock will set the global variable @@ -93,9 +142,23 @@ to reflect the reason that the lock file could not be removed. Refer to the description of .Xr unlink 2 for further details. +.Sh SEE ALSO +.Xr open 2 , +.Xr read 2 , +.Xr lseek 2 , +.Xr write 2 .Sh BUGS -Locking is not atomic. Should a race condition occur, it's entirely -possible that both processes obtain the lock. +Locking is not atomic. Should a race condition occur, it's +possible that the +.Dq losing +process fails to identify the +.Dq winning +process. If this happens, +.Fn uu_lock +returns +.Dv UU_LOCK_READ_ERR +and errno is set to +.Dv EINVAL . .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 diff --git a/lib/libutil/uucplock.c b/lib/libutil/uucplock.c index 20eafe487dc3..0f08646c65d3 100644 --- a/lib/libutil/uucplock.c +++ b/lib/libutil/uucplock.c @@ -47,12 +47,14 @@ static const char sccsid[] = "@(#)uucplock.c 8.1 (Berkeley) 6/6/93"; #include #include #include +#include +#include "libutil.h" #define LOCKFMT "LCK..%s" /* Forward declarations */ static int put_pid (int fd, pid_t pid); -static pid_t get_pid (int fd); +static pid_t get_pid (int fd,int *err); /* * uucp style locking routines @@ -65,6 +67,7 @@ int uu_lock (char *ttyname) int fd; pid_t pid; char tbuf[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN]; + int err; (void)sprintf(tbuf, _PATH_UUCPLOCK LOCKFMT, ttyname); fd = open(tbuf, O_RDWR|O_CREAT|O_EXCL, 0660); @@ -74,56 +77,41 @@ int uu_lock (char *ttyname) * 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 + if (fd < 0) + return UU_LOCK_OPEN_ERR; + + if ((pid = get_pid (fd, &err)) == -1) { (void)close(fd); - return(-1); + errno = err; + return UU_LOCK_READ_ERR; } if (kill(pid, 0) == 0 || errno != ESRCH) { (void)close(fd); /* process is still running */ - return(-1); + return UU_LOCK_INUSE; } /* * 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 + err = errno; (void)close(fd); - return(-1); + errno = err; + return UU_LOCK_SEEK_ERR; } /* 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 + err = errno; (void)close(fd); (void)unlink(tbuf); - return(-1); + errno = err; + return UU_LOCK_WRITE_ERR; } (void)close(fd); - return(0); + return UU_LOCK_OK; } int uu_unlock (char *ttyname) @@ -131,7 +119,43 @@ int uu_unlock (char *ttyname) char tbuf[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN]; (void)sprintf(tbuf, _PATH_UUCPLOCK LOCKFMT, ttyname); - return(unlink(tbuf)); + return unlink(tbuf); +} + +char *uu_lockerr (int uu_lockresult) +{ + static char errbuf[512]; + int len; + + switch (uu_lockresult) { + case UU_LOCK_INUSE: + return ""; + case UU_LOCK_OK: + return 0; + case UU_LOCK_OPEN_ERR: + strcpy(errbuf,"open error: "); + len = 12; + break; + case UU_LOCK_READ_ERR: + strcpy(errbuf,"read error: "); + len = 12; + break; + case UU_LOCK_SEEK_ERR: + strcpy(errbuf,"seek error: "); + len = 12; + break; + case UU_LOCK_WRITE_ERR: + strcpy(errbuf,"write error: "); + len = 13; + break; + default: + strcpy(errbuf,"Undefined error: "); + len = 17; + break; + } + + strncpy(errbuf+len,strerror(errno),sizeof(errbuf)-len-1); + return errbuf; } static int put_pid (int fd, pid_t pid) @@ -143,7 +167,7 @@ static int put_pid (int fd, pid_t pid) return write (fd, buf, len) == len; } -static pid_t get_pid (int fd) +static pid_t get_pid (int fd,int *err) { int bytes_read; char buf[32]; @@ -153,8 +177,10 @@ static pid_t get_pid (int fd) if (bytes_read > 0) { buf[bytes_read] = '\0'; pid = strtol (buf, (char **) NULL, 10); - } else + } else { pid = -1; + *err = bytes_read ? errno : EINVAL; + } return pid; } diff --git a/sbin/slattach/slattach.c b/sbin/slattach/slattach.c index ab38ffb75a96..506cad6cacae 100644 --- a/sbin/slattach/slattach.c +++ b/sbin/slattach/slattach.c @@ -42,7 +42,7 @@ static char copyright[] = #ifndef lint /*static char sccsid[] = "from: @(#)slattach.c 4.6 (Berkeley) 6/1/90";*/ -static char rcsid[] = "$Id: slattach.c,v 1.25 1997/02/22 14:33:19 peter Exp $"; +static char rcsid[] = "$Id: slattach.c,v 1.26 1997/03/29 03:33:07 imp Exp $"; #endif /* not lint */ #include @@ -61,6 +61,7 @@ static char rcsid[] = "$Id: slattach.c,v 1.25 1997/02/22 14:33:19 peter Exp $"; #include #include #include +#include #include #include @@ -294,7 +295,10 @@ void acquire_line() if (uucp_lock) { /* unlock not needed here, always re-lock with new pid */ - if (uu_lock(dvname)) { + int res; + if ((res = uu_lock(dvname)) != UU_LOCK_OK) { + if (res != UU_LOCK_INUSE) + syslog(LOG_ERR, "uu_lock: %s", uu_lockerr(res)); syslog(LOG_ERR, "can't lock %s", dev); exit_handler(1); } @@ -474,7 +478,10 @@ void sighup_handler() if (system(redial_cmd)) goto again; if (uucp_lock) { - if (uu_lock(dvname)) { + int res; + if ((res = uu_lock(dvname)) != UU_LOCK_OK) { + if (res != UU_LOCK_INUSE) + syslog(LOG_ERR, "uu_lock: %s", uu_lockerr(res)); syslog(LOG_ERR, "can't relock %s after %s, aborting", dev, redial_cmd); exit_handler(1); diff --git a/sbin/startslip/startslip.c b/sbin/startslip/startslip.c index 90d928c39ac5..60d97e029c62 100644 --- a/sbin/startslip/startslip.c +++ b/sbin/startslip/startslip.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: startslip.c,v 1.22 1997/02/22 14:33:20 peter Exp $ + * $Id: startslip.c,v 1.23 1997/03/29 03:33:08 imp Exp $ */ #ifndef lint @@ -60,6 +60,7 @@ static char sccsid[] = "@(#)startslip.c 8.1 (Berkeley) 6/5/93"; #include #include #include +#include #include #include @@ -289,7 +290,10 @@ main(argc, argv) } printd("open"); if (uucp_lock) { - if (uu_lock(dvname)) { + int res; + if ((res = uu_lock(dvname)) != UU_LOCK_OK) { + if (res != UU_LOCK_INUSE) + syslog(LOG_ERR, "uu_lock: %s", uu_lockerr(res)); syslog(LOG_ERR, "%s: can't lock %s", username, devicename); goto restart; } diff --git a/usr.bin/tip/tip/Makefile b/usr.bin/tip/tip/Makefile index 073a0e497c25..ec9aee18ae68 100644 --- a/usr.bin/tip/tip/Makefile +++ b/usr.bin/tip/tip/Makefile @@ -14,7 +14,6 @@ LIBACU=${.CURDIR}/../libacu/libacu.a .endif PROG= tip -CFLAGS+=-DUSE_PERROR DPADD= $(LIBACU) LDADD= $(LIBACU) -lutil LINKS= ${BINDIR}/tip diff --git a/usr.bin/tip/tip/hunt.c b/usr.bin/tip/tip/hunt.c index 97e3a6aa2655..e99e73ba16c7 100644 --- a/usr.bin/tip/tip/hunt.c +++ b/usr.bin/tip/tip/hunt.c @@ -35,6 +35,7 @@ static char sccsid[] = "@(#)hunt.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ +#include #include "tipconf.h" #include "tip.h" @@ -56,13 +57,17 @@ hunt(name) { register char *cp; sig_t f; + int res; f = signal(SIGALRM, dead); while (cp = getremote(name)) { deadfl = 0; uucplock = rindex(cp, '/')+1; - if (uu_lock(uucplock) < 0) + if ((res = uu_lock(uucplock)) != UU_LOCK_OK) { + if (res != UU_LOCK_INUSE) + fprintf(stderr, "uu_lock: %s\n", uu_lockerr(res)); continue; + } /* * Straight through call units, such as the BIZCOMP, * VADIC and the DF, must indicate they're hardwired in diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile index d28e5436fc90..4a2e2baf3ef9 100644 --- a/usr.sbin/ppp/Makefile +++ b/usr.sbin/ppp/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.16 1997/03/13 12:45:26 brian Exp $ +# $Id: Makefile,v 1.17 1997/03/30 12:12:20 brian Exp $ PROG= ppp SRCS= async.c auth.c ccp.c chap.c chat.c command.c filter.c fsm.c hdlc.c \ @@ -7,7 +7,7 @@ SRCS= async.c auth.c ccp.c chap.c chat.c command.c filter.c fsm.c hdlc.c \ vjcomp.c arp.c alias.c alias_db.c alias_ftp.c alias_util.c \ passwdauth.c sig.c #CFLAGS+= -DHAVE_SHELL_CMD_WITH_ANY_MODE -CFLAGS += -Wall -DUSE_PERROR -DMSEXT -DPASSWDAUTH +CFLAGS += -Wall -DMSEXT -DPASSWDAUTH LDADD += -lmd -lcrypt -lutil DPADD += ${LIBMD} ${LIBCRYPT} ${LIBUTIL} MAN8= ppp.8 diff --git a/usr.sbin/ppp/modem.c b/usr.sbin/ppp/modem.c index e791776f67df..074276a447c5 100644 --- a/usr.sbin/ppp/modem.c +++ b/usr.sbin/ppp/modem.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: modem.c,v 1.30 1997/03/10 06:21:02 ache Exp $ + * $Id: modem.c,v 1.31 1997/03/10 06:54:58 ache Exp $ * * TODO: */ @@ -28,6 +28,7 @@ #include #include #include +#include #include "hdlc.h" #include "lcp.h" #include "ip.h" @@ -48,7 +49,6 @@ static int connect_count; static struct pppTimer ModemTimer; static char uucplock[10]; -extern int uu_lock(), uu_unlock(); extern void PacketMode(), TtyTermMode(), TtyCommandMode(); extern int TermMode; @@ -377,6 +377,7 @@ int mode; struct termios rstio; int oldflag; char *host, *cp, *port; + int res; mbits = 0; if (mode & MODE_DIRECT) { @@ -392,8 +393,12 @@ int mode; if (strncmp(VarDevice, "/dev", 4) == 0) { strncpy(uucplock, rindex(VarDevice, '/')+1,sizeof(uucplock)-1); uucplock[sizeof(uucplock)-1] = '\0'; - if (uu_lock(uucplock) < 0) { - LogPrintf(LOG_PHASE_BIT, "Modem %s is in use\n", VarDevice); + if ((res = uu_lock(uucplock)) != UU_LOCK_OK) { + if (res == UU_LOCK_INUSE) + LogPrintf(LOG_PHASE_BIT, "Modem %s is in use\n", VarDevice); + else + LogPrintf(LOG_PHASE_BIT, "Modem %s is in use: uu_lock: %s\n", + VarDevice, uu_lockerr(res)); return(-1); } modem = open(VarDevice, O_RDWR|O_NONBLOCK);