35 m_error_msg (
"no errors")
40 l_start = l_len = l_pid = 0;
62 lock (
const string& fname_)
83 if (ftruncate (
m_fd, 0) < 0) {
98 if ((val = ::fcntl(
m_fd, F_GETFD, 0)) < 0) {
104 if (::fcntl (
m_fd, F_SETFD, val) < 0) {
108 DL((
PIDFLOCK,
"CLOSE-ON-EXEC is set on FD.\n"));
115 return m_error == 0 ? true :
false;
139 std::ostringstream mypid;
142 this->l_pid = getpid ();
144 len = strlen (mypid.str ().c_str ());
151 if (write (
m_fd, mypid.str ().c_str (), len) != len) {
154 DL((
PIDFLOCK,
"Wrote PID=%d to the lock file.\n", l_pid));
160 if (write (
m_fd, mypid.str ().c_str (), len) != len) {
163 DL((
PIDFLOCK,
"Wrote PID=%d to the lock file.\n", this->l_pid));
188 this->l_type = F_RDLCK;
190 this->l_type = F_WRLCK;
194 this->l_whence = SEEK_SET;
197 ret = ::fcntl (
m_fd, F_SETLK,
static_cast<struct flock*
>(
this));
199 DL((
PIDFLOCK,
"fcntl(fd=%d, F_SETLK, %s) returned: %d\n",
201 (this->l_type == F_RDLCK ?
"F_RDLCK" :
"F_WRLCK"),
222 this->l_type = F_WRLCK;
224 this->l_whence = SEEK_SET;
227 ret = ::fcntl (
m_fd, F_SETLK,
static_cast<struct flock*
>(
this));
229 DL((
PIDFLOCK,
"fcntl(fd=%d, F_SETLK, F_WRLCK) returned: %d\n",
m_fd, ret));
248 this->l_type = F_UNLCK;
250 this->l_whence = SEEK_SET;
253 ret = ::fcntl (
m_fd, F_SETLK,
static_cast<struct flock*
>(
this));
255 DL((
PIDFLOCK,
"fcntl(fd=%d, F_SETLK, F_UNLCK) returned: %d\n",
305 this->l_type = F_WRLCK;
307 this->l_whence = SEEK_SET;
310 ret = ::fcntl (
m_fd, F_GETLK,
static_cast<struct flock*
>(
this));
312 DL((
PIDFLOCK,
"fcntl(fd=%d, F_GETLK, %s) returned: %d\n",
314 (this->l_type == F_RDLCK ?
"F_RDLCK" :
"F_WRLCK"),
317 EL ((
PIDFLOCK,
"fcntl() failed. l_pid = %d\n", this->l_pid));
327 this->l_type = F_RDLCK;
328 if (read (
m_fd, buf, 64) > 0) {
329 if (sscanf (buf,
"%d", &pid) == 1) {
367 DL((
PIDFLOCK,
"Failed to retrieve lock status.\n"));
370 if (this->l_type == F_UNLCK) {
375 DL((
PIDFLOCK,
"Region is already locked by PID %d\n", this->l_pid));
376 return (this->l_pid);
395 if (
m_fd == -1)
return;
399 if (this->l_type == F_RDLCK)
402 if (this->l_type == F_WRLCK)
405 if (this->l_type == F_UNLCK)
409 this->l_whence == SEEK_SET ?
"SEEK_SET" :
410 this->l_whence == SEEK_CUR ?
"SEEK_CUR" :
"SEEK_END"));
412 DL((
PIDFLOCK,
"l_start : %d\n", this->l_start));
425 "Error: \"Failed to get a lock on PID file - %s\".\n", msg_));
441 m_fd = ::open (fname_.c_str (), O_WRONLY|O_CREAT, 0644);
453 log_error (
"PID file is already locked (by someone).");
461 if (errno == EACCES || errno == EAGAIN) {
462 log_error(
"PID file is locked by another process");
#define EL(X)
A macro for writing error message to the Logger.
#define DL(X)
A macro for writing debug message to the Logger.
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
A utility class for creating and managing process PID lock file.
int get_lock_status()
Retrieve lock status.
~PidFileLock()
Destructor.
int write_pid()
Write our process pid to the lock file.
pid_t open_pid_file(const std::string &fname_)
Open pid file in a cross-platform way.
int m_error
Last system call error.
const char * get_error_msg() const
In case of error, return a verbal description of the last error.
PidFileLock()
Constructor.
int get_error() const
Return last errno value.
void log_error(const char *msg_)
Log an error message to the log file and set internal error to errno.
pid_t test_region()
Test if file is unlocked.
string m_filename
Lock file name.
int m_fd
Lock file descriptor.
void dump()
Write the state of the lock to debug file.
bool lock(const string &filename_)
Lock the file.
int lock_region()
Lock the entire file.
int lock_region_exclusive()
Lock the entire file (only under Cygwin).
int unlock_region()
Unlock the entire file.
std::string strenv(const char *in_)
Expand the passed string in_ by substituting environment variable names for their values.
@ ASSAERR
ASSA and system errors
@ PIDFLOCK
Class PidFileLock messages
Socket & ends(Socket &os_)
ends manipulator.