summaryrefslogtreecommitdiffstats
path: root/lib/libutil
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1997-03-31 22:51:00 +0000
committerbrian <brian@FreeBSD.org>1997-03-31 22:51:00 +0000
commitcb7f5ad55578fad7245152f0f9b7647830a53a2b (patch)
tree2c78d1ecaf1cdd58a514ff6e9ba36cc4bc7becdf /lib/libutil
parent8871c2899e1277da4a3d19c3cbbc4d2fae060306 (diff)
downloadFreeBSD-src-cb7f5ad55578fad7245152f0f9b7647830a53a2b.zip
FreeBSD-src-cb7f5ad55578fad7245152f0f9b7647830a53a2b.tar.gz
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
Diffstat (limited to 'lib/libutil')
-rw-r--r--lib/libutil/libutil.h10
-rw-r--r--lib/libutil/uucplock.391
-rw-r--r--lib/libutil/uucplock.c92
3 files changed, 145 insertions, 48 deletions
diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h
index 695a8cb..35c1163 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 a8b5df8..0c1ae7e 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,
-.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,
+If
.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 20eafe4..0f08646 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 <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;
}
OpenPOWER on IntegriCloud