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 <tdeapplication.h>
00024 #include <kdebug.h>
00025 #include <tdelocale.h>
00026 #include <kstandarddirs.h>
00027 #include <tdetempfile.h>
00028
00029 #include <tqfile.h>
00030
00031 #include <signal.h>
00032 #include <sys/types.h>
00033 #include <sys/stat.h>
00034 #include <unistd.h>
00035
00036 using namespace TDEABC;
00037
00038 Lock::Lock( const TQString &identifier )
00039 : mIdentifier( identifier )
00040 {
00041 mIdentifier.replace( "/", "_" );
00042 }
00043
00044 Lock::~Lock()
00045 {
00046 unlock();
00047 }
00048
00049 TQString Lock::locksDir()
00050 {
00051 return locateLocal( "data", "tdeabc/lock/" );
00052 }
00053
00054 bool Lock::readLockFile( const TQString &filename, int &pid, TQString &app )
00055 {
00056 TQFile file( filename );
00057 if ( !file.open( IO_ReadOnly ) ) return false;
00058
00059 TQTextStream t( &file );
00060 pid = t.readLine().toInt();
00061 app = t.readLine();
00062
00063 return true;
00064 }
00065
00066 bool Lock::writeLockFile( const TQString &filename )
00067 {
00068 TQFile file( filename );
00069 if ( !file.open( IO_WriteOnly ) ) return false;
00070 TQTextStream t( &file );
00071 t << ::getpid() << endl << TQString( TDEGlobal::instance()->instanceName() );
00072
00073 return true;
00074 }
00075
00076 TQString Lock::lockFileName() const
00077 {
00078 return locksDir() + mIdentifier + ".lock";
00079 }
00080
00081 bool Lock::lock()
00082 {
00083 kdDebug(5700) << "Lock::lock()" << endl;
00084
00085 TQString lockName = lockFileName();
00086 kdDebug(5700) << "-- lock name: " << lockName << endl;
00087
00088 if ( TQFile::exists( lockName ) ) {
00089 int pid;
00090 TQString app;
00091
00092 if ( !readLockFile( lockFileName(), pid, app ) ) {
00093 mError = i18n("Unable to open lock file.");
00094 return false;
00095 }
00096
00097 int retval = ::kill( pid, 0 );
00098 if ( retval == -1 && errno == ESRCH ) {
00099 TQFile::remove( lockName );
00100 kdWarning(5700) << "Removed stale lock file from process '" << app << "'"
00101 << endl;
00102 } else {
00103 TQString identifier( mIdentifier );
00104 identifier.replace( '_', '/' );
00105
00106 mError = i18n("The address book '%1' is locked by application '%2'.\nIf you believe this is incorrect, just remove the lock file from '%3'")
00107 .arg( identifier ).arg( app ).arg( locateLocal( "data", "tdeabc/lock/*.lock" ) );
00108 return false;
00109 }
00110 }
00111
00112 TQString lockUniqueName;
00113 lockUniqueName = mIdentifier + kapp->randomString( 8 );
00114 mLockUniqueName = locateLocal( "data", "tdeabc/lock/" + lockUniqueName );
00115 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl;
00116
00117
00118 writeLockFile( mLockUniqueName );
00119
00120
00121 int result = ::link( TQFile::encodeName( mLockUniqueName ),
00122 TQFile::encodeName( lockName ) );
00123
00124 if ( result == 0 ) {
00125 mError = "";
00126 emit locked();
00127 return true;
00128 }
00129
00130
00131
00132 mError = i18n("Error");
00133 return false;
00134 }
00135
00136 bool Lock::unlock()
00137 {
00138 int pid;
00139 TQString app;
00140 if ( readLockFile( lockFileName(), pid, app ) ) {
00141 if ( pid == getpid() ) {
00142 TQFile::remove( lockFileName() );
00143 TQFile::remove( mLockUniqueName );
00144 emit unlocked();
00145 } else {
00146 mError = i18n("Unlock failed. Lock file is owned by other process: %1 (%2)")
00147 .arg( app ).arg( TQString::number( pid ) );
00148 kdDebug() << "Lock::unlock(): " << mError << endl;
00149 return false;
00150 }
00151 }
00152
00153 mError = "";
00154 return true;
00155 }
00156
00157 TQString Lock::error() const
00158 {
00159 return mError;
00160 }
00161
00162 #include "lock.moc"