Fixed FTBFS in Debian/Ubuntu due to missing liblockdev1-dev package. Device locking is now done through 'flock()'

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
(cherry picked from commit 3ed5f6bda5)
r14.0.x
Michele Calgaro 9 years ago
parent b80f9a2251
commit 3811fc1773

@ -54,17 +54,6 @@ if( BUILD_KMOBILE )
endif( ) 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) ) if( WITH_GNOKII AND (BUILD_KADDRESSBOOK OR BUILD_KMOBILE) )
pkg_search_module( GNOKII gnokii ) pkg_search_module( GNOKII gnokii )
if( NOT GNOKII_FOUND ) if( NOT GNOKII_FOUND )

@ -39,9 +39,6 @@
// kaddressbook // kaddressbook
#cmakedefine TDEPIM_NEW_DISTRLISTS 1 #cmakedefine TDEPIM_NEW_DISTRLISTS 1
// kandy
#cmakedefine HAVE_LOCKDEV 1
// karm // karm
#cmakedefine HAVE_LIBXSS 1 #cmakedefine HAVE_LIBXSS 1

@ -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)

@ -47,7 +47,7 @@ tde_add_executable( kandy AUTOMOC
atcommand.cpp commanditem.cpp mobilegui_base.ui mobilegui.cpp atcommand.cpp commanditem.cpp mobilegui_base.ui mobilegui.cpp
commandscheduler.cpp commandset.cpp kandyprefs.kcfgc commandscheduler.cpp commandset.cpp kandyprefs.kcfgc
kandyprefsdialog.cpp mobilemain.cpp kandyprefsdialog.cpp mobilemain.cpp
LINK tdepim-shared ${LOCKDEV_LIBRARY} LINK tdepim-shared
DESTINATION ${BIN_INSTALL_DIR} DESTINATION ${BIN_INSTALL_DIR}
) )

@ -3,7 +3,7 @@ bin_PROGRAMS = kandy kandy_client
INCLUDES = -I$(top_srcdir) $(all_includes) INCLUDES = -I$(top_srcdir) $(all_includes)
kandy_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor 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 \ kandy_SOURCES = main.cpp kandy.cpp \
cmdpropertiesdialog_base.ui cmdpropertiesdialog.cpp \ cmdpropertiesdialog_base.ui cmdpropertiesdialog.cpp \
kandyview.cpp \ kandyview.cpp \

@ -30,6 +30,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/file.h>
#include <fcntl.h> #include <fcntl.h>
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
@ -75,7 +76,7 @@
Modem::Modem( KandyPrefs *kprefs, TQObject *parent, const char *name ) : Modem::Modem( KandyPrefs *kprefs, TQObject *parent, const char *name ) :
TQObject(parent, name) TQObject(parent, name), fd(-1)
{ {
mOpen = false; mOpen = false;
@ -185,12 +186,10 @@ bool Modem::open()
{ {
struct termios tty; struct termios tty;
close(); close();
if ( !lockDevice() ) if (fd == -1)
return false; {
TQCString dev = TQFile::encodeName( (*prefs).serialDevice() ); TQCString dev = TQFile::encodeName( (*prefs).serialDevice() );
const char *fdev = dev.data(); const char *fdev = dev.data();
if ( ( fd = ::open( fdev, O_RDWR | O_NOCTTY | O_NONBLOCK ) ) == -1 ) { if ( ( fd = ::open( fdev, O_RDWR | O_NOCTTY | O_NONBLOCK ) ) == -1 ) {
@ -199,14 +198,19 @@ bool Modem::open()
.arg( fdev ) ); .arg( fdev ) );
return false; return false;
} }
}
if ( !lockDevice() )
return false;
tcflush( fd, TCIOFLUSH ); tcflush( fd, TCIOFLUSH );
if ( tcgetattr( fd, &init_tty ) == -1 ) { if ( tcgetattr( fd, &init_tty ) == -1 ) {
int errnumber = errno; int errnumber = errno;
emit errorMessage( i18n( "Communication setup failed (tcgetattr code: %1)" ) emit errorMessage( i18n( "Communication setup failed (tcgetattr code: %1)" )
.arg(strerror(errnumber)) ); .arg(strerror(errnumber)) );
unlockDevice();
::close( fd ); ::close( fd );
fd = 0; fd = -1;
return false; return false;
} }
@ -221,8 +225,9 @@ bool Modem::open()
if ( tcsetattr( fd, TCSANOW, &tty ) == -1 ) { if ( tcsetattr( fd, TCSANOW, &tty ) == -1 ) {
emit errorMessage( i18n( "tcsetattr() failed." ) ); emit errorMessage( i18n( "tcsetattr() failed." ) );
unlockDevice();
::close( fd ); ::close( fd );
fd = 0; fd = -1;
return false; return false;
} }
@ -244,127 +249,56 @@ void Modem::close()
delete sn; delete sn;
sn = 0; sn = 0;
unlockDevice();
if ( fd ) { if ( fd ) {
tcflush( fd, TCIOFLUSH ); tcflush( fd, TCIOFLUSH );
tcsetattr( fd, TCSANOW, &init_tty ); tcsetattr( fd, TCSANOW, &init_tty );
::close( fd ); ::close( fd );
fd = 0; fd = -1;
} }
xreset(); xreset();
unlockDevice();
mOpen = false; mOpen = false;
} }
void Modem::flush() void Modem::flush()
{ {
if ( fd ) { if ( fd != -1) {
tcflush( fd, TCIOFLUSH ); tcflush( fd, TCIOFLUSH );
bufpos = 0; bufpos = 0;
} }
} }
#ifdef HAVE_LOCKDEV
#include <lockdev.h>
#endif
bool Modem::lockDevice() bool Modem::lockDevice()
{ {
if (is_locked) if (is_locked)
return true; return true;
#ifdef HAVE_LOCKDEV if (flock(fd, LOCK_EX))
is_locked = !dev_lock( (*prefs).serialDevice().local8Bit() ); {
if (!is_locked) // Locking failed
emit errorMessage( i18n( "Unable to lock device '%1'." ).arg( is_locked = false;
(*prefs).serialDevice() )); 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;
} }
else
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; is_locked = true;
}
return true; return is_locked;
#endif
} }
void Modem::unlockDevice() void Modem::unlockDevice()
{ {
#ifdef HAVE_LOCKDEV if (fd != -1 && is_locked)
dev_unlock( (*prefs).serialDevice().local8Bit(), getpid() ); {
#else flock(fd, LOCK_UN);
if ( is_locked ) {
TQStringList pathList = TQStringList::split( "/", (*prefs).serialDevice() );
TQFile::remove( (*prefs).lockDirectory() + "/LCK.." + pathList.last() );
is_locked = false; is_locked = false;
} }
#endif
} }
@ -373,7 +307,7 @@ bool Modem::dsrOn()
int flags; int flags;
if ( !fd ) { if ( fd == -1 ) {
#ifdef MODEM_DEBUG #ifdef MODEM_DEBUG
fprintf( stderr, "Modem: dsrOn(): File not open.\n" ); fprintf( stderr, "Modem: dsrOn(): File not open.\n" );
#endif #endif
@ -396,7 +330,7 @@ bool Modem::ctsOn()
int flags; int flags;
if ( !fd ) { if ( fd == -1 ) {
#ifdef MODEM_DEBUG #ifdef MODEM_DEBUG
fprintf( stderr, "Modem: ctsOn(): File not open.\n" ); fprintf( stderr, "Modem: ctsOn(): File not open.\n" );
#endif #endif
@ -640,7 +574,7 @@ void Modem::init()
{ {
is_locked = false; is_locked = false;
fd = 0; fd = -1;
sn = 0; sn = 0;
cspeed = B38400; cspeed = B38400;

@ -86,7 +86,7 @@ HINTS FOR DRIVER DEVELOPERS:
all calls to your driver, so you always will have a clean state all calls to your driver, so you always will have a clean state
- use lockDevice("/dev/ttyS1") and unlockDevice("/dev/ttyS1") to - use lockDevice("/dev/ttyS1") and unlockDevice("/dev/ttyS1") to
lock those devices system-wide (creates /var/lock/LCK..<devname> files), lock those devices system-wide,
and to prevent other applications to access the same physical ports/devices and to prevent other applications to access the same physical ports/devices
- use the helper functions createDirEntry() and createFileEntry() to - use the helper functions createDirEntry() and createFileEntry() to

@ -21,7 +21,7 @@ noinst_HEADERS = kmobile.h kmobileview.h kmobileitem.h pref.h
# the low-level devices driver library # the low-level devices driver library
libkmobiledevice_la_SOURCES = kmobiledevice.cpp libkmobiledevice_la_SOURCES = kmobiledevice.cpp
libkmobiledevice_la_LDFLAGS = $(all_libraries) -no-undefined -avoid-version 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 # the KDE application's client library to KMobile
libkmobileclient_la_SOURCES = kmobileclient.cpp libkmobileclient_la_SOURCES = kmobileclient.cpp

@ -1,16 +0,0 @@
DO_NOT_COMPILE="$DO_NOT_COMPILE kmobile"
AC_CHECK_HEADERS(baudboy.h,,,
[
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#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)

@ -19,7 +19,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/file.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
@ -48,8 +48,7 @@
*/ */
KMobileDevice::KMobileDevice(TQObject *obj, const char *name, const TQStringList &args) KMobileDevice::KMobileDevice(TQObject *obj, const char *name, const TQStringList &args)
: KLibFactory(obj,name), : KLibFactory(obj,name), m_config(0L), d(0L), m_fd(-1)
m_config(0L), d(0L)
{ {
setClassType(Unclassified); setClassType(Unclassified);
setCapabilities(hasNothing); setCapabilities(hasNothing);
@ -348,104 +347,34 @@ void KMobileDevice::special( const TQByteArray & )
// and no one is in this group. Only the binary /usr/sbin/lockdev is // 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 // owned by this group and has the setgid flag set. This binary is called
// in ttylock etc ... // in ttylock etc ...
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <baudboy.h> # include <baudboy.h>
# include <cstdlib> # include <cstdlib>
#else
# ifdef HAVE_LOCKDEV_H
// Library shipped with newer RedHat and Debian(?) distributions.
// Use this if bauddev is not available.
# include <lockdev.h>
# include <sys/types.h>
# include <unistd.h>
# else
// If lockdev.h is also unavailable do locking
// like described in the serial HOWTO.
# include <sys/types.h>
# include <sys/stat.h>
# include <unistd.h>
# include <tqfile.h>
# include <signal.h>
# include <errno.h>
# endif
#endif #endif
#define DEVICE_LOCK_PATH_PREFIX "/var/lock/LCK.."
bool KMobileDevice::lockDevice(const TQString &device, TQString &err_reason) bool KMobileDevice::lockDevice(const TQString &device, TQString &err_reason)
{ {
#ifdef HAVE_BAUDBOY_H #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 #else
int pid = -1; if (m_fd != -1)
TQStringList all = TQStringList::split('/', device); return true;
if (!all.count()) {
err_reason = i18n("Invalid device (%1)").arg(device); TQCString dev = TQFile::encodeName(device.local8Bit());
return false; const char *fdev = dev.data();
} if ((m_fd = open(fdev, O_RDWR)) == -1)
TQString lockName = DEVICE_LOCK_PATH_PREFIX + all[all.count()-1]; {
TQFile file(lockName); PRINT_DEBUG << i18n("Unable to open device '%1'. "
if (file.exists() && file.open(IO_ReadOnly)) { "Please check that you have sufficient permissions.").arg(fdev);
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);
return false;
}
} else {
err_reason = i18n("Device %1 already locked.").arg(device);
return false; return false;
} }
} if (flock(m_fd, LOCK_EX))
{
/* Try to create a new file, with 0644 mode */ // Locking failed
int fd = open(lockName.local8Bit(), O_CREAT | O_EXCL | O_WRONLY, 0644); PRINT_DEBUG << i18n("Unable to lock device '%1'.").arg(fdev);
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; 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();
return true; return true;
#endif #endif
#endif
} }
bool KMobileDevice::unlockDevice(const TQString &device) bool KMobileDevice::unlockDevice(const TQString &device)
@ -453,17 +382,12 @@ bool KMobileDevice::unlockDevice(const TQString &device)
#ifdef HAVE_BAUDBOY_H #ifdef HAVE_BAUDBOY_H
return ttyunlock(device.local8bit()) == EXIT_SUCCESS; return ttyunlock(device.local8bit()) == EXIT_SUCCESS;
#else #else
# ifdef HAVE_LOCKDEV_H if (m_fd != -1)
return 0 <= dev_unlock(device.local8bit(), getpid()); {
# else flock(m_fd, LOCK_UN);
TQStringList all = TQStringList::split('/', device); }
if (!all.count()) return false; close(m_fd);
TQString lockName = DEVICE_LOCK_PATH_PREFIX + all[all.count()-1]; m_fd = -1;
TQFile file(lockName);
if (!file.exists())
return true;
return file.remove();
# endif
#endif #endif
} }

@ -497,6 +497,7 @@ protected:
TQString m_connectionName; // e.g. "IRDA", "USB", "Cable", "gnokii", "gammu", ... TQString m_connectionName; // e.g. "IRDA", "USB", "Cable", "gnokii", "gammu", ...
int m_caps; // see enum Capabilities int m_caps; // see enum Capabilities
bool m_connected; bool m_connected;
int m_fd; // file descriptor used for locking/unlocking devices
private: private:
class KMobileDevicePrivate *d; class KMobileDevicePrivate *d;

Loading…
Cancel
Save