WvStreams
|
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * A simple lockfile class using WvStreams. 00006 */ 00007 00008 #include "wvlockfile.h" 00009 #include "strutils.h" 00010 #include <signal.h> 00011 00012 00013 WvLockFile::WvLockFile(WvStringParm _lockname) 00014 : lockname(_lockname) 00015 { 00016 // nothing special 00017 } 00018 00019 00020 bool WvLockFile::isok() 00021 { 00022 pid_t pid = readpid(); 00023 return !pid || pid == getpid(); 00024 } 00025 00026 00027 bool WvLockFile::lock() 00028 { 00029 if (!isok()) 00030 return false; 00031 00032 WvFile lock(lockname, O_WRONLY|O_CREAT|O_EXCL); 00033 if (!lock.isok()) 00034 return false; 00035 00036 lock.print("%s\n", getpid()); 00037 return true; 00038 } 00039 00040 00041 bool WvLockFile::unlock() 00042 { 00043 if (!isok()) 00044 return false; 00045 00046 unlink(lockname); 00047 00048 return readpid() == 0; 00049 } 00050 00051 00052 pid_t WvLockFile::readpid() 00053 { 00054 char *line; 00055 pid_t pid = 0; 00056 WvString lockdir(getdirname(lockname)); 00057 00058 if (access(lockdir, W_OK) < 0 00059 || (!access(lockname, F_OK) && access(lockname, R_OK) < 0)) 00060 return -1; // won't be able to create a lock 00061 else 00062 { 00063 WvFile lock(lockname, O_RDONLY); 00064 line = lock.blocking_getline(-1); 00065 if (line) 00066 { 00067 pid = atoi(line); 00068 if (pid != -1 && kill(pid, 0) < 0 && errno == ESRCH) // no such process 00069 { 00070 // previous lock owner is dead; clean it up. 00071 ::unlink(lockname); 00072 return 0; 00073 } 00074 } 00075 else 00076 { 00077 // blank lock file; clean it up. 00078 ::unlink(lockname); 00079 return 0; 00080 } 00081 } 00082 00083 return pid; 00084 }