00001
00002
00003
00004
00005
00006
00007 #include "wvlockdev.h"
00008 #include "wvfile.h"
00009 #include "strutils.h"
00010 #include <signal.h>
00011 #include <string.h>
00012 #include <sys/types.h>
00013 #include <fcntl.h>
00014 #include <sys/stat.h>
00015 #include <errno.h>
00016
00017 WvLockDev::WvLockDev(WvString _devicename)
00018 : devicename(_devicename)
00019 {
00020 const char *p = strrchr(devicename, '/');
00021 if (p)
00022 p++;
00023 else
00024 p = devicename;
00025
00026 lock_count = 0;
00027 filename = WvString("/var/lock/LCK..%s", p);
00028 }
00029
00030
00031 WvLockDev::~WvLockDev()
00032 {
00033 if (lock_count)
00034 {
00035 lock_count = 1;
00036 unlock();
00037 }
00038 }
00039
00040
00041 #if USE_LOCKDEV
00042
00043 #include <lockdev.h>
00044
00045 bool WvLockDev::lock()
00046 {
00047 if (lock_count)
00048 {
00049 lock_count++;
00050 return true;
00051 }
00052
00053 if (dev_lock(devicename))
00054 return false;
00055
00056 lock_count++;
00057 return true;
00058 }
00059
00060
00061 void WvLockDev::unlock()
00062 {
00063 if (!lock_count) return;
00064
00065 if (!--lock_count)
00066 dev_unlock(devicename, getpid());
00067 }
00068
00069
00070 #else
00071
00072
00073
00074
00075
00076
00077
00078
00079 bool WvLockDev::lock()
00080 {
00081 pid_t pid;
00082
00083 if (lock_count)
00084 {
00085 lock_count++;
00086 return true;
00087 }
00088
00089 WvFile fd(filename, O_RDWR | O_EXCL | O_CREAT, 0644);
00090
00091 if (fd.isok())
00092 {
00093
00094 fd.print("%10s\n", getpid());
00095 }
00096 else if (fd.geterr() == EEXIST)
00097 {
00098 char *inbuf;
00099
00100
00101 sleep(1);
00102
00103 fd.open(filename, O_RDONLY);
00104
00105 inbuf = trim_string(fd.blocking_getline(-1));
00106
00107
00108 if (inbuf)
00109 pid = atoi(inbuf);
00110 else
00111 pid = 0;
00112
00113
00114
00115 if (pid && pid != -1 && kill(pid, 0) == -1 && errno == ESRCH)
00116 {
00117
00118 fd.close();
00119 if (unlink(filename))
00120 return false;
00121 fd.open(filename, O_RDWR | O_EXCL | O_CREAT, 0644);
00122 fd.print("%10s\n", getpid());
00123 }
00124 else
00125 return false;
00126 }
00127 else
00128 return false;
00129
00130 lock_count++;
00131 return true;
00132 }
00133
00134
00135
00136 void WvLockDev::unlock()
00137 {
00138 if (!lock_count) return;
00139
00140 if (!--lock_count)
00141 unlink(filename);
00142 }
00143
00144
00145 #endif