buses/uart: Use 'lockf()' for serial locking

Using this standard Linux mechanism to lock serial ports has the advantage that if the process is killed the lock is automatically released.

Before a lock was simulated using the custom termios 'c_iflag' value 0x80000000, which has the disadvantage, other than being non-standard, that if the process is killed before closing the serial port, it would appear as locked and require manual cleanup of the flag.

Signed-off-by: Giovanni Giacobbi <giovanni@giacobbi.net>
This commit is contained in:
Giovanni Giacobbi 2021-04-13 12:13:20 +00:00
parent 2b5ad9ce0b
commit 7ff5d11127
No known key found for this signature in database
GPG Key ID: 63A98B68F17EE59B

View File

@ -92,9 +92,6 @@ const char *serial_ports_device_radix[] = { "ttyUSB", "ttyS", "ttyACM", "ttyAMA"
# define FIONREAD TIOCINQ # define FIONREAD TIOCINQ
#endif #endif
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
# define CCLAIMED 0x80000000
struct serial_port_unix { struct serial_port_unix {
int fd; // Serial port file descriptor int fd; // Serial port file descriptor
struct termios termios_backup; // Terminal info before using the port struct termios termios_backup; // Terminal info before using the port
@ -124,7 +121,7 @@ uart_open(const char *pcPortName)
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
} }
// Make sure the port is not claimed already // Make sure the port is not claimed already
if (sp->termios_backup.c_iflag & CCLAIMED) { if (lockf(sp->fd, F_TLOCK, 0)) {
uart_close_ext(sp, false); uart_close_ext(sp, false);
return CLAIMED_SERIAL_PORT; return CLAIMED_SERIAL_PORT;
} }
@ -132,7 +129,7 @@ uart_open(const char *pcPortName)
sp->termios_new = sp->termios_backup; sp->termios_new = sp->termios_backup;
sp->termios_new.c_cflag = CS8 | CLOCAL | CREAD; sp->termios_new.c_cflag = CS8 | CLOCAL | CREAD;
sp->termios_new.c_iflag = CCLAIMED | IGNPAR; sp->termios_new.c_iflag = IGNPAR;
sp->termios_new.c_oflag = 0; sp->termios_new.c_oflag = 0;
sp->termios_new.c_lflag = 0; sp->termios_new.c_lflag = 0;
@ -282,6 +279,7 @@ uart_close_ext(const serial_port sp, const bool restore_termios)
if (UART_DATA(sp)->fd >= 0) { if (UART_DATA(sp)->fd >= 0) {
if (restore_termios) if (restore_termios)
tcsetattr(UART_DATA(sp)->fd, TCSANOW, &UART_DATA(sp)->termios_backup); tcsetattr(UART_DATA(sp)->fd, TCSANOW, &UART_DATA(sp)->termios_backup);
lockf(UART_DATA(sp)->fd, F_ULOCK, 0);
close(UART_DATA(sp)->fd); close(UART_DATA(sp)->fd);
} }
free(sp); free(sp);