23 #define LIRC_LOCKDIR "/var/lock/lockdev"
38 #include <sys/types.h>
40 #include <sys/ioctl.h>
42 #if defined (__linux__)
43 #include <linux/serial.h>
47 #include "lirc/lirc_log.h"
51 struct termios options;
53 if (tcgetattr(fd, &options) == -1) {
54 LOGPRINTF(1,
"tty_reset(): tcgetattr() failed");
59 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
60 LOGPRINTF(1,
"tty_reset(): tcsetattr() failed");
69 struct termios options;
71 if (tcgetattr(fd, &options) == -1) {
72 LOGPRINTF(1,
"%s: tcgetattr() failed", __FUNCTION__);
77 options.c_cflag |= CRTSCTS;
79 options.c_cflag &= ~CRTSCTS;
81 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
82 LOGPRINTF(1,
"%s: tcsetattr() failed", __FUNCTION__);
93 if (ioctl(fd, TIOCMGET, &sts) < 0) {
94 LOGPRINTF(1,
"%s: ioctl(TIOCMGET) failed", __FUNCTION__);
98 if (((sts & TIOCM_DTR) == 0) && enable) {
100 }
else if ((!enable) && (sts & TIOCM_DTR)) {
109 if (ioctl(fd, cmd, &sts) < 0) {
110 LOGPRINTF(1,
"%s: ioctl(TIOCMBI(S|C)) failed", __FUNCTION__);
119 struct termios options;
121 #if defined (__linux__)
122 int use_custom_divisor = 0;
123 struct serial_struct serinfo;
220 #if defined (__linux__)
222 use_custom_divisor = 1;
225 LOGPRINTF(1,
"tty_setbaud(): bad baud rate %d", baud);
229 if (tcgetattr(fd, &options) == -1) {
230 LOGPRINTF(1,
"tty_setbaud(): tcgetattr() failed");
234 (void)cfsetispeed(&options, speed);
235 (void)cfsetospeed(&options, speed);
236 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
237 LOGPRINTF(1,
"tty_setbaud(): tcsetattr() failed");
241 #if defined (__linux__)
242 if (use_custom_divisor) {
243 if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
244 LOGPRINTF(1,
"tty_setbaud(): TIOCGSERIAL failed");
248 serinfo.flags &= ~ASYNC_SPD_MASK;
249 serinfo.flags |= ASYNC_SPD_CUST;
250 serinfo.custom_divisor = serinfo.baud_base / baud;
251 if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0) {
252 LOGPRINTF(1,
"tty_setbaud(): TIOCSSERIAL failed");
263 struct termios options;
280 LOGPRINTF(1,
"tty_setcsize(): bad csize rate %d", csize);
283 if (tcgetattr(fd, &options) == -1) {
284 LOGPRINTF(1,
"tty_setcsize(): tcgetattr() failed");
288 options.c_cflag &= ~CSIZE;
289 options.c_cflag |= size;
290 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
291 LOGPRINTF(1,
"tty_setcsize(): tcsetattr() failed");
306 char filename[FILENAME_MAX + 1];
307 char symlink[FILENAME_MAX + 1];
308 char cwd[FILENAME_MAX + 1];
309 const char *last, *s;
314 strcpy(filename, LIRC_LOCKDIR
"/LCK..");
316 last = strrchr(name,
'/');
322 if (strlen(filename) + strlen(s) > FILENAME_MAX) {
323 logprintf(LIRC_ERROR,
"invalid filename \"%s%s\"", filename, s);
328 tty_create_lock_retry:
329 if ((len = snprintf(
id, 10 + 1 + 1,
"%10d\n", getpid())) == -1) {
330 logprintf(LIRC_ERROR,
"invalid pid \"%d\"", getpid());
333 lock = open(filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
335 logperror(LIRC_ERROR,
"could not create lock file \"%s\"", filename);
336 lock = open(filename, O_RDONLY);
341 if (read(lock,
id, 10 + 1) == 10 + 1 && read(lock,
id, 1) == 0
342 && sscanf(
id,
"%d\n", &otherpid) > 0) {
343 if (kill(otherpid, 0) == -1 && errno == ESRCH) {
344 logprintf(LIRC_WARNING,
"detected stale lockfile %s", filename);
346 if (unlink(filename) != -1) {
347 logprintf(LIRC_WARNING,
"stale lockfile removed");
348 goto tty_create_lock_retry;
351 "could not remove stale lockfile");
355 logprintf(LIRC_ERROR,
"%s is locked by PID %d", name, otherpid);
358 logprintf(LIRC_ERROR,
"invalid lockfile %s encountered", filename);
364 if (write(lock,
id, len) != len) {
365 logperror(LIRC_ERROR,
"could not write pid to lock file");
367 if (unlink(filename) == -1) {
368 logperror(LIRC_ERROR,
"could not delete file \"%s\"", filename);
373 if (close(lock) == -1) {
374 logperror(LIRC_ERROR,
"could not close lock file");
375 if (unlink(filename) == -1) {
376 logperror(LIRC_ERROR,
"could not delete file \"%s\"", filename);
382 if ((len = readlink(name, symlink, FILENAME_MAX)) == -1) {
383 if (errno != EINVAL) {
384 logperror(LIRC_ERROR,
"readlink() failed for \"%s\"", name);
385 if (unlink(filename) == -1) {
387 "could not delete file \"%s\"", filename);
396 char dirname[FILENAME_MAX + 1];
398 if (getcwd(cwd, FILENAME_MAX) == NULL) {
399 logperror(LIRC_ERROR,
"getcwd() failed");
400 if (unlink(filename) == -1) {
402 "could not delete file \"%s\"",
409 strcpy(dirname, name);
410 dirname[strlen(name) - strlen(last)] = 0;
411 if (chdir(dirname) == -1) {
413 "chdir() to \"%s\" failed", dirname);
414 if (unlink(filename) == -1) {
416 "could not delete file \"%s\"",
424 if (unlink(filename) == -1) {
426 "could not delete file \"%s\"", filename);
432 if (chdir(cwd) == -1) {
433 logperror(LIRC_ERROR,
"chdir() to \"%s\" failed", cwd);
434 if (unlink(filename) == -1) {
436 "could not delete file \"%s\"",
458 char id[20] = {
'\0'};
459 char filename[FILENAME_MAX + 1];
463 dp = opendir(LIRC_LOCKDIR);
465 while ((ep = readdir(dp))) {
466 if (strcmp(ep->d_name,
".") == 0 || strcmp(ep->d_name,
"..") == 0) {
470 strcpy(filename, LIRC_LOCKDIR
"/");
471 if (strlen(filename) + strlen(ep->d_name) > FILENAME_MAX) {
475 strcat(filename, ep->d_name);
476 if (strstr(filename,
"LCK..") == NULL) {
477 logprintf(LIRC_DEBUG,
478 "Ignoring non-LCK.. logfile %s",
483 lock = open(filename, O_RDONLY);
488 len = read(lock,
id,
sizeof(
id) - 1);
494 pid = strtol(
id, NULL, 10);
495 if (pid == LONG_MIN || pid == LONG_MAX || pid == 0) {
496 logprintf(LIRC_DEBUG,
497 "Can't parse lockfile %s (ignored)",
502 if (pid == getpid()) {
503 if (unlink(filename) == -1) {
505 "could not delete file \"%s\"",
514 logprintf(LIRC_ERROR,
"could not open directory \"" LIRC_LOCKDIR
"\"");
524 mask = rts ? TIOCM_RTS : 0;
525 mask |= dtr ? TIOCM_DTR : 0;
526 if (ioctl(fd, TIOCMBIS, &mask) == -1) {
527 LOGPRINTF(1,
"tty_set(): ioctl() failed");
538 mask = rts ? TIOCM_RTS : 0;
539 mask |= dtr ? TIOCM_DTR : 0;
540 if (ioctl(fd, TIOCMBIC, &mask) == -1) {
541 LOGPRINTF(1,
"tty_clear(): ioctl() failed");
550 if (write(fd, &byte, 1) != 1) {
551 LOGPRINTF(1,
"tty_write(): write() failed");
577 ret = select(fd + 1, &fds, NULL, NULL, &tv);
579 logprintf(LIRC_ERROR,
"tty_read(): timeout");
581 }
else if (ret != 1) {
582 LOGPRINTF(1,
"tty_read(): select() failed");
586 if (read(fd, byte, 1) != 1) {
587 LOGPRINTF(1,
"tty_read(): read() failed");
602 LOGPRINTF(1,
"sent: A%u D%01x reply: A%u D%01x", (((
unsigned int)(
unsigned char)byte) & 0xf0) >> 4,
603 ((
unsigned int)(
unsigned char)byte) & 0x0f, (((
unsigned int)(
unsigned char)reply) & 0xf0) >> 4,
604 ((
unsigned int)(
unsigned char)reply) & 0x0f);
606 logprintf(LIRC_ERROR,
"Command mismatch.");
int tty_setrtscts(int fd, int enable)
int tty_setdtr(int fd, int enable)
int tty_delete_lock(void)
int tty_create_lock(const char *name)
int tty_write(int fd, char byte)
int tty_clear(int fd, int rts, int dtr)
#define LOGPERROR(level, s)
int tty_setcsize(int fd, int csize)
int tty_write_echo(int fd, char byte)
int tty_read(int fd, char *byte)
int tty_setbaud(int fd, int baud)
#define LOGPRINTF(level, fmt, args...)
void logperror(loglevel_t prio, const char *fmt,...)
int tty_set(int fd, int rts, int dtr)