Try another fix for wvlinkerhack and static libraries.
[wvstreams.git] / streams / wvlockdev.cc
blobf9b86dd3f3fd9c22d2675eaa8976288de203a329
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * Some handy functions to create/remove /var/lock lockfiles.
6 */
7 #include "wvlockdev.h"
8 #include "wvfile.h"
9 #include "strutils.h"
10 #include <signal.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <fcntl.h>
14 #include <sys/stat.h>
15 #include <errno.h>
17 WvLockDev::WvLockDev(WvString _devicename)
18 : devicename(_devicename)
20 const char *p = strrchr(devicename, '/');
21 if (p)
22 p++;
23 else
24 p = devicename;
26 lock_count = 0;
27 filename = WvString("/var/lock/LCK..%s", p);
31 WvLockDev::~WvLockDev()
33 if (lock_count)
35 lock_count = 1;
36 unlock();
41 #if USE_LOCKDEV /* use the liblockdev.a locking routines */
43 #include <lockdev.h>
45 bool WvLockDev::lock()
47 if (lock_count)
49 lock_count++;
50 return true;
53 if (dev_lock(devicename))
54 return false;
56 lock_count++;
57 return true;
61 void WvLockDev::unlock()
63 if (!lock_count) return;
65 if (!--lock_count)
66 dev_unlock(devicename, getpid());
70 #else /* !USE_LOCKDEV -- implement our own locking routines */
73 // note: this function uses the O_EXCL flag to open(), and thus assumes
74 // that /var/lock is not an NFS-mounted drive (according to the open() man
75 // page, you need to follow a special procedure to ensure successful NFS
76 // locking)
78 // Actually there may be other race conditions that we should look into.
79 bool WvLockDev::lock()
81 pid_t pid;
83 if (lock_count)
85 lock_count++;
86 return true;
89 WvFile fd(filename, O_RDWR | O_EXCL | O_CREAT, 0644);
91 if (fd.isok())
93 // We made a lock file...
94 fd.print("%10s\n", getpid());
96 else if (fd.geterr() == EEXIST)
98 char *inbuf;
100 // Lock file is already there! Check for staleness...
101 sleep(1); // preventing race condition...
103 fd.open(filename, O_RDONLY);
104 //fprintf(stderr, "ok: %d\n", fd.isok());
105 inbuf = trim_string(fd.blocking_getline(-1));
106 //fprintf(stderr, "blocking_getline: '%s'\n", inbuf);
108 if (inbuf)
109 pid = atoi(inbuf);
110 else
111 pid = 0;
113 //fprintf(stderr, "pid: '%d'\n", pid);
115 if (pid && pid != -1 && kill(pid, 0) == -1 && errno == ESRCH)
117 // we can create a lockfile now
118 fd.close();
119 if (unlink(filename))
120 return false; // cannot remove lockfile
121 fd.open(filename, O_RDWR | O_EXCL | O_CREAT, 0644);
122 fd.print("%10s\n", getpid());
124 else
125 return false; // device already locked
127 else // some other unexpected error
128 return false;
130 lock_count++;
131 return true;
136 void WvLockDev::unlock()
138 if (!lock_count) return;
140 if (!--lock_count)
141 unlink(filename);
145 #endif /* !USE_LOCKDEV */