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
This commit is contained in:
Brian Somers 1997-03-31 22:51:00 +00:00
parent 539f83b7f0
commit 687d0cdeb3
9 changed files with 178 additions and 61 deletions

View File

@ -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_ */

View File

@ -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

View File

@ -47,12 +47,14 @@ static const char sccsid[] = "@(#)uucplock.c 8.1 (Berkeley) 6/6/93";
#include <stdio.h>
#include <stdlib.h>
#include <paths.h>
#include <string.h>
#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;
}

View File

@ -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 <sys/param.h>
@ -61,6 +61,7 @@ static char rcsid[] = "$Id: slattach.c,v 1.25 1997/02/22 14:33:19 peter Exp $";
#include <syslog.h>
#include <termios.h>
#include <unistd.h>
#include <libutil.h>
#include <netinet/in.h>
#include <net/if.h>
@ -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 @@ again:
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);

View File

@ -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 <termios.h>
#include <time.h>
#include <unistd.h>
#include <libutil.h>
#include <netinet/in.h>
#include <net/if.h>
@ -289,7 +290,10 @@ restart:
}
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;
}

View File

@ -14,7 +14,6 @@ LIBACU=${.CURDIR}/../libacu/libacu.a
.endif
PROG= tip
CFLAGS+=-DUSE_PERROR
DPADD= $(LIBACU)
LDADD= $(LIBACU) -lutil
LINKS= ${BINDIR}/tip

View File

@ -35,6 +35,7 @@
static char sccsid[] = "@(#)hunt.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#include <libutil.h>
#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

View File

@ -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

View File

@ -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 <sys/tty.h>
#include <errno.h>
#include <time.h>
#include <libutil.h>
#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);