kabc
lock.cpp
00001 /* 00002 This file is part of libkabc. 00003 Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "lock.h" 00022 00023 #include <krandom.h> 00024 #include <kcomponentdata.h> 00025 #include <kdebug.h> 00026 #include <klocale.h> 00027 #include <kstandarddirs.h> 00028 00029 #include <QtCore/QFile> 00030 #include <QtCore/QTextStream> 00031 00032 #include <errno.h> 00033 #include <signal.h> 00034 #include <sys/types.h> 00035 #include <sys/stat.h> 00036 #include <unistd.h> 00037 00038 using namespace KABC; 00039 00040 class Lock::Private 00041 { 00042 public: 00043 Private( const QString &identifier ) 00044 : mIdentifier( identifier ), 00045 mOrigIdentifier( identifier ) 00046 { 00047 mIdentifier.replace( QLatin1Char( '/' ), QLatin1Char( '_' ) ); 00048 #ifdef Q_WS_WIN 00049 mIdentifier.replace( QLatin1Char( ':' ), QLatin1Char( '_' ) ); 00050 #endif 00051 } 00052 00053 QString mIdentifier; 00054 QString mOrigIdentifier; 00055 QString mLockUniqueName; 00056 QString mError; 00057 }; 00058 00059 Lock::Lock( const QString &identifier ) 00060 : d( new Private( identifier ) ) 00061 { 00062 } 00063 00064 Lock::~Lock() 00065 { 00066 unlock(); 00067 00068 delete d; 00069 } 00070 00071 QString Lock::locksDir() 00072 { 00073 return KStandardDirs::locateLocal( "data", QLatin1String( "kabc/lock/" ) ); 00074 } 00075 00076 bool Lock::readLockFile( const QString &filename, int &pid, QString &app ) 00077 { 00078 QFile file( filename ); 00079 if ( !file.open( QIODevice::ReadOnly ) ) { 00080 return false; 00081 } 00082 00083 QTextStream t( &file ); 00084 t >> pid >> ws >> app; 00085 00086 return true; 00087 } 00088 00089 bool Lock::writeLockFile( const QString &filename ) 00090 { 00091 QFile file( filename ); 00092 if ( !file.open( QIODevice::WriteOnly ) ) { 00093 return false; 00094 } 00095 00096 QTextStream t( &file ); 00097 t << ::getpid() << endl << QString( KGlobal::mainComponent().componentName() ); 00098 00099 return true; 00100 } 00101 00102 QString Lock::lockFileName() const 00103 { 00104 return locksDir() + d->mIdentifier + QLatin1String( ".lock" ); 00105 } 00106 00107 bool Lock::lock() 00108 { 00109 QString lockName = lockFileName(); 00110 kDebug() << "-- lock name:" << lockName; 00111 00112 if ( QFile::exists( lockName ) ) { // check if it is a stale lock file 00113 int pid; 00114 QString app; 00115 00116 if ( !readLockFile( lockFileName(), pid, app ) ) { 00117 d->mError = i18n( "Unable to open lock file." ); 00118 return false; 00119 } 00120 00121 int retval = ::kill( pid, 0 ); 00122 if ( retval == -1 && errno == ESRCH ) { // process doesn't exists anymore 00123 QFile::remove( lockName ); 00124 kWarning() << "Removed stale lock file from process '" << app << "'"; 00125 } else { 00126 d->mError = i18n( "The resource '%1' is locked by application '%2'.", 00127 d->mOrigIdentifier, app ); 00128 return false; 00129 } 00130 } 00131 00132 QString lockUniqueName; 00133 lockUniqueName = d->mIdentifier + KRandom::randomString( 8 ); 00134 d->mLockUniqueName = KStandardDirs::locateLocal( 00135 "data", QLatin1String( "kabc/lock/" ) + lockUniqueName ); 00136 kDebug() << "-- lock unique name:" << d->mLockUniqueName; 00137 00138 // Create unique file 00139 writeLockFile( d->mLockUniqueName ); 00140 00141 // Create lock file 00142 int result = ::link( QFile::encodeName( d->mLockUniqueName ), 00143 QFile::encodeName( lockName ) ); 00144 00145 if ( result == 0 ) { 00146 d->mError.clear(); 00147 emit locked(); 00148 return true; 00149 } 00150 00151 // TODO: check stat 00152 00153 d->mError = i18n( "Error" ); 00154 return false; 00155 } 00156 00157 bool Lock::unlock() 00158 { 00159 int pid; 00160 QString app; 00161 if ( readLockFile( lockFileName(), pid, app ) ) { 00162 if ( pid == getpid() ) { 00163 QFile::remove( lockFileName() ); 00164 QFile::remove( d->mLockUniqueName ); 00165 emit unlocked(); 00166 } else { 00167 d->mError = i18n( "Unlock failed. Lock file is owned by other process: %1 (%2)", app, pid ); 00168 kDebug() << d->mError; 00169 return false; 00170 } 00171 } 00172 00173 d->mError.clear(); 00174 00175 return true; 00176 } 00177 00178 QString Lock::error() const 00179 { 00180 return d->mError; 00181 } 00182 00183 #include "lock.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:49:55 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:49:55 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.