#include #include #include #include #include #include #include #include "instance.h" #include "fileutil.h" #include "debug.h" ///////////////////////////////////////////////////////////////////////////// // #define _PIDFILE_ROOT_DIR "/tmp" ///////////////////////////////////////////////////////////////////////////// // int CProcessInstance::m_fdPid = -1; ///////////////////////////////////////////////////////////////////////////// // CProcessInstance::CProcessInstance(void) { m_pid = getpid(); #if _USE_BINARY_LOCK memset(m_szBinaryPath, 0, sizeof(m_szBinaryPath)); #else // _USE_BINARY_LOCK memset(m_szPidFileDir, 0, sizeof(m_szPidFileDir)); memset(m_szPidFilePath, 0, sizeof(m_szPidFilePath)); #endif // _USE_BINARY_LOCK } CProcessInstance::~CProcessInstance(void) { UnlockInstance(); } ///////////////////////////////////////////////////////////////////////////// // bool CProcessInstance::LockInstance(const char *pszUuid) { extern char *__progname; int nRet, nRead, fdPid; if(m_fdPid >= 0) { TRACE("%s: Instance lock already acquired!\n", __progname); return true; } #if _USE_BINARY_LOCK if(!GetAppPath(m_szBinaryPath, sizeof(m_szBinaryPath))) { TRACE("Failed to retrieve binary path!\n"); return false; } fdPid = open(m_szBinaryPath, O_RDONLY); if(fdPid < 0) { TRACE("Failed to open binary file: %s\n", m_szBinaryPath); TRACE("errno: %d\n", errno); return false; } #else // _USE_BINARY_LOCK sprintf(m_szPidFileDir, "%s/%s", _PIDFILE_ROOT_DIR, pszUuid); sprintf(m_szPidFilePath, "%s/%s/%s.pid", _PIDFILE_ROOT_DIR, pszUuid, __progname); if(!DirectoryExist(m_szPidFileDir)) { if(!CreateDirectory(m_szPidFileDir)) { TRACE("Failed to create run directory!\n"); return false; } } fdPid = open(m_szPidFilePath, O_CREAT | O_RDWR, 0666); if(fdPid < 0) { TRACE("Failed to open PID file: %s\n", m_szPidFilePath); TRACE("errno: %d\n", errno); return false; } #endif // _USE_BINARY_LOCK if((nRet = flock(fdPid, LOCK_EX | LOCK_NB))) { if(errno == EWOULDBLOCK) { #if !_USE_BINARY_LOCK char szPid[32]; if((nRead = (int)read(fdPid, szPid, sizeof(szPid) - 1)) > 0) { szPid[nRead] = '\0'; TRACE("%s: another instance is already running -> PID: %s\n", __progname, szPid); } else #endif // _USE_BINARY_LOCK { TRACE("%s: another instance is already running!\n", __progname); } close(fdPid); return false; } else { TRACE("flock failed with code %d\n", errno); close(fdPid); return false; } } else { #if !_USE_BINARY_LOCK char szPid[32]; int nLen = sprintf(szPid, "%d", getpid()); write(fdPid, szPid, (size_t)nLen); #endif // _USE_BINARY_LOCK m_fdPid = fdPid; } return true; } ///////////////////////////////////////////////////////////////////////////// // void CProcessInstance::UnlockInstance(void) { if(m_fdPid >= 0) { int fdPid = m_fdPid; m_fdPid = -1; flock(fdPid, LOCK_UN); close(fdPid); } #if _USE_BINARY_LOCK memset(m_szBinaryPath, 0, sizeof(m_szBinaryPath)); #else // _USE_BINARY_LOCK memset(m_szPidFileDir, 0, sizeof(m_szPidFileDir)); memset(m_szPidFilePath, 0, sizeof(m_szPidFilePath)); #endif // _USE_BINARY_LOCK m_pid = -1; }