00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "lock.h"
00022
00023
#include <kapplication.h>
00024
#include <kdebug.h>
00025
#include <klocale.h>
00026
#include <kstandarddirs.h>
00027
#include <ktempfile.h>
00028
00029
#include <qfile.h>
00030
00031
#include <signal.h>
00032
#include <sys/types.h>
00033
#include <sys/stat.h>
00034
#include <unistd.h>
00035
00036
using namespace KABC;
00037
00038 Lock::Lock(
const QString &identifier )
00039 : mIdentifier( identifier )
00040 {
00041 mIdentifier.
replace(
"/",
"_" );
00042 }
00043
00044 Lock::~Lock()
00045 {
00046
unlock();
00047 }
00048
00049
QString Lock::locksDir()
00050 {
00051
return locateLocal(
"data",
"kabc/lock/" );
00052 }
00053
00054
bool Lock::readLockFile(
const QString &filename,
int &pid,
QString &app )
00055 {
00056
QFile file( filename );
00057
if ( !file.
open( IO_ReadOnly ) )
return false;
00058
00059
QTextStream t( &file );
00060 t >> pid >> ws >> app;
00061
00062
return true;
00063 }
00064
00065
bool Lock::writeLockFile(
const QString &filename )
00066 {
00067
QFile file( filename );
00068
if ( !file.
open( IO_WriteOnly ) )
return false;
00069
QTextStream t( &file );
00070 t << ::getpid() <<
endl <<
QString( KGlobal::instance()->instanceName() );
00071
00072
return true;
00073 }
00074
00075 QString Lock::lockFileName()
const
00076
{
00077
return locksDir() + mIdentifier +
".lock";
00078 }
00079
00080 bool Lock::lock()
00081 {
00082
kdDebug(5700) <<
"Lock::lock()" <<
endl;
00083
00084 QString lockName = lockFileName();
00085
kdDebug(5700) <<
"-- lock name: " << lockName <<
endl;
00086
00087
if (
QFile::exists( lockName ) ) {
00088
int pid;
00089 QString app;
00090
00091
if ( !readLockFile( lockFileName(), pid, app ) ) {
00092 mError = i18n(
"Unable to open lock file.");
00093
return false;
00094 }
00095
00096
int retval = ::kill( pid, 0 );
00097
if ( retval == -1 && errno == ESRCH ) {
00098
QFile::remove( lockName );
00099
kdWarning(5700) <<
"Removed stale lock file from process '" << app <<
"'"
00100 <<
endl;
00101 }
else {
00102 QString identifier( mIdentifier );
00103 identifier.
replace(
'_',
'/' );
00104
00105 mError = i18n(
"The resource '%1' is locked by application '%2'.")
00106 .
arg( identifier ).arg( app );
00107
return false;
00108 }
00109 }
00110
00111 QString lockUniqueName;
00112 lockUniqueName = mIdentifier + kapp->randomString( 8 );
00113 mLockUniqueName =
locateLocal(
"data",
"kabc/lock/" + lockUniqueName );
00114
kdDebug(5700) <<
"-- lock unique name: " << mLockUniqueName <<
endl;
00115
00116
00117 writeLockFile( mLockUniqueName );
00118
00119
00120
int result = ::link( QFile::encodeName( mLockUniqueName ),
00121 QFile::encodeName( lockName ) );
00122
00123
if ( result == 0 ) {
00124 mError =
"";
00125 emit locked();
00126
return true;
00127 }
00128
00129
00130
00131 mError = i18n(
"Error");
00132
return false;
00133 }
00134
00135 bool Lock::unlock()
00136 {
00137
int pid;
00138 QString app;
00139
if ( readLockFile( lockFileName(), pid, app ) ) {
00140
if ( pid == getpid() ) {
00141
QFile::remove( lockFileName() );
00142
QFile::remove( mLockUniqueName );
00143 emit unlocked();
00144 }
else {
00145 mError = i18n(
"Unlock failed. Lock file is owned by other process: %1 (%2)")
00146 .
arg( app ).arg( QString::number( pid ) );
00147
kdDebug() <<
"Lock::unlock(): " << mError <<
endl;
00148
return false;
00149 }
00150 }
00151
00152 mError =
"";
00153
return true;
00154 }
00155
00156 QString Lock::error()
const
00157
{
00158
return mError;
00159 }
00160
00161
#include "lock.moc"