// -*- c++ -*-
//------------------------------------------------------------------------------
//                           PidFileLock.h
//------------------------------------------------------------------------------
// $Id: PidFileLock.h,v 1.2 2002/12/05 03:20:17 vlg Exp $
//------------------------------------------------------------------------------
//  Copyright (C) 1997-2002  Vladislav Grinchenko <vladg@erols.com>
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//------------------------------------------------------------------------------
#ifndef FILE_LOCK_H
#define FILE_LOCK_H

//System Includes
#include <sys/types.h>

#include "assa/Assert.h"

//STL
#include <string>
using std::string;

namespace ASSA {

/** @file PidFileLock.h

A utility class for creating and managing process PID lock file.
*/

class PidFileLock   : public flock
{
public:
	/// Constructor. 
	PidFileLock ();

	/** Destructor. If process is holds the lock on the file, file
	    is removed from the file system.
	*/
	~PidFileLock ();

	/** Lock the file. 
	    @return true on success, false on error
	*/
	bool lock (const string& filename_);

	/** Return last <TT>errno</TT> value. 
	    @return 0 for success, <TT>errno</TT> on error
	*/
	int get_error () const;
	
	/** In case of error, return a verbal description of the 
	    last error.
	*/
	const char* get_error_msg () const;

	/** Write the state of the lock to debug file. <TT>m_fd = -1</TT>
	    indicates that lock file is not opened.
	*/
	void dump ();

private:
	/** Lock the entire file.
	    @return -1 on error and if file is locked by some other
	    process, errno is set to EAGAIN or EACCES; 0 on success.
	*/
	int lock_region ();

	/** Test if file can be locked by the process.
	    @return 0 on success (file can be locked or is already locked);
	    pid of the process that holds the lock on error.
	*/
	pid_t test_region ();

	/** Log an error message to the log file and set internal  error to errno.
	*/
	void log_error   (const char* msg_);

private:
	/// Lock file name
	string m_filename;

	/// Lock file descriptor
	int    m_fd;

	/// Last system call error
	int    m_error;

	/// Error explanation
	string m_error_msg;
};

inline int 
PidFileLock::
get_error () const 
{ 
	return m_error; 
}

inline const char* 
PidFileLock::
get_error_msg () const 
{ 
	return m_error_msg.c_str (); 
}

} // end namespace ASSA

#endif /* FILE_LOCK_H */  
