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>
pull/21/head
Michele Calgaro 8 years ago
parent c2ad4a056c
commit 3ed5f6bda5

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

@ -39,9 +39,6 @@
// kaddressbook
#cmakedefine TDEPIM_NEW_DISTRLISTS 1
// kandy
#cmakedefine HAVE_LOCKDEV 1
// karm
#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
commandscheduler.cpp commandset.cpp kandyprefs.kcfgc
kandyprefsdialog.cpp mobilemain.cpp
LINK tdepim-shared ${LOCKDEV_LIBRARY}
LINK tdepim-shared
DESTINATION ${BIN_INSTALL_DIR}
)

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

@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
@ -75,7 +76,7 @@
Modem::Modem( KandyPrefs *kprefs, TQObject *parent, const char *name ) :
TQObject(parent, name)
TQObject(parent, name), fd(-1)
{
mOpen = false;
@ -185,28 +186,31 @@ bool Modem::open()
{
struct termios tty;
close();
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;
}
}
if ( !lockDevice() )
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 ) );
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 <lockdev.h>
#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;

@ -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..<devname> 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

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

@ -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/stat.h>
#include <sys/types.h>
#include <sys/file.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
@ -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 <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <baudboy.h>
# 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
#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
}

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

Loading…
Cancel
Save