📄 lock.c
字号:
/* PKCIPE - public key based configuration tool for CIPE lock.c - lock and PID file handling Copyright 2000 Olaf Titz <olaf@bigred.inka.de> 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.*//* $Id: lock.c,v 1.6 2003/07/22 19:35:26 olaf81825 Exp $ */#include <fcntl.h>#include <string.h>#include <unistd.h>#include <sys/file.h>#include "pkcipe.h"/* Locking scheme: All locks are in /var/run/cipe (or OPTDIR). The file @@LOCKFILE ("master") is flock()d while the others are processed. For each PEER, PEER.pid holds the PID of a running ciped, managed by ip-up/ip-down. PEER.pkc holds the PID of pkcipe while negotiating. The pkc file is only removed after ciped has started, so there is no gap.*/#ifndef OPTDIR#define OPTDIR "/var/run/cipe/%s"#endif#define PIDDIR OPTDIR ".pid"#define PKCDIR OPTDIR ".pkc"static int writeint(int fd, int n){ char buf[16]; int i=snprintf(buf, sizeof(buf), "%11d\n", n); return xwrite(fd, buf, i);}static char *master=NULL;static char masterfd=-1;int lockMaster(void){ debug((DEB_LOCK, "lockMaster")); if (!master) { if (!(master=dsprintf(OPTDIR, "@@LOCKFILE"))) { Log(LOG_ERR, "lockMaster: malloc failure"); return -1; } } if (masterfd<0) { if ((masterfd=open(master, O_RDWR|O_CREAT, 0600))<0) { Log(LOG_ERR, "lockMaster: open: %m"); return -1; } if (fcntl(masterfd, F_SETFD, FD_CLOEXEC)<0) Log(LOG_ERR, "lockMaster: FD_CLOEXEC: %m"); /* not fatal */ } if (flock(masterfd, LOCK_EX)<0) { Log(LOG_ERR, "lockMaster: flock: %m"); return -1; } return writeint(masterfd, getpid());}int unlockMaster(void){ debug((DEB_LOCK, "unlockMaster")); if (masterfd<0) { Log(LOG_ERR, "unlockMaster: internal not locked"); return -1; } if (flock(masterfd, LOCK_UN)<0) { Log(LOG_ERR, "unlockMaster: flock: %m"); return -1; } (void)close(masterfd); /* (void)unlink(master); no! race! */ masterfd=-1; return 0;}/* these routines are run under master lock which should guarantee it to be free of races */INLINE int handleLock(FILE *f){ int i, pid, e=0; char buf[32]; FILE *p; if (fscanf(f, "%d", &pid)<1) { Log(LOG_NOTICE, "handleLock: pid file garbage"); goto out; } debug((DEB_LOCK, "handleLock: %d", pid)); snprintf(buf, sizeof(buf), "/proc/%d/stat", pid); if (!(p=fopen(buf, "r"))) { Log(LOG_INFO, "handleLock: open %s: %m", buf); goto out; } if (fscanf(p, "%d %31s", &i, buf)<2 || i!=pid) { Log(LOG_ERR, "handleLock: proc/stat garbage?"); fclose(p); goto out; } fclose(p); if (strstr(buf, "pkcipe")) { debug((DEB_LOCK, "handleLock: found pkcipe process %d", pid)); e=pid; goto out; } if (strstr(buf, "ciped")) { Log(LOG_NOTICE, "handleLock: killing process %d %s", pid, buf); kill(pid, SIGTERM); snprintf(buf, sizeof(buf), "/proc/%d/stat", pid); for (i=0; i<10; ++i) { if (access(buf, R_OK)<0) break; debug((DEB_LOCK, "handleLock: waiting...")); sleep(1); } if (i>=10) Log(LOG_WARNING, "handleLock: %d not going away", pid); } else { Log(LOG_NOTICE, "handleLock: lock seems to be stale %s", buf); } out: rewind(f); return e;}static void unlockPeer(void){ char *buf=dsprintf(PKCDIR, peerIdentity); if (!buf) { Log(LOG_ERR, "unlockPeer: malloc failure"); return; } unlink(buf); free(buf);}int lockPeer(void){ FILE *f; int i=0; char *pkc=dsprintf(PKCDIR, peerIdentity); if (!pkc) { Log(LOG_ERR, "lockPeer: malloc failure"); return -1; } debug((DEB_LOCK, "lockPeer")); if (access(pkc, R_OK|W_OK)==0) { /* pkc file exists */ f=fopen(pkc, "r+"); if (f) i=handleLock(f); } else { /* pkc file does not exist, first check pid file */ char *pid=dsprintf(PIDDIR, peerIdentity); if (!pid) { Log(LOG_ERR, "lockPeer: malloc failure"); i=-1; goto out; } f=fopen(pid, "r"); if (f) { i=handleLock(f); fclose(f); } f=fopen(pkc, "w"); free(pid); } if (!f) { Log(LOG_ERR, "lockPeer: fopen: %m"); i=-1; goto out; } fprintf(f, "%d\n", getpid()); fclose(f); out: if (pkc) free(pkc); if (!i) atexit(unlockPeer); return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -