From f9e70e9ff0cd9ccc3e644453fbea988eda75c8cd Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Mon, 14 May 2012 16:57:46 +0200 Subject: [PATCH] cec: serial port locking on linux --- configure.ac | 3 ++- debian/control | 4 +-- src/lib/platform/posix/os-types.h | 4 +++ src/lib/platform/posix/serialport.cpp | 35 +++++++++++++++++++++++++++ src/lib/platform/sockets/serialport.h | 3 +++ 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index f8b8701..b8d6031 100644 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,8 @@ has_libudev="yes" case "${host}" in *-*-linux*) PKG_CHECK_MODULES([UDEV],[libudev],,[has_libudev="no"]; AC_MSG_WARN("library 'udev' is missing - adapter detection will not be available")) - LIBS+=" -lrt" + AC_CHECK_HEADER(lockdev.h,, AC_MSG_ERROR("required library 'liblockdev' is missing")) + LIBS+=" -lrt -llockdev" ;; *-apple-darwin*) has_libudev="no"; diff --git a/debian/control b/debian/control index 5709349..fa8b761 100644 --- a/debian/control +++ b/debian/control @@ -2,13 +2,13 @@ Source: libcec Section: video Priority: extra Maintainer: Lars Op den Kamp -Build-Depends: debhelper (>= 7), libudev-dev, mime-support, locales, gawk, autotools-dev, autoconf, automake, pkg-config +Build-Depends: debhelper (>= 7), libudev-dev, mime-support, locales, gawk, autotools-dev, autoconf, automake, pkg-config, liblockdev1-dev Standards-Version: 3.8.3 Homepage: http://www.pulse-eight.net/ Package: libcec Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: ${shlibs:Depends}, ${misc:Depends}, liblockdev1 Description: Pulse-Eight CEC adapter control library With this library you can access your Pulse-Eight CEC adapter. diff --git a/src/lib/platform/posix/os-types.h b/src/lib/platform/posix/os-types.h index b89b9cc..a365635 100644 --- a/src/lib/platform/posix/os-types.h +++ b/src/lib/platform/posix/os-types.h @@ -44,6 +44,10 @@ #include #include +extern "C" { +#include +} + #define LIBTYPE #define DECLSPEC diff --git a/src/lib/platform/posix/serialport.cpp b/src/lib/platform/posix/serialport.cpp index cefc212..2237b65 100644 --- a/src/lib/platform/posix/serialport.cpp +++ b/src/lib/platform/posix/serialport.cpp @@ -47,20 +47,33 @@ #ifndef IUCLC #define IUCLC 0 #endif +#else +#include #endif + using namespace std; using namespace PLATFORM; void CSerialSocket::Close(void) { if (IsOpen()) + { SocketClose(m_socket); + #if !defined(__APPLE__) && !defined(__FreeBSD__) + dev_unlock(m_strName.c_str(), m_lockPid); + #endif + } } void CSerialSocket::Shutdown(void) { if (IsOpen()) + { SocketClose(m_socket); + #if !defined(__APPLE__) && !defined(__FreeBSD__) + dev_unlock(m_strName.c_str(), m_lockPid); + #endif + } } ssize_t CSerialSocket::Write(void* data, size_t len) @@ -78,32 +91,51 @@ bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */) { iTimeoutMs = 0; if (IsOpen()) + { + m_iError = EINVAL; return false; + } if (m_iDatabits != SERIAL_DATA_BITS_FIVE && m_iDatabits != SERIAL_DATA_BITS_SIX && m_iDatabits != SERIAL_DATA_BITS_SEVEN && m_iDatabits != SERIAL_DATA_BITS_EIGHT) { m_strError = "Databits has to be between 5 and 8"; + m_iError = EINVAL; return false; } if (m_iStopbits != SERIAL_STOP_BITS_ONE && m_iStopbits != SERIAL_STOP_BITS_TWO) { m_strError = "Stopbits has to be 1 or 2"; + m_iError = EINVAL; return false; } if (m_iParity != SERIAL_PARITY_NONE && m_iParity != SERIAL_PARITY_EVEN && m_iParity != SERIAL_PARITY_ODD) { m_strError = "Parity has to be none, even or odd"; + m_iError = EINVAL; + return false; + } + + #if !defined(__APPLE__) && !defined(__FreeBSD__) + m_lockPid = dev_lock(m_strName.c_str()); + if (m_lockPid != 0) + { + m_strError = "Couldn't lock the serial port"; + m_iError = EBUSY; return false; } + #endif m_socket = open(m_strName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); if (m_socket == INVALID_SERIAL_SOCKET_VALUE) { m_strError = strerror(errno); + #if !defined(__APPLE__) && !defined(__FreeBSD__) + m_lockPid = dev_unlock(m_strName.c_str(), m_lockPid); + #endif return false; } @@ -150,6 +182,9 @@ bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */) if (tcsetattr(m_socket, TCSANOW, &m_options) != 0) { m_strError = strerror(errno); + #if !defined(__APPLE__) && !defined(__FreeBSD__) + m_lockPid = dev_unlock(m_strName.c_str(), m_lockPid); + #endif return false; } diff --git a/src/lib/platform/sockets/serialport.h b/src/lib/platform/sockets/serialport.h index eed05a0..a16e3ca 100644 --- a/src/lib/platform/sockets/serialport.h +++ b/src/lib/platform/sockets/serialport.h @@ -73,6 +73,8 @@ namespace PLATFORM CCommonSocket(INVALID_SERIAL_SOCKET_VALUE, strName), #ifdef __WINDOWS__ m_iCurrentReadTimeout(MAXDWORD), + #else + m_lockPid(0), #endif m_bIsOpen(false), m_iBaudrate(iBaudrate), @@ -99,6 +101,7 @@ namespace PLATFORM protected: #ifndef __WINDOWS__ struct termios m_options; + pid_t m_lockPid; #else bool SetTimeouts(serial_socket_t socket, int* iError, DWORD iTimeoutMs); DWORD m_iCurrentReadTimeout; -- 2.34.1