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_write(int fd, char byte)
Write a single byte to serial device.
int tty_set(int fd, int rts, int dtr)
Set RTS and DTR control lines.
int tty_reset(int fd)
Set the cfmakeraw termio options.
int tty_setbaud(int fd, int baud)
Set the speed a.
int tty_read(int fd, char *byte)
Read a single byte from serial device.
int tty_setdtr(int fd, int enable)
Set/clear DTR control line.
int tty_write_echo(int fd, char byte)
Write a single byte and check the echo from remote party.
int tty_delete_lock(void)
Delete any legacy lock(s) owned by this process.
int tty_create_lock(const char *name)
Creates a lock file of the type /var/local/LCK.
int tty_clear(int fd, int rts, int dtr)
Clear RTS and DTR control lines.
int tty_setrtscts(int fd, int enable)
Set/clear CTS control line.
int tty_setcsize(int fd, int csize)
Set the character size.
#define log_trace(fmt,...)
Log a trace message.
#define log_debug(fmt,...)
Log a debug message.
#define log_perror_debug(fmt,...)
perror wrapper logging with level LIRC_DEBUG.
#define log_perror_err(fmt,...)
perror wrapper logging with level LIRC_ERROR.
#define log_error(fmt,...)
Log an error message.
#define log_perror_warn(fmt,...)
perror wrapper logging with level LIRC_WARNING.
logchannel_t
Log channels used to filter messages.
#define log_warn(fmt,...)
Log a warning message.