22 #define LIRC_LOCKDIR "/var/lock/lockdev"
38 #include <sys/types.h>
40 #include <sys/ioctl.h>
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", __func__);
77 options.c_cflag |= CRTSCTS;
79 options.c_cflag &= ~CRTSCTS;
80 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
81 LOGPRINTF(1,
"%s: tcsetattr() failed", __func__);
92 if (ioctl(fd, TIOCMGET, &sts) < 0) {
93 LOGPRINTF(1,
"%s: ioctl(TIOCMGET) failed", __func__);
97 if (((sts & TIOCM_DTR) == 0) && enable) {
99 }
else if ((!enable) && (sts & TIOCM_DTR)) {
107 if (ioctl(fd, cmd, &sts) < 0) {
108 LOGPRINTF(1,
"%s: ioctl(TIOCMBI(S|C)) failed", __func__);
117 struct termios options;
120 #if defined __linux__
121 int use_custom_divisor = 0;
122 struct serial_struct serinfo;
219 #if defined __linux__
221 use_custom_divisor = 1;
224 LOGPRINTF(1,
"tty_setbaud(): bad baud rate %d", baud);
228 if (tcgetattr(fd, &options) == -1) {
229 LOGPRINTF(1,
"tty_setbaud(): tcgetattr() failed");
233 (void)cfsetispeed(&options, speed);
234 (void)cfsetospeed(&options, speed);
235 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
236 LOGPRINTF(1,
"tty_setbaud(): tcsetattr() failed");
240 #if defined __linux__
241 if (use_custom_divisor) {
242 if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
243 LOGPRINTF(1,
"tty_setbaud(): TIOCGSERIAL failed");
247 serinfo.flags &= ~ASYNC_SPD_MASK;
248 serinfo.flags |= ASYNC_SPD_CUST;
249 serinfo.custom_divisor = serinfo.baud_base / baud;
250 if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0) {
251 LOGPRINTF(1,
"tty_setbaud(): TIOCSSERIAL failed");
262 struct termios options;
279 LOGPRINTF(1,
"tty_setcsize(): bad csize rate %d", csize);
282 if (tcgetattr(fd, &options) == -1) {
283 LOGPRINTF(1,
"tty_setcsize(): tcgetattr() failed");
287 options.c_cflag &= ~CSIZE;
288 options.c_cflag |= size;
289 if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
290 LOGPRINTF(1,
"tty_setcsize(): tcsetattr() failed");
299 char filename[FILENAME_MAX + 1];
300 char symlink[FILENAME_MAX + 1];
301 char cwd[FILENAME_MAX + 1];
308 strcpy(filename, LIRC_LOCKDIR
"/LCK..");
310 last = strrchr(name,
'/');
316 if (strlen(filename) + strlen(s) > FILENAME_MAX) {
317 logprintf(LIRC_ERROR,
"invalid filename \"%s%s\"", filename, s);
322 tty_create_lock_retry:
323 len = snprintf(
id, 10 + 1 + 1,
"%10d\n", getpid());
325 logprintf(LIRC_ERROR,
"invalid pid \"%d\"", getpid());
328 lock = open(filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
330 logperror(LIRC_ERROR,
"could not create lock file \"%s\"", filename);
331 lock = open(filename, O_RDONLY);
336 if (read(lock,
id, 10 + 1) == 10 + 1 && read(lock,
id, 1) == 0
337 && sscanf(
id,
"%d\n", &otherpid) > 0) {
338 if (kill(otherpid, 0) == -1 && errno == ESRCH) {
339 logprintf(LIRC_WARNING,
"detected stale lockfile %s", filename);
341 if (unlink(filename) != -1) {
342 logprintf(LIRC_WARNING,
"stale lockfile removed");
343 goto tty_create_lock_retry;
346 "could not remove stale lockfile");
350 logprintf(LIRC_ERROR,
"%s is locked by PID %d", name, otherpid);
352 logprintf(LIRC_ERROR,
"invalid lockfile %s encountered", filename);
358 if (write(lock,
id, len) != len) {
359 logperror(LIRC_ERROR,
"could not write pid to lock file");
361 if (unlink(filename) == -1)
362 logperror(LIRC_ERROR,
"could not delete file \"%s\"", filename);
366 if (close(lock) == -1) {
367 logperror(LIRC_ERROR,
"could not close lock file");
368 if (unlink(filename) == -1)
369 logperror(LIRC_ERROR,
"could not delete file \"%s\"", filename);
374 len = readlink(name, symlink, FILENAME_MAX);
376 if (errno != EINVAL) {
377 logperror(LIRC_ERROR,
"readlink() failed for \"%s\"", name);
378 if (unlink(filename) == -1) {
380 "could not delete file \"%s\"", filename);
389 char dirname[FILENAME_MAX + 1];
391 if (getcwd(cwd, FILENAME_MAX) == NULL) {
392 logperror(LIRC_ERROR,
"getcwd() failed");
393 if (unlink(filename) == -1) {
395 "could not delete file \"%s\"",
402 strcpy(dirname, name);
403 dirname[strlen(name) - strlen(last)] = 0;
404 if (chdir(dirname) == -1) {
406 "chdir() to \"%s\" failed", dirname);
407 if (unlink(filename) == -1) {
409 "could not delete file \"%s\"",
417 if (unlink(filename) == -1) {
419 "could not delete file \"%s\"", filename);
425 if (chdir(cwd) == -1) {
426 logperror(LIRC_ERROR,
"chdir() to \"%s\" failed", cwd);
427 if (unlink(filename) == -1) {
429 "could not delete file \"%s\"",
446 char id[20] = {
'\0' };
447 char filename[FILENAME_MAX + 1];
451 dp = opendir(LIRC_LOCKDIR);
453 while ((ep = readdir(dp))) {
454 if (strcmp(ep->d_name,
".") == 0 || strcmp(ep->d_name,
"..") == 0) {
458 strcpy(filename, LIRC_LOCKDIR
"/");
459 if (strlen(filename) + strlen(ep->d_name) > FILENAME_MAX) {
463 strcat(filename, ep->d_name);
464 if (strstr(filename,
"LCK..") == NULL) {
465 logprintf(LIRC_DEBUG,
466 "Ignoring non-LCK.. logfile %s",
471 lock = open(filename, O_RDONLY);
476 len = read(lock,
id,
sizeof(
id) - 1);
482 pid = strtol(
id, NULL, 10);
483 if (pid == LONG_MIN || pid == LONG_MAX || pid == 0) {
484 logprintf(LIRC_DEBUG,
485 "Can't parse lockfile %s (ignored)",
490 if (pid == getpid()) {
491 if (unlink(filename) == -1) {
493 "could not delete file \"%s\"",
502 logprintf(LIRC_ERROR,
"could not open directory \"" LIRC_LOCKDIR
"\"");
512 mask = rts ? TIOCM_RTS : 0;
513 mask |= dtr ? TIOCM_DTR : 0;
514 if (ioctl(fd, TIOCMBIS, &mask) == -1) {
515 LOGPRINTF(1,
"tty_set(): ioctl() failed");
526 mask = rts ? TIOCM_RTS : 0;
527 mask |= dtr ? TIOCM_DTR : 0;
528 if (ioctl(fd, TIOCMBIC, &mask) == -1) {
529 LOGPRINTF(1,
"tty_clear(): ioctl() failed");
538 if (write(fd, &byte, 1) != 1) {
539 LOGPRINTF(1,
"tty_write(): write() failed");
556 struct pollfd pfd = {.fd = fd, .events = POLLIN, .revents = 0};
559 ret = poll(&pfd, 1, 1000);
561 logprintf(LIRC_ERROR,
"tty_read(): timeout");
563 }
else if (ret != 1) {
564 LOGPERROR(1,
"tty_read(): poll() failed");
567 if (read(fd, byte, 1) != 1) {
568 LOGPERROR(1,
"tty_read(): read() failed");
582 LOGPRINTF(1,
"sent: A%u D%01x reply: A%u D%01x", (((
unsigned int)(
unsigned char)byte) & 0xf0) >> 4,
583 ((
unsigned int)(
unsigned char)byte) & 0x0f, (((
unsigned int)(
unsigned char)reply) & 0xf0) >> 4,
584 ((
unsigned int)(
unsigned char)reply) & 0x0f);
586 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)