1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
/* $Id: xiolockfile.c,v 1.1 2005/08/18 19:42:05 gerhard Exp $ */
/* Copyright Gerhard Rieger 2005 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains socats explicit locking mechanisms */
#include "xiosysincludes.h"
#include "compat.h"
#include "mytypes.h"
#include "error.h"
#include "utils.h"
#include "sysutils.h"
#include "sycls.h"
#include "xio.h"
#include "xiolockfile.h"
/* returns 0 if it could create lock; 1 if the lock exists; -1 on error */
int xiogetlock(const char *lockfile) {
char *s;
struct stat strat;
int fd;
pid_t pid;
char pidbuf[3*sizeof(pid_t)+1];
size_t bytes;
if (Lstat(lockfile, &strat) == 0) {
return 1;
}
switch (errno) {
case ENOENT: break;
default:
Error3("Lstat(\"%s\", %p): %s", lockfile, &strat, strerror(errno));
return -1;
}
/* in this moment, the file did not exist */
if ((s = Malloc(strlen(lockfile)+8)) == NULL) {
errno = ENOMEM;
return -1;
}
strcpy(s, lockfile);
strcat(s, ".XXXXXX");
if ((fd = Mkstemp(s)) < 0) {
Error2("mkstemp(\"%s\"): %s", s, strerror(errno));
return -1;
}
pid = Getpid();
bytes = sprintf(pidbuf, F_pid, pid);
Write(fd, pidbuf, bytes);
Close(fd);
/* Chmod(lockfile, 0600); */
if (Link(s, lockfile) < 0) {
int _errno = errno;
Error3("link(\"%s\", \"%s\"): %s", s, lockfile, strerror(errno));
Unlink(s);
errno = _errno;
return -1;
}
Unlink(s);
return 0;
}
int xiounlock(const char *lockfile) {
return Unlink(lockfile);
}
/* returns 0 when it could create lock, or -1 on error */
int xiowaitlock(const char *lockfile, struct timespec *intervall) {
int rc;
int level = E_NOTICE; /* first print a notice */
while ((rc = xiogetlock(lockfile)) == 1) {
Msg1(level, "waiting for lock \"%s\"", lockfile);
level = E_INFO; /* afterwards only make info */
Nanosleep(intervall, NULL);
}
return rc;
}
/* returns 0 when it could obtain lock or the lock is not valid
(lockfile==NULL), 1 if it could not obtain the lock, or -1 on error */
int xiolock(xiolock_t *lock) {
int result;
if (lock->lockfile == NULL) {
return 0;
}
if (lock->waitlock) {
result = xiowaitlock(lock->lockfile, &lock->intervall);
} else {
result = xiogetlock(lock->lockfile);
}
if (result == 0) {
Info1("obtained lock \"%s\"", lock->lockfile);
}
return result;
}
int xiofiledroplock(xiofile_t *xfd) {
if (xfd->tag == XIO_TAG_DUAL) {
xiofiledroplock(xfd->dual.stream[0]);
xiofiledroplock(xfd->dual.stream[1]);
} else {
xfd->stream.havelock = false;
}
return 0;
}
|