📄 lock.c
字号:
/*
Portserver - Use RTERM protocol to serve serial ports over a network
Copyright (C) 1998 Kenn Humborg
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* These functions are derived from pppd (sys-linux.c) */
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include <unistd.h>
#include "port.h" /* for struct Port */
#ifndef LOCK_PREFIX
#define LOCK_PREFIX "/var/lock/LCK.."
#endif
/* The pppd code doesn't define PID_BINARY, so make
sure it's not defined here as well */
#ifdef PID_BINARY
#undef PID_BINARY
#endif
/*
* LockPort - create a lock file for the named device.
*
* Returns 0 for success, -1 for failure
*/
int LockPort (struct Port *port)
{
char hdb_lock_buffer[12];
int fd, n;
int pid;
char *p;
char *dev;
char *lock_file;
dev = port->device_name;
p = strrchr(dev, '/');
if (p != NULL)
{
dev = ++p;
}
lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
if (lock_file == NULL)
{
port->lock_file = NULL;
return -1;
}
strcpy (lock_file, LOCK_PREFIX);
strcat (lock_file, dev);
/*
* Attempt to create the lock file at this point.
*/
while (1)
{
fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
if (fd >= 0)
{
pid = getpid();
#ifndef PID_BINARY
sprintf (hdb_lock_buffer, "%010d\n", pid);
write (fd, hdb_lock_buffer, 11);
#else
write(fd, &pid, sizeof (pid));
#endif
close(fd);
port->lock_file = lock_file;
return 0;
}
/*
* If the file exists then check to see if the pid is stale
*/
if (errno == EEXIST)
{
fd = open(lock_file, O_RDONLY, 0);
if (fd < 0)
{
if (errno == ENOENT) /* This is just a timing problem. */
{
continue;
}
break;
}
/* Read the lock file to find out who has the device locked */
n = read (fd, hdb_lock_buffer, 11);
close (fd);
if (n < 0)
{
syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
break;
}
/* See the process still exists. */
if (n > 0)
{
#ifndef PID_BINARY
hdb_lock_buffer[n] = '\0';
sscanf (hdb_lock_buffer, " %d", &pid);
#else
pid = ((int *) hdb_lock_buffer)[0];
#endif
if (pid == 0 || (kill(pid, 0) == -1 && errno == ESRCH))
{
n = 0;
}
}
/* If the process does not exist then try to remove the lock */
if (n == 0 && unlink (lock_file) == 0)
{
syslog (LOG_NOTICE, "Removed stale lock on %s (pid %d)",
dev, pid);
continue;
}
syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, pid);
break;
}
syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file);
break;
}
free(lock_file);
port->lock_file = NULL;
return -1;
}
/*
* UnlockPort - remove our lockfile
*/
void UnlockPort(struct Port *port)
{
if (port->lock_file)
{
unlink(port->lock_file);
free(port->lock_file);
port->lock_file = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -