From 3ed5f6bda5dabbb74b0126982cb515de1a8e2558 Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Wed, 24 Feb 2016 21:05:19 +0700 Subject: [PATCH] Fixed FTBFS in Debian/Ubuntu due to missing liblockdev1-dev package. Device locking is now done through 'flock()' Signed-off-by: Michele Calgaro --- ConfigureChecks.cmake | 11 --- config.h.cmake | 3 - kandy/configure.in.in | 12 --- kandy/src/CMakeLists.txt | 2 +- kandy/src/Makefile.am | 2 +- kandy/src/modem.cpp | 152 +++++++++++--------------------------- kmobile/DESIGN | 12 +-- kmobile/Makefile.am | 4 +- kmobile/configure.in.in | 16 ---- kmobile/kmobiledevice.cpp | 124 ++++++------------------------- kmobile/kmobiledevice.h | 3 +- 11 files changed, 79 insertions(+), 262 deletions(-) delete mode 100644 kandy/configure.in.in delete mode 100644 kmobile/configure.in.in diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index dd7034c7..c0bcd225 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -54,17 +54,6 @@ if( BUILD_KMOBILE ) endif( ) -if( BUILD_KANDY OR (BUILD_KMOBILE AND NOT HAVE_BAUDBOY_H) ) - check_include_file( "lockdev.h" HAVE_LOCKDEV_H ) - if( HAVE_LOCKDEV_H ) - check_library_exists( lockdev dev_unlock "" HAVE_LOCKDEV ) - if( HAVE_LOCKDEV ) - set( LOCKDEV_LIBRARY lockdev CACHE INTERNAL "" FORCE ) - endif( ) - endif( ) -endif( ) - - if( WITH_GNOKII AND (BUILD_KADDRESSBOOK OR BUILD_KMOBILE) ) pkg_search_module( GNOKII gnokii ) if( NOT GNOKII_FOUND ) diff --git a/config.h.cmake b/config.h.cmake index eecbf497..206a8123 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -39,9 +39,6 @@ // kaddressbook #cmakedefine TDEPIM_NEW_DISTRLISTS 1 -// kandy -#cmakedefine HAVE_LOCKDEV 1 - // karm #cmakedefine HAVE_LIBXSS 1 diff --git a/kandy/configure.in.in b/kandy/configure.in.in deleted file mode 100644 index b3bd4558..00000000 --- a/kandy/configure.in.in +++ /dev/null @@ -1,12 +0,0 @@ -# check for lockdev, optionally used to lock serial device -AH_TEMPLATE(HAVE_LOCKDEV) -AC_CHECK_HEADERS(lockdev.h, HAVE_LOCKDEV_H=1, HAVE_LOCKDEV_H=) -AC_SUBST(HAVE_LOCKDEV_H) -# we check for dev_unlock since kmobile checks dev_lock, caches it -# and the variables are messed up then... *sigh* -if test -n "$HAVE_LOCKDEV_H"; then - AC_CHECK_LIB(lockdev, dev_unlock, - [KANDY_LIBLOCKDEV="-llockdev $KANDY_LIBLOCKDEV" -AC_DEFINE(HAVE_LOCKDEV)], , $KANDY_LIBLOCKDEV) -fi -AC_SUBST(KANDY_LIBLOCKDEV) diff --git a/kandy/src/CMakeLists.txt b/kandy/src/CMakeLists.txt index 06889351..04130591 100644 --- a/kandy/src/CMakeLists.txt +++ b/kandy/src/CMakeLists.txt @@ -47,7 +47,7 @@ tde_add_executable( kandy AUTOMOC atcommand.cpp commanditem.cpp mobilegui_base.ui mobilegui.cpp commandscheduler.cpp commandset.cpp kandyprefs.kcfgc kandyprefsdialog.cpp mobilemain.cpp - LINK tdepim-shared ${LOCKDEV_LIBRARY} + LINK tdepim-shared DESTINATION ${BIN_INSTALL_DIR} ) diff --git a/kandy/src/Makefile.am b/kandy/src/Makefile.am index 7691d37b..f6187234 100644 --- a/kandy/src/Makefile.am +++ b/kandy/src/Makefile.am @@ -3,7 +3,7 @@ bin_PROGRAMS = kandy kandy_client INCLUDES = -I$(top_srcdir) $(all_includes) kandy_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor -kandy_LDADD = $(KANDY_LIBLOCKDEV) $(LIB_TDEFILE) -ltdeabc $(top_builddir)/libtdepim/libtdepim.la +kandy_LDADD = $(LIB_TDEFILE) -ltdeabc $(top_builddir)/libtdepim/libtdepim.la kandy_SOURCES = main.cpp kandy.cpp \ cmdpropertiesdialog_base.ui cmdpropertiesdialog.cpp \ kandyview.cpp \ diff --git a/kandy/src/modem.cpp b/kandy/src/modem.cpp index 86c36d67..2a275bf4 100644 --- a/kandy/src/modem.cpp +++ b/kandy/src/modem.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -75,10 +76,10 @@ Modem::Modem( KandyPrefs *kprefs, TQObject *parent, const char *name ) : - TQObject(parent, name) + TQObject(parent, name), fd(-1) { mOpen = false; - + prefs = kprefs; timer = new TQTimer( this, "modemtimer" ); @@ -185,28 +186,31 @@ bool Modem::open() { struct termios tty; - close(); - if ( !lockDevice() ) - return false; + if (fd == -1) + { + TQCString dev = TQFile::encodeName( (*prefs).serialDevice() ); + const char *fdev = dev.data(); + if ( ( fd = ::open( fdev, O_RDWR | O_NOCTTY | O_NONBLOCK ) ) == -1 ) { + emit errorMessage( i18n( "Unable to open device '%1'. " + "Please check that you have sufficient permissions." ) + .arg( fdev ) ); + return false; + } + } - TQCString dev = TQFile::encodeName( (*prefs).serialDevice() ); - const char *fdev = dev.data(); - if ( ( fd = ::open( fdev, O_RDWR | O_NOCTTY | O_NONBLOCK ) ) == -1 ) { - emit errorMessage( i18n( "Unable to open device '%1'. " - "Please check that you have sufficient permissions." ) - .arg( fdev ) ); + if ( !lockDevice() ) return false; - } tcflush( fd, TCIOFLUSH ); if ( tcgetattr( fd, &init_tty ) == -1 ) { int errnumber = errno; emit errorMessage( i18n( "Communication setup failed (tcgetattr code: %1)" ) .arg(strerror(errnumber)) ); + unlockDevice(); ::close( fd ); - fd = 0; + fd = -1; return false; } @@ -221,8 +225,9 @@ bool Modem::open() if ( tcsetattr( fd, TCSANOW, &tty ) == -1 ) { emit errorMessage( i18n( "tcsetattr() failed." ) ); + unlockDevice(); ::close( fd ); - fd = 0; + fd = -1; return false; } @@ -244,127 +249,56 @@ void Modem::close() delete sn; sn = 0; + unlockDevice(); + if ( fd ) { tcflush( fd, TCIOFLUSH ); tcsetattr( fd, TCSANOW, &init_tty ); ::close( fd ); - fd = 0; + fd = -1; } xreset(); - unlockDevice(); - mOpen = false; } void Modem::flush() { - if ( fd ) { + if ( fd != -1) { tcflush( fd, TCIOFLUSH ); bufpos = 0; } } -#ifdef HAVE_LOCKDEV -#include -#endif - bool Modem::lockDevice() { - if ( is_locked ) + if (is_locked) return true; -#ifdef HAVE_LOCKDEV - is_locked = !dev_lock( (*prefs).serialDevice().local8Bit() ); - if (!is_locked) - emit errorMessage( i18n( "Unable to lock device '%1'." ).arg( - (*prefs).serialDevice() )); - return is_locked; -#else - ssize_t count; - pid_t pid; - int lfd; - struct passwd *pw; - TQStringList pathList; - TQString fileName, content; - - pathList = TQStringList::split( "/", (*prefs).serialDevice() ); - fileName = (*prefs).lockDirectory() + "/LCK.." + pathList.last(); - - if ( !access( TQFile::encodeName( fileName ).data(), F_OK ) ) { - char buf[256]; - - - if ( ( lfd = ::open( TQFile::encodeName( fileName ), O_RDONLY ) ) < 0 ) { - emit errorMessage( i18n( "Unable to open lock file '%1'.") - .arg( fileName ) ); - return false; - } - - count = read( lfd, buf, 79 ); - - if ( count < 0 ) { - emit errorMessage( i18n( "Unable to read lock file '%1'.") - .arg( fileName ) ); - ::close( lfd ); - return false; - } - buf[ count ] = 0; - ::close( lfd ); - - count = sscanf( buf, "%d", &pid ); - if ( ( count != 1 ) || ( pid <= 0 ) ) { - emit errorMessage( i18n( "Unable to get PID from file '%1'.") - .arg( fileName ) ); - return false; - } - - if ( !kill( (pid_t) pid, 0 ) ) { - emit errorMessage( i18n( "Process with PID %1, which is locking the device, is still running.") - .arg( pid ) ); - return false; - } - - if ( errno != ESRCH ) { - emit errorMessage( i18n( "Unable to emit signal to PID of existing lock file.") ); - return false; - } - } - - if ( ( lfd = creat( TQFile::encodeName( fileName ).data(), 0644 ) ) == -1 ) { - emit errorMessage( i18n( "Unable to create lock file '%1'. " - "Please check that you have sufficient permissions.") - .arg( fileName ) ); - return false; + if (flock(fd, LOCK_EX)) + { + // Locking failed + is_locked = false; + emit errorMessage(i18n("Unable to lock device '%1'.").arg((*prefs).serialDevice())); + } + else + { + is_locked = true; } - pid = (int) getpid(); - pw = getpwuid( getuid() ); - content.sprintf( "%08d %s %s", pid, "kandy", pw->pw_name ); - write( lfd, TQFile::encodeName( content ).data(), content.length() ); - ::close( lfd ); - - is_locked = true; - - return true; -#endif + return is_locked; } void Modem::unlockDevice() { -#ifdef HAVE_LOCKDEV - dev_unlock( (*prefs).serialDevice().local8Bit(), getpid() ); -#else - if ( is_locked ) { - TQStringList pathList = TQStringList::split( "/", (*prefs).serialDevice() ); - - TQFile::remove( (*prefs).lockDirectory() + "/LCK.." + pathList.last() ); - is_locked = false; - } -#endif + if (fd != -1 && is_locked) + { + flock(fd, LOCK_UN); + is_locked = false; + } } @@ -373,7 +307,7 @@ bool Modem::dsrOn() int flags; - if ( !fd ) { + if ( fd == -1 ) { #ifdef MODEM_DEBUG fprintf( stderr, "Modem: dsrOn(): File not open.\n" ); #endif @@ -396,7 +330,7 @@ bool Modem::ctsOn() int flags; - if ( !fd ) { + if ( fd == -1 ) { #ifdef MODEM_DEBUG fprintf( stderr, "Modem: ctsOn(): File not open.\n" ); #endif @@ -640,7 +574,7 @@ void Modem::init() { is_locked = false; - fd = 0; + fd = -1; sn = 0; cspeed = B38400; @@ -687,7 +621,7 @@ ushort Modem::calcCRC() int i, j; ushort c = 0; - + for ( i = 0; i < xsize; i++ ) { c ^= (ushort) buffer[ i ] << 8; for ( j = 0; j < 8; j++ ) diff --git a/kmobile/DESIGN b/kmobile/DESIGN index 90ea509e..c8e28f06 100644 --- a/kmobile/DESIGN +++ b/kmobile/DESIGN @@ -7,7 +7,7 @@ "kmobile" is suite to easily access "Mobile Devices", which means, that you have one single interface to access -any type of mobile device (e.g. cellular phone, PDAs, +any type of mobile device (e.g. cellular phone, PDAs, MP3-Players, Digital Cameras and a lot more). Each of this devices have different types of information, @@ -17,11 +17,11 @@ Each of this devices have different types of information, - calendar entries, - a file storage section (e.g. pictures in digital cameras) - and more - + The whole interface is pretty extendable. Each device has -a device driver, which reports the capatibilities of the +a device driver, which reports the capatibilities of the connected device to the higher level. -So, if you once write a device driver, you can access it's +So, if you once write a device driver, you can access it's contents from any KDE application later. Currently the whole interface is divided into 3 sections: @@ -48,7 +48,7 @@ The mid-layer handles the main functionality, which is entirely implemented in the kmobile application. All low-level drivers are loaded by kmobile only, and then all low-level functions to any device is made available to other applications -with a DCOP interface. Normal KDE applications should prefer the +with a DCOP interface. Normal KDE applications should prefer the userland library (see below) instead of using direct DCOP calls. Nevertheless, the DCOP interface might be very interesting to write standalone command line tools. @@ -86,7 +86,7 @@ HINTS FOR DRIVER DEVELOPERS: all calls to your driver, so you always will have a clean state - use lockDevice("/dev/ttyS1") and unlockDevice("/dev/ttyS1") to - lock those devices system-wide (creates /var/lock/LCK.. files), + lock those devices system-wide, and to prevent other applications to access the same physical ports/devices - use the helper functions createDirEntry() and createFileEntry() to diff --git a/kmobile/Makefile.am b/kmobile/Makefile.am index 6d2640ee..249ab533 100644 --- a/kmobile/Makefile.am +++ b/kmobile/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = . devices # tdeioslave -bin_PROGRAMS = kmobile +bin_PROGRAMS = kmobile lib_LTLIBRARIES = libkmobiledevice.la libkmobileclient.la @@ -21,7 +21,7 @@ noinst_HEADERS = kmobile.h kmobileview.h kmobileitem.h pref.h # the low-level devices driver library libkmobiledevice_la_SOURCES = kmobiledevice.cpp libkmobiledevice_la_LDFLAGS = $(all_libraries) -no-undefined -avoid-version -libkmobiledevice_la_LIBADD = $(LIB_TDEABC) $(LIB_LOCKDEV) ../libkcal/libkcal.la +libkmobiledevice_la_LIBADD = $(LIB_TDEABC) ../libkcal/libkcal.la # the KDE application's client library to KMobile libkmobileclient_la_SOURCES = kmobileclient.cpp diff --git a/kmobile/configure.in.in b/kmobile/configure.in.in deleted file mode 100644 index cf47242d..00000000 --- a/kmobile/configure.in.in +++ /dev/null @@ -1,16 +0,0 @@ -DO_NOT_COMPILE="$DO_NOT_COMPILE kmobile" - -AC_CHECK_HEADERS(baudboy.h,,, -[ -#include -#include -#include -#define inline __inline__ -]) -AC_CHECK_HEADERS(lockdev.h) -AC_CHECK_LIB(lockdev, dev_lock, [ LIB_LOCKDEV="-llockdev" ]) -dnl We don't need liblockdev if we have baudboy working -if [[ -n "$HAVE_BAUDBOY_H" ]]; then - LIB_LOCKDEV="" -fi -AC_SUBST(LIB_LOCKDEV) diff --git a/kmobile/kmobiledevice.cpp b/kmobile/kmobiledevice.cpp index c408d72d..abf75057 100644 --- a/kmobile/kmobiledevice.cpp +++ b/kmobile/kmobiledevice.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include @@ -48,8 +48,7 @@ */ KMobileDevice::KMobileDevice(TQObject *obj, const char *name, const TQStringList &args) - : KLibFactory(obj,name), - m_config(0L), d(0L) + : KLibFactory(obj,name), m_config(0L), d(0L), m_fd(-1) { setClassType(Unclassified); setCapabilities(hasNothing); @@ -348,103 +347,33 @@ void KMobileDevice::special( const TQByteArray & ) // and no one is in this group. Only the binary /usr/sbin/lockdev is // owned by this group and has the setgid flag set. This binary is called // in ttylock etc ... -# include -# include -# include # include # include -#else -# ifdef HAVE_LOCKDEV_H -// Library shipped with newer RedHat and Debian(?) distributions. -// Use this if bauddev is not available. -# include -# include -# include -# else -// If lockdev.h is also unavailable do locking -// like described in the serial HOWTO. -# include -# include -# include -# include -# include -# include -# endif #endif -#define DEVICE_LOCK_PATH_PREFIX "/var/lock/LCK.." - bool KMobileDevice::lockDevice(const TQString &device, TQString &err_reason) { #ifdef HAVE_BAUDBOY_H - return ttylock(device.local8bit()) == EXIT_SUCCESS; + return ttylock(device.local8Bit()) == EXIT_SUCCESS; #else -# ifdef HAVE_LOCKDEV_H - return !dev_lock(device.local8bit()); -# else - int pid = -1; - TQStringList all = TQStringList::split('/', device); - if (!all.count()) { - err_reason = i18n("Invalid device (%1)").arg(device); - return false; - } - TQString lockName = DEVICE_LOCK_PATH_PREFIX + all[all.count()-1]; - TQFile file(lockName); - if (file.exists() && file.open(IO_ReadOnly)) { - if (file.size() == 0) { - err_reason = i18n("Unable to read lockfile %s. Please check for reason and " - "remove the lockfile by hand.").arg(lockName); - PRINT_DEBUG << err_reason; - return false; - } - if (file.size() == 4 && sizeof(int)==4) { - file.readLine((char *)(&pid), 4); /* Kermit-style lockfile */ - } else { - TQTextStream ts(&file); - ts >> pid; /* Ascii lockfile */ - } - file.close(); - - if (pid > 0 && kill((pid_t)pid, 0) < 0 && errno == ESRCH) { - PRINT_DEBUG << TQString("Lockfile %1 is stale. Overriding it..\n").arg(lockName); - sleep(1); - if (!file.remove()) { - PRINT_DEBUG << TQString("Overriding failed, please check the permissions\n"); - PRINT_DEBUG << TQString("Cannot lock device %1\n").arg(device); - err_reason = i18n("Lockfile %1 is stale. Please check permissions.").arg(lockName); + if (m_fd != -1) + return true; + + TQCString dev = TQFile::encodeName(device.local8Bit()); + const char *fdev = dev.data(); + if ((m_fd = open(fdev, O_RDWR)) == -1) + { + PRINT_DEBUG << i18n("Unable to open device '%1'. " + "Please check that you have sufficient permissions.").arg(fdev); return false; } - } else { - err_reason = i18n("Device %1 already locked.").arg(device); - return false; - } - } - - /* Try to create a new file, with 0644 mode */ - int fd = open(lockName.local8Bit(), O_CREAT | O_EXCL | O_WRONLY, 0644); - if (fd == -1) { - if (errno == EEXIST) - err_reason = i18n("Device %1 seems to be locked by unknown process.").arg(device); - else if (errno == EACCES) - err_reason = i18n("Please check permission on lock directory."); - else if (errno == ENOENT) - err_reason = i18n("Cannot create lockfile %1. Please check for existence of path.").arg(lockName); - else - err_reason = i18n("Could not create lockfile %1. Error-Code is %2.").arg(lockName).arg(errno); - return false; - } - TQString lockText; - lockText = TQString("%1 kmobile\n").arg(getpid(),10); - write(fd, lockText.utf8(), lockText.utf8().length()); - close(fd); - - PRINT_DEBUG << TQString("%1: Device %2 locked with lockfile %3.\n") - .arg(deviceName()).arg(device).arg(lockName); - - err_reason = TQString(); - + if (flock(m_fd, LOCK_EX)) + { + // Locking failed + PRINT_DEBUG << i18n("Unable to lock device '%1'.").arg(fdev); + return false; + } return true; -# endif #endif } @@ -453,17 +382,12 @@ bool KMobileDevice::unlockDevice(const TQString &device) #ifdef HAVE_BAUDBOY_H return ttyunlock(device.local8bit()) == EXIT_SUCCESS; #else -# ifdef HAVE_LOCKDEV_H - return 0 <= dev_unlock(device.local8bit(), getpid()); -# else - TQStringList all = TQStringList::split('/', device); - if (!all.count()) return false; - TQString lockName = DEVICE_LOCK_PATH_PREFIX + all[all.count()-1]; - TQFile file(lockName); - if (!file.exists()) - return true; - return file.remove(); -# endif + if (m_fd != -1) + { + flock(m_fd, LOCK_UN); + } + close(m_fd); + m_fd = -1; #endif } diff --git a/kmobile/kmobiledevice.h b/kmobile/kmobiledevice.h index d4469d35..78fc50e8 100644 --- a/kmobile/kmobiledevice.h +++ b/kmobile/kmobiledevice.h @@ -65,7 +65,7 @@ class TDEConfig; class KDE_EXPORT KMobileDevice : public KLibFactory { Q_OBJECT - + friend class KMobileView; public: @@ -497,6 +497,7 @@ protected: TQString m_connectionName; // e.g. "IRDA", "USB", "Cable", "gnokii", "gammu", ... int m_caps; // see enum Capabilities bool m_connected; + int m_fd; // file descriptor used for locking/unlocking devices private: class KMobileDevicePrivate *d;