WvStreams
wvlockfile.cc
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 }