instance.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <sys/file.h>
  6. #include <linux/limits.h>
  7. #include <unistd.h>
  8. #include "instance.h"
  9. #include "fileutil.h"
  10. #include "debug.h"
  11. /////////////////////////////////////////////////////////////////////////////
  12. //
  13. #define _PIDFILE_ROOT_DIR "/tmp"
  14. /////////////////////////////////////////////////////////////////////////////
  15. //
  16. int CProcessInstance::m_fdPid = -1;
  17. /////////////////////////////////////////////////////////////////////////////
  18. //
  19. CProcessInstance::CProcessInstance(void)
  20. {
  21. m_pid = getpid();
  22. #if _USE_BINARY_LOCK
  23. memset(m_szBinaryPath, 0, sizeof(m_szBinaryPath));
  24. #else // _USE_BINARY_LOCK
  25. memset(m_szPidFileDir, 0, sizeof(m_szPidFileDir));
  26. memset(m_szPidFilePath, 0, sizeof(m_szPidFilePath));
  27. #endif // _USE_BINARY_LOCK
  28. }
  29. CProcessInstance::~CProcessInstance(void)
  30. {
  31. UnlockInstance();
  32. }
  33. /////////////////////////////////////////////////////////////////////////////
  34. //
  35. bool CProcessInstance::LockInstance(const char *pszUuid)
  36. {
  37. extern char *__progname;
  38. int nRet, nRead, fdPid;
  39. if(m_fdPid >= 0)
  40. {
  41. TRACE("%s: Instance lock already acquired!\n", __progname);
  42. return true;
  43. }
  44. #if _USE_BINARY_LOCK
  45. if(!GetAppPath(m_szBinaryPath, sizeof(m_szBinaryPath)))
  46. {
  47. TRACE("Failed to retrieve binary path!\n");
  48. return false;
  49. }
  50. fdPid = open(m_szBinaryPath, O_RDONLY);
  51. if(fdPid < 0)
  52. {
  53. TRACE("Failed to open binary file: %s\n", m_szBinaryPath);
  54. TRACE("errno: %d\n", errno);
  55. return false;
  56. }
  57. #else // _USE_BINARY_LOCK
  58. sprintf(m_szPidFileDir, "%s/%s", _PIDFILE_ROOT_DIR, pszUuid);
  59. sprintf(m_szPidFilePath, "%s/%s/%s.pid", _PIDFILE_ROOT_DIR, pszUuid, __progname);
  60. if(!DirectoryExist(m_szPidFileDir))
  61. {
  62. if(!CreateDirectory(m_szPidFileDir))
  63. {
  64. TRACE("Failed to create run directory!\n");
  65. return false;
  66. }
  67. }
  68. fdPid = open(m_szPidFilePath, O_CREAT | O_RDWR, 0666);
  69. if(fdPid < 0)
  70. {
  71. TRACE("Failed to open PID file: %s\n", m_szPidFilePath);
  72. TRACE("errno: %d\n", errno);
  73. return false;
  74. }
  75. #endif // _USE_BINARY_LOCK
  76. if((nRet = flock(fdPid, LOCK_EX | LOCK_NB)))
  77. {
  78. if(errno == EWOULDBLOCK)
  79. {
  80. #if !_USE_BINARY_LOCK
  81. char szPid[32];
  82. if((nRead = (int)read(fdPid, szPid, sizeof(szPid) - 1)) > 0)
  83. {
  84. szPid[nRead] = '\0';
  85. TRACE("%s: another instance is already running -> PID: %s\n", __progname, szPid);
  86. }
  87. else
  88. #endif // _USE_BINARY_LOCK
  89. {
  90. TRACE("%s: another instance is already running!\n", __progname);
  91. }
  92. close(fdPid);
  93. return false;
  94. }
  95. else
  96. {
  97. TRACE("flock failed with code %d\n", errno);
  98. close(fdPid);
  99. return false;
  100. }
  101. }
  102. else
  103. {
  104. #if !_USE_BINARY_LOCK
  105. char szPid[32];
  106. int nLen = sprintf(szPid, "%d", getpid());
  107. write(fdPid, szPid, (size_t)nLen);
  108. #endif // _USE_BINARY_LOCK
  109. m_fdPid = fdPid;
  110. }
  111. return true;
  112. }
  113. /////////////////////////////////////////////////////////////////////////////
  114. //
  115. void CProcessInstance::UnlockInstance(void)
  116. {
  117. if(m_fdPid >= 0)
  118. {
  119. int fdPid = m_fdPid;
  120. m_fdPid = -1;
  121. flock(fdPid, LOCK_UN);
  122. close(fdPid);
  123. }
  124. #if _USE_BINARY_LOCK
  125. memset(m_szBinaryPath, 0, sizeof(m_szBinaryPath));
  126. #else // _USE_BINARY_LOCK
  127. memset(m_szPidFileDir, 0, sizeof(m_szPidFileDir));
  128. memset(m_szPidFilePath, 0, sizeof(m_szPidFilePath));
  129. #endif // _USE_BINARY_LOCK
  130. m_pid = -1;
  131. }