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" 49 #include "lirc/curl_poll.h" 56 struct termios options;
58 if (tcgetattr(fd, &options) == -1) {
59 log_trace(
"tty_reset(): tcgetattr() failed");
65 options.c_iflag &= ~(IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IGNPAR);
66 options.c_iflag |= IGNBRK;
67 options.c_oflag &= ~OPOST;
68 options.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|TOSTOP|PENDIN);
69 options.c_cflag &= ~(CSIZE|PARENB);
70 options.c_cflag |= CS8|CREAD;
71 options.c_cc[VMIN] = 1;
72 options.c_cc[VTIME] = 0;
76 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
77 log_trace(
"tty_reset(): tcsetattr() failed");
86 struct termios options;
88 if (tcgetattr(fd, &options) == -1) {
89 log_trace(
"%s: tcgetattr() failed", __func__);
94 options.c_cflag |= CRTSCTS;
96 options.c_cflag &= ~CRTSCTS;
97 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
98 log_trace(
"%s: tcsetattr() failed", __func__);
109 if (ioctl(fd, TIOCMGET, &sts) < 0) {
110 log_trace(
"%s: ioctl(TIOCMGET) failed", __func__);
114 if (((sts & TIOCM_DTR) == 0) && enable) {
116 }
else if ((!enable) && (sts & TIOCM_DTR)) {
124 if (ioctl(fd, cmd, &sts) < 0) {
125 log_trace(
"%s: ioctl(TIOCMBI(S|C)) failed", __func__);
134 struct termios options;
137 #if defined __linux__ 138 int use_custom_divisor = 0;
139 struct serial_struct serinfo;
236 #if defined __linux__ 238 use_custom_divisor = 1;
241 log_trace(
"tty_setbaud(): bad baud rate %d", baud);
245 if (tcgetattr(fd, &options) == -1) {
246 log_trace(
"tty_setbaud(): tcgetattr() failed");
250 (void)cfsetispeed(&options, speed);
251 (void)cfsetospeed(&options, speed);
252 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
253 log_trace(
"tty_setbaud(): tcsetattr() failed");
257 #if defined __linux__ 258 if (use_custom_divisor) {
259 if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
260 log_trace(
"tty_setbaud(): TIOCGSERIAL failed");
264 serinfo.flags &= ~ASYNC_SPD_MASK;
265 serinfo.flags |= ASYNC_SPD_CUST;
266 serinfo.custom_divisor = serinfo.baud_base / baud;
267 if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0) {
268 log_trace(
"tty_setbaud(): TIOCSSERIAL failed");
279 struct termios options;
296 log_trace(
"tty_setcsize(): bad csize rate %d", csize);
299 if (tcgetattr(fd, &options) == -1) {
300 log_trace(
"tty_setcsize(): tcgetattr() failed");
304 options.c_cflag &= ~CSIZE;
305 options.c_cflag |= size;
306 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
307 log_trace(
"tty_setcsize(): tcsetattr() failed");
316 char filename[FILENAME_MAX + 1];
317 char symlink[FILENAME_MAX + 1];
318 char cwd[FILENAME_MAX + 1];
325 strcpy(filename, LIRC_LOCKDIR
"/LCK..");
327 last = strrchr(name,
'/');
333 if (strlen(filename) + strlen(s) > FILENAME_MAX) {
334 log_error(
"invalid filename \"%s%s\"", filename, s);
339 tty_create_lock_retry:
340 len = snprintf(
id, 10 + 1 + 1,
"%10d\n", getpid());
342 log_error(
"invalid pid \"%d\"", getpid());
345 lock = open(filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
348 lock = open(filename, O_RDONLY);
353 if (read(lock,
id, 10 + 1) == 10 + 1 && read(lock,
id, 1) == 0
354 && sscanf(
id,
"%d\n", &otherpid) > 0) {
355 if (kill(otherpid, 0) == -1 && errno == ESRCH) {
356 log_warn(
"detected stale lockfile %s", filename);
358 if (unlink(filename) != -1) {
360 goto tty_create_lock_retry;
363 "could not remove stale lockfile");
367 log_error(
"%s is locked by PID %d", name, otherpid);
369 log_error(
"invalid lockfile %s encountered", filename);
375 if (write(lock,
id, len) != len) {
378 if (unlink(filename) == -1)
383 if (close(lock) == -1) {
385 if (unlink(filename) == -1)
391 len = readlink(name, symlink, FILENAME_MAX);
393 if (errno != EINVAL) {
395 if (unlink(filename) == -1) {
406 char dirname[FILENAME_MAX + 1];
408 if (getcwd(cwd, FILENAME_MAX) == NULL) {
410 if (unlink(filename) == -1) {
412 "could not delete file \"%s\"",
419 strcpy(dirname, name);
420 dirname[strlen(name) - strlen(last)] = 0;
421 if (chdir(dirname) == -1) {
423 "chdir() to \"%s\" failed", dirname);
424 if (unlink(filename) == -1) {
426 "could not delete file \"%s\"",
434 if (unlink(filename) == -1) {
436 "could not delete file \"%s\"", filename);
442 if (chdir(cwd) == -1) {
444 if (unlink(filename) == -1) {
446 "could not delete file \"%s\"",
463 char id[20] = {
'\0' };
464 char filename[FILENAME_MAX + 1];
468 dp = opendir(LIRC_LOCKDIR);
470 while ((ep = readdir(dp))) {
471 if (strcmp(ep->d_name,
".") == 0 || strcmp(ep->d_name,
"..") == 0) {
475 strcpy(filename, LIRC_LOCKDIR
"/");
476 if (strlen(filename) + strlen(ep->d_name) > FILENAME_MAX) {
480 strcat(filename, ep->d_name);
481 if (strstr(filename,
"LCK..") == NULL) {
482 log_debug(
"Ignoring non-LCK.. logfile %s",
487 lock = open(filename, O_RDONLY);
492 len = read(lock,
id,
sizeof(
id) - 1);
498 pid = strtol(
id, NULL, 10);
499 if (pid == LONG_MIN || pid == LONG_MAX || pid == 0) {
500 log_debug(
"Can't parse lockfile %s (ignored)",
505 if (pid == getpid()) {
506 if (unlink(filename) == -1) {
508 "could not delete file \"%s\"",
517 log_error(
"could not open directory \"" LIRC_LOCKDIR
"\"");
527 mask = rts ? TIOCM_RTS : 0;
528 mask |= dtr ? TIOCM_DTR : 0;
529 if (ioctl(fd, TIOCMBIS, &mask) == -1) {
541 mask = rts ? TIOCM_RTS : 0;
542 mask |= dtr ? TIOCM_DTR : 0;
543 if (ioctl(fd, TIOCMBIC, &mask) == -1) {
545 log_trace(
"tty_clear(): ioctl() failed");
553 if (write(fd, &byte, 1) != 1) {
554 log_trace(
"tty_write(): write() failed");
571 struct pollfd pfd = {.fd = fd, .events = POLLIN, .revents = 0};
574 ret = curl_poll(&pfd, 1, 1000);
578 }
else if (ret != 1) {
582 if (read(fd, byte, 1) != 1) {
597 log_trace(
"sent: A%u D%01x reply: A%u D%01x", (((
unsigned int)(
unsigned char)byte) & 0xf0) >> 4,
598 ((
unsigned int)(
unsigned char)byte) & 0x0f, (((
unsigned int)(
unsigned char)reply) & 0xf0) >> 4,
599 ((
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)