home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume26
/
modempool
/
part01
/
lock.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-05
|
5KB
|
242 lines
/*******************************************************************
*
* Module: @(#)lock.c 4.2 92/04/16
*
* Description:
* Handle various lockfile functions.
*
* Revision:
* Date By Reason
* ---- -- ------
* 920306 Lars Berntzon Created
*
*******************************************************************/
static char SccsId[] = "@(#)lock.c 4.2 92/04/16";
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <stdarg.h>
#include "modempool.h"
/*******************************************************************
* L O C K _ L I N E
* -----------------
*
* Description:
* Lock a tty-port the old UNIX way.
*
* Arguments:
* line - Name of tty device.
*
*******************************************************************/
int
lock_line(char *line, int pid)
{
char fname[NAME_SIZE];
char id[NAME_SIZE];
int fd;
sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
/*
* Check that lockdirectory is writeable.
*/
if (access(LOCKDIR, O_WRONLY) != 0) {
logerr("lock_line: lock directory not writeable");
return E_FAIL;
}
/*
* First try to create own lockfile.
*/
while(1)
{
if ((fd = open(fname, O_RDWR | O_CREAT | O_EXCL, 0666)) >= 0)
{
/* Succeded, break out of retry loop */
break;
}
else
{
/*
* File allready existed, try to open it without creation.
*/
if ((fd = open(fname, O_RDONLY)) < 0) {
logerr("lock_line: can't read file '%s'", fname);
return E_LOCK;
}
id[0] = 0;
if (read(fd, id, sizeof id) < 0)
{
close(fd);
debug("lock_line: failed to read");
return E_READ;
}
close(fd);
/*
* If I own the lock, it's all right.
*/
if (atoi(id) == pid) {
debug("lock_line: i allready owned the lock");
break;
}
/*
* Process owning lock does exists so i can't use the line.
*/
if (kill(atoi(id), 0) >= 0)
{
debug("lock_line: process exists");
return E_PROC_EXIST;
}
if (unlink(fname) < 0)
{
debug("lock_line: failed to unlink");
return E_UNLINK;
}
}
}
/*
* Here our own lock file has been created.
*/
lseek(fd, 0, 0);
sprintf(id, "%10d\n", pid);
write(fd, id, strlen(id));
close(fd);
debug("lock_line: ok");
return E_OK;
}
/*******************************************************************
* R E L O C K _ L I N E
* ---------------------
*
* Description:
* Relock the line
*
* Arguments:
* line - Name of tty device.
*
*******************************************************************/
int
relock_line(char *line)
{
char fname[NAME_SIZE];
char id[NAME_SIZE];
int fd;
sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
/* Open lockfile */
if ((fd = open(fname, O_WRONLY | O_TRUNC)) < 0) return E_OPEN;
/* Write pid to lockfile */
sprintf(id, "%10d\n", getpid());
if (write(fd, id, strlen(id)) < 0) {
return E_WRITE;
}
close(fd);
return E_OK;
}
/*******************************************************************
* U N L O C K _ L I N E
* ---------------------
*
* Description:
* Unlock line.
*
* Arguments:
* line - Name of tty device.
*
*******************************************************************/
int
unlock_line(char *line)
{
char fname[NAME_SIZE];
sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
unlink(fname);
return E_OK;
}
/*******************************************************************
* L O C K _ W A I T
* -----------------
*
* Description:
* Wait until lock goes away.
*
*******************************************************************/
int
lock_wait(char *line)
{
int fd = -1;
char fname[NAME_SIZE], id[NAME_SIZE];
if (line == NULL) {
logerr("lock_wait: programming error: line = NULL");
return E_FAIL;
}
sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
/*
* This one never times out when line is locked.
*/
while(1)
{
/*
* Check if lockfile exists.
*/
if (access(fname, F_OK) != 0) {
return E_OK;
}
/*
* Open lockfile.
*/
if ((fd = open(fname, O_RDONLY)) < 0) {
fatal("lockfile not readable");
}
id[0] = 0;
if (read(fd, id, sizeof id) < 0) {
logerr("lock_wait: failed to read lockfile");
close(fd);
return E_FAIL;
}
/*
* If I hold the lock, remove it and return.
*/
if (atoi(id) == getpid()) {
debug("lock_wait: i owned the lock");
unlock_line(line);
close(fd);
return E_OK;
}
/*
* If no owner of lock, remove it and return.
*/
if (kill(atoi(id), 0) != 0) {
debug("lock_wait: no owner of lock");
unlock_line(line);
close(fd);
return E_OK;
}
close(fd);
sleep(5);
}
}