| # kabc Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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"

This file is part of the documentation for kabc Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:31:30 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003