kabc Library API Documentation

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., 59 Temple Place - Suite 330,
00018     Boston, MA 02111-1307, USA.
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 ) ) {  // check if it is a stale lock file
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 ) { // process doesn't exists anymore
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   // Create unique file
00117   writeLockFile( mLockUniqueName );
00118 
00119   // Create lock file
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   // TODO: check stat
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"
KDE Logo
This file is part of the documentation for kabc Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed May 4 07:15:21 2005 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003