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");
    64         if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
    65                 log_trace(
"tty_reset(): tcsetattr() failed");
    74         struct termios options;
    76         if (tcgetattr(fd, &options) == -1) {
    77                 log_trace(
"%s: tcgetattr() failed", __func__);
    82                 options.c_cflag |= CRTSCTS;
    84                 options.c_cflag &= ~CRTSCTS;
    85         if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
    86                 log_trace(
"%s: tcsetattr() failed", __func__);
    97         if (ioctl(fd, TIOCMGET, &sts) < 0) {
    98                 log_trace(
"%s: ioctl(TIOCMGET) failed", __func__);
   102         if (((sts & TIOCM_DTR) == 0) && enable) {
   104         } 
else if ((!enable) && (sts & TIOCM_DTR)) {
   112         if (ioctl(fd, cmd, &sts) < 0) {
   113                 log_trace(
"%s: ioctl(TIOCMBI(S|C)) failed", __func__);
   122         struct termios options;
   125 #if defined __linux__   126         int use_custom_divisor = 0;
   127         struct serial_struct serinfo;
   224 #if defined __linux__   226                 use_custom_divisor = 1;
   229                 log_trace(
"tty_setbaud(): bad baud rate %d", baud);
   233         if (tcgetattr(fd, &options) == -1) {
   234                 log_trace(
"tty_setbaud(): tcgetattr() failed");
   238         (void)cfsetispeed(&options, speed);
   239         (void)cfsetospeed(&options, speed);
   240         if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
   241                 log_trace(
"tty_setbaud(): tcsetattr() failed");
   245 #if defined __linux__   246         if (use_custom_divisor) {
   247                 if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
   248                         log_trace(
"tty_setbaud(): TIOCGSERIAL failed");
   252                 serinfo.flags &= ~ASYNC_SPD_MASK;
   253                 serinfo.flags |= ASYNC_SPD_CUST;
   254                 serinfo.custom_divisor = serinfo.baud_base / baud;
   255                 if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0) {
   256                         log_trace(
"tty_setbaud(): TIOCSSERIAL failed");
   267         struct termios options;
   284                 log_trace(
"tty_setcsize(): bad csize rate %d", csize);
   287         if (tcgetattr(fd, &options) == -1) {
   288                 log_trace(
"tty_setcsize(): tcgetattr() failed");
   292         options.c_cflag &= ~CSIZE;
   293         options.c_cflag |= size;
   294         if (tcsetattr(fd, TCSAFLUSH, &options) == -1) {
   295                 log_trace(
"tty_setcsize(): tcsetattr() failed");
   304         char filename[FILENAME_MAX + 1];
   305         char symlink[FILENAME_MAX + 1];
   306         char cwd[FILENAME_MAX + 1];
   313         strcpy(filename, LIRC_LOCKDIR 
"/LCK..");
   315         last = strrchr(name, 
'/');
   321         if (strlen(filename) + strlen(s) > FILENAME_MAX) {
   322                 log_error(
"invalid filename \"%s%s\"", filename, s);
   327 tty_create_lock_retry:
   328         len = snprintf(
id, 10 + 1 + 1, 
"%10d\n", getpid());
   330                 log_error(
"invalid pid \"%d\"", getpid());
   333         lock = open(filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
   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                                         log_warn(
"detected stale lockfile %s", filename);
   346                                         if (unlink(filename) != -1) {
   348                                                 goto tty_create_lock_retry;
   351                                                           "could not remove stale lockfile");
   355                                 log_error(
"%s is locked by PID %d", name, otherpid);
   357                                 log_error(
"invalid lockfile %s encountered", filename);
   363         if (write(lock, 
id, len) != len) {
   366                 if (unlink(filename) == -1)
   371         if (close(lock) == -1) {
   373                 if (unlink(filename) == -1)
   379         len = readlink(name, symlink, FILENAME_MAX);
   381                 if (errno != EINVAL) {  
   383                         if (unlink(filename) == -1) {
   394                         char dirname[FILENAME_MAX + 1];
   396                         if (getcwd(cwd, FILENAME_MAX) == NULL) {
   398                                 if (unlink(filename) == -1) {
   400                                                   "could not delete file \"%s\"",
   407                         strcpy(dirname, name);
   408                         dirname[strlen(name) - strlen(last)] = 0;
   409                         if (chdir(dirname) == -1) {
   411                                           "chdir() to \"%s\" failed", dirname);
   412                                 if (unlink(filename) == -1) {
   414                                                   "could not delete file \"%s\"",
   422                         if (unlink(filename) == -1) {
   424                                           "could not delete file \"%s\"", filename);
   430                         if (chdir(cwd) == -1) {
   432                                 if (unlink(filename) == -1) {
   434                                                   "could not delete file \"%s\"",
   451         char id[20] = { 
'\0' };
   452         char filename[FILENAME_MAX + 1];
   456         dp = opendir(LIRC_LOCKDIR);
   458                 while ((ep = readdir(dp))) {
   459                         if (strcmp(ep->d_name, 
".") == 0 || strcmp(ep->d_name, 
"..") == 0) {
   463                         strcpy(filename, LIRC_LOCKDIR 
"/");
   464                         if (strlen(filename) + strlen(ep->d_name) > FILENAME_MAX) {
   468                         strcat(filename, ep->d_name);
   469                         if (strstr(filename, 
"LCK..") == NULL) {
   470                                 log_debug(
"Ignoring non-LCK.. logfile %s",
   475                         lock = open(filename, O_RDONLY);
   480                         len = read(lock, 
id, 
sizeof(
id) - 1);
   486                         pid = strtol(
id, NULL, 10);
   487                         if (pid == LONG_MIN || pid == LONG_MAX || pid == 0) {
   488                                 log_debug(
"Can't parse lockfile %s (ignored)",
   493                         if (pid == getpid()) {
   494                                 if (unlink(filename) == -1) {
   496                                                   "could not delete file \"%s\"",
   505                 log_error(
"could not open directory \"" LIRC_LOCKDIR 
"\"");
   515         mask = rts ? TIOCM_RTS : 0;
   516         mask |= dtr ? TIOCM_DTR : 0;
   517         if (ioctl(fd, TIOCMBIS, &mask) == -1) {
   529         mask = rts ? TIOCM_RTS : 0;
   530         mask |= dtr ? TIOCM_DTR : 0;
   531         if (ioctl(fd, TIOCMBIC, &mask) == -1) {
   533                 log_trace(
"tty_clear(): ioctl() failed");
   541         if (write(fd, &byte, 1) != 1) {
   542                 log_trace(
"tty_write(): write() failed");
   559         struct pollfd pfd = {.fd = fd, .events = POLLIN, .revents = 0};
   562         ret = curl_poll(&pfd, 1, 1000); 
   566         } 
else if (ret != 1) {
   570         if (read(fd, byte, 1) != 1) {
   585         log_trace(
"sent: A%u D%01x reply: A%u D%01x", (((
unsigned int)(
unsigned char)byte) & 0xf0) >> 4,
   586                   ((
unsigned int)(
unsigned char)byte) & 0x0f, (((
unsigned int)(
unsigned char)reply) & 0xf0) >> 4,
   587                   ((
unsigned int)(
unsigned char)reply) & 0x0f);
 int tty_setrtscts(int fd, int enable)
Set/clear CTS control line. 
#define log_debug(fmt,...)
Log a debug message. 
#define log_perror_debug(fmt,...)
perror wrapper logging with level LIRC_DEBUG. 
int tty_setdtr(int fd, int enable)
Set/clear DTR control line. 
int tty_delete_lock(void)
Delete any legacy lock(s) owned by this process. 
#define log_warn(fmt,...)
Log a warning message. 
logchannel_t
Log channels used to filter messages. 
int tty_reset(int fd)
Set the cfmakeraw termio options. 
int tty_create_lock(const char *name)
Creates a lock file of the type /var/local/LCK. 
#define log_error(fmt,...)
Log an error message. 
int tty_write(int fd, char byte)
Write a single byte to serial device. 
int tty_clear(int fd, int rts, int dtr)
Clear RTS and DTR control lines. 
int tty_setcsize(int fd, int csize)
Set the character size. 
#define log_trace(fmt,...)
Log a trace message. 
#define log_perror_err(fmt,...)
perror wrapper logging with level LIRC_ERROR. 
int tty_write_echo(int fd, char byte)
Write a single byte and check the echo from remote party. 
int tty_read(int fd, char *byte)
Read a single byte from serial device. 
int tty_setbaud(int fd, int baud)
Set the speed a. 
#define log_perror_warn(fmt,...)
perror wrapper logging with level LIRC_WARNING. 
int tty_set(int fd, int rts, int dtr)
Set RTS and DTR control lines.