summaryrefslogtreecommitdiff
path: root/libgammu/device/serial/ser_unx.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgammu/device/serial/ser_unx.c')
-rw-r--r--libgammu/device/serial/ser_unx.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/libgammu/device/serial/ser_unx.c b/libgammu/device/serial/ser_unx.c
index 300639b..6755bf1 100644
--- a/libgammu/device/serial/ser_unx.c
+++ b/libgammu/device/serial/ser_unx.c
@@ -26,6 +26,8 @@
#include <termios.h>
#include <errno.h>
#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
#ifdef HAVE_I_SETSIG
#include <stropts.h>
#endif
@@ -38,8 +40,6 @@
#endif
#ifdef __NetBSD__
-# define FNONBLOCK O_NONBLOCK
-
#ifndef B57600
# define B57600 0010001
#endif
@@ -158,6 +158,9 @@ static GSM_Error serial_close(GSM_StateMachine *s)
/* Restores old settings */
tcsetattr(d->hPhone, TCSANOW, &d->old_settings);
+ /* Remove advisory lock */
+ flock(d->hPhone, LOCK_UN);
+
/* Closes device */
close(d->hPhone);
@@ -188,6 +191,7 @@ static GSM_Error serial_open (GSM_StateMachine *s)
#ifdef TIOCEXCL
/* open() calls from other applications shall fail now */
+ /* this works only with CAP_SYS_ADMIN on Linux though */
ioctl(d->hPhone, TIOCEXCL, (char *) 0);
#endif
#ifdef HAVE_I_SETSIG
@@ -195,6 +199,14 @@ static GSM_Error serial_open (GSM_StateMachine *s)
ioctl(d->hPhone, I_SETSIG, (char *) 0);
#endif
+ /* Try advisory locks */
+ if (flock(d->hPhone, LOCK_EX | LOCK_NB) != 0) {
+ if (errno == EWOULDBLOCK) {
+ GSM_OSErrorInfo(s, "failed to lock device, probably opened by other process");
+ return ERR_DEVICEOPENERROR;
+ }
+ }
+
if (tcgetattr(d->hPhone, &d->old_settings) == -1) {
close(d->hPhone);
GSM_OSErrorInfo(s,"tcgetattr in serial_open");