22 #define LIRC_LOCKDIR "/var/lock/lockdev"
39 #include <sys/types.h>
41 #include <sys/ioctl.h>
44 #include <linux/serial.h>
48 #include "lirc/lirc_log.h"
54 struct termios options;
56 if (tcgetattr(fd, &options) == -1) {
57 log_trace(
"tty_reset(): tcgetattr() failed");
62 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
63 log_trace(
"tty_reset(): tcsetattr() failed");
72 struct termios options;
74 if (tcgetattr(fd, &options) == -1) {
75 log_trace(
"%s: tcgetattr() failed", __func__);
80 options.c_cflag |= CRTSCTS;
82 options.c_cflag &= ~CRTSCTS;
83 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
84 log_trace(
"%s: tcsetattr() failed", __func__);
95 if (ioctl(fd, TIOCMGET, &sts) < 0) {
96 log_trace(
"%s: ioctl(TIOCMGET) failed", __func__);
100 if (((sts & TIOCM_DTR) == 0) && enable) {
102 }
else if ((!enable) && (sts & TIOCM_DTR)) {
110 if (ioctl(fd, cmd, &sts) < 0) {
111 log_trace(
"%s: ioctl(TIOCMBI(S|C)) failed", __func__);
120 struct termios options;
123 #if defined __linux__
124 int use_custom_divisor = 0;
125 struct serial_struct serinfo;
222 #if defined __linux__
224 use_custom_divisor = 1;
227 log_trace(
"tty_setbaud(): bad baud rate %d", baud);
231 if (tcgetattr(fd, &options) == -1) {
232 log_trace(
"tty_setbaud(): tcgetattr() failed");
236 (void)cfsetispeed(&options, speed);
237 (void)cfsetospeed(&options, speed);
238 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
239 log_trace(
"tty_setbaud(): tcsetattr() failed");
243 #if defined __linux__
244 if (use_custom_divisor) {
245 if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
246 log_trace(
"tty_setbaud(): TIOCGSERIAL failed");
250 serinfo.flags &= ~ASYNC_SPD_MASK;
251 serinfo.flags |= ASYNC_SPD_CUST;
252 serinfo.custom_divisor = serinfo.baud_base / baud;
253 if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0) {
254 log_trace(
"tty_setbaud(): TIOCSSERIAL failed");
265 struct termios options;
282 log_trace(
"tty_setcsize(): bad csize rate %d", csize);
285 if (tcgetattr(fd, &options) == -1) {
286 log_trace(
"tty_setcsize(): tcgetattr() failed");
290 options.c_cflag &= ~CSIZE;
291 options.c_cflag |= size;
292 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
293 log_trace(
"tty_setcsize(): tcsetattr() failed");
302 char filename[FILENAME_MAX + 1];
303 char symlink[FILENAME_MAX + 1];
304 char cwd[FILENAME_MAX + 1];
311 strcpy(filename, LIRC_LOCKDIR
"/LCK..");
313 last = strrchr(name,
'/');
319 if (strlen(filename) + strlen(s) > FILENAME_MAX) {
320 log_error(
"invalid filename \"%s%s\"", filename, s);
325 tty_create_lock_retry:
326 len = snprintf(
id, 10 + 1 + 1,
"%10d\n", getpid());
328 log_error(
"invalid pid \"%d\"", getpid());
331 lock = open(filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
334 lock = open(filename, O_RDONLY);
339 if (read(lock,
id, 10 + 1) == 10 + 1 && read(lock,
id, 1) == 0
340 && sscanf(
id,
"%d\n", &otherpid) > 0) {
341 if (kill(otherpid, 0) == -1 && errno == ESRCH) {
342 log_warn(
"detected stale lockfile %s", filename);
344 if (unlink(filename) != -1) {
346 goto tty_create_lock_retry;
349 "could not remove stale lockfile");
353 log_error(
"%s is locked by PID %d", name, otherpid);
355 log_error(
"invalid lockfile %s encountered", filename);
361 if (write(lock,
id, len) != len) {
364 if (unlink(filename) == -1)
369 if (close(lock) == -1) {
371 if (unlink(filename) == -1)
377 len = readlink(name, symlink, FILENAME_MAX);
379 if (errno != EINVAL) {
381 if (unlink(filename) == -1) {
392 char dirname[FILENAME_MAX + 1];
394 if (getcwd(cwd, FILENAME_MAX) == NULL) {
396 if (unlink(filename) == -1) {
398 "could not delete file \"%s\"",
405 strcpy(dirname, name);
406 dirname[strlen(name) - strlen(last)] = 0;
407 if (chdir(dirname) == -1) {
409 "chdir() to \"%s\" failed", dirname);
410 if (unlink(filename) == -1) {
412 "could not delete file \"%s\"",
420 if (unlink(filename) == -1) {
422 "could not delete file \"%s\"", filename);
428 if (chdir(cwd) == -1) {
430 if (unlink(filename) == -1) {
432 "could not delete file \"%s\"",
449 char id[20] = {
'\0' };
450 char filename[FILENAME_MAX + 1];
454 dp = opendir(LIRC_LOCKDIR);
456 while ((ep = readdir(dp))) {
457 if (strcmp(ep->d_name,
".") == 0 || strcmp(ep->d_name,
"..") == 0) {
461 strcpy(filename, LIRC_LOCKDIR
"/");
462 if (strlen(filename) + strlen(ep->d_name) > FILENAME_MAX) {
466 strcat(filename, ep->d_name);
467 if (strstr(filename,
"LCK..") == NULL) {
468 log_debug(
"Ignoring non-LCK.. logfile %s",
473 lock = open(filename, O_RDONLY);
478 len = read(lock,
id,
sizeof(
id) - 1);
484 pid = strtol(
id, NULL, 10);
485 if (pid == LONG_MIN || pid == LONG_MAX || pid == 0) {
486 log_debug(
"Can't parse lockfile %s (ignored)",
491 if (pid == getpid()) {
492 if (unlink(filename) == -1) {
494 "could not delete file \"%s\"",
503 log_error(
"could not open directory \"" LIRC_LOCKDIR
"\"");
513 mask = rts ? TIOCM_RTS : 0;
514 mask |= dtr ? TIOCM_DTR : 0;
515 if (ioctl(fd, TIOCMBIS, &mask) == -1) {
527 mask = rts ? TIOCM_RTS : 0;
528 mask |= dtr ? TIOCM_DTR : 0;
529 if (ioctl(fd, TIOCMBIC, &mask) == -1) {
531 log_trace(
"tty_clear(): ioctl() failed");
539 if (write(fd, &byte, 1) != 1) {
540 log_trace(
"tty_write(): write() failed");
557 struct pollfd pfd = {.fd = fd, .events = POLLIN, .revents = 0};
560 ret = poll(&pfd, 1, 1000);
564 }
else if (ret != 1) {
568 if (read(fd, byte, 1) != 1) {
583 log_trace(
"sent: A%u D%01x reply: A%u D%01x", (((
unsigned int)(
unsigned char)byte) & 0xf0) >> 4,
584 ((
unsigned int)(
unsigned char)byte) & 0x0f, (((
unsigned int)(
unsigned char)reply) & 0xf0) >> 4,
585 ((
unsigned int)(
unsigned char)reply) & 0x0f);
int tty_setrtscts(int fd, int enable)
#define log_debug(fmt,...)
#define log_perror_debug(fmt,...)
int tty_setdtr(int fd, int enable)
int tty_delete_lock(void)
#define log_warn(fmt,...)
int tty_create_lock(const char *name)
#define log_error(fmt,...)
int tty_write(int fd, char byte)
int tty_clear(int fd, int rts, int dtr)
int tty_setcsize(int fd, int csize)
#define log_trace(fmt,...)
#define log_perror_err(fmt,...)
int tty_write_echo(int fd, char byte)
int tty_read(int fd, char *byte)
int tty_setbaud(int fd, int baud)
#define log_perror_warn(fmt,...)
int tty_set(int fd, int rts, int dtr)