diff --git a/ttynvt.c b/ttynvt.c index feeb7ec..df8b1ed 100644 --- a/ttynvt.c +++ b/ttynvt.c @@ -61,16 +61,17 @@ typedef struct { struct pollfd fds[3]; - struct termios tio; - unsigned char mcr; - char net_buf[NET_BUF_SIZE]; size_t net_cnt; char tmp_buf[TMP_BUF_SIZE]; + struct termios tio; + int cmcr; int epipe; - volatile sig_atomic_t error; - volatile sig_atomic_t pollin; + + volatile int smcr; + volatile int error; + volatile int pollin; tn_ctx_t *tn; } ttynvt_t; @@ -200,12 +201,7 @@ static void *_read_net(void *arg) else break; } - else if (tty->fds[FD_NET].revents & (POLLERR | POLLHUP | POLLNVAL)) - { - _log(LOG_ERR, "net io error\n"); - break; - } - else if (tty->fds[FD_NET].revents & POLLIN) + if (tty->fds[FD_NET].revents & POLLIN) { res = read(tty->fds[FD_NET].fd, tty->net_buf + tty->net_cnt, NET_BUF_SIZE - tty->net_cnt); @@ -334,25 +330,24 @@ static int _srv_read(void *cctx, int timeout) static void _modem_status_cb(void *cctx, int status) { ttynvt_t *tty = cctx; + int mcr = 0; DBG("MCR: DSR=%c CTS=%c RI=%c CD=%c\n", status & TNS_STATE_DSR ? '1' : '0', status & TNS_STATE_CTS ? '1' : '0', status & TNS_STATE_RI ? '1' : '0', status & TNS_STATE_CD ? '1' : '0'); - pthread_mutex_lock(&tty->tty_lock); - - tty->mcr &= ~(TIOCM_CD | TIOCM_RI | TIOCM_CTS | TIOCM_DSR); - if (status & TNS_STATE_CD) - tty->mcr |= TIOCM_CD; + mcr |= TIOCM_CD; if (status & TNS_STATE_RI) - tty->mcr |= TIOCM_RI; + mcr |= TIOCM_RI; if (status & TNS_STATE_CTS) - tty->mcr |= TIOCM_CTS; + mcr |= TIOCM_CTS; if (status & TNS_STATE_DSR) - tty->mcr |= TIOCM_DSR; + mcr |= TIOCM_DSR; + pthread_mutex_lock(&tty->tty_lock); + tty->smcr = mcr; pthread_mutex_unlock(&tty->tty_lock); } @@ -615,6 +610,7 @@ ttynvt_ioctl(fuse_req_t req, int cmd, void *arg, ttynvt_t *tty = (ttynvt_t *) (uintptr_t) info->fh; struct winsize ws; unsigned int tiocm = 0; + int mcr; static struct termios tio = { .c_cflag = B115200 | CS8 | PARODD | CREAD | CLOCAL, }; @@ -677,15 +673,12 @@ ttynvt_ioctl(fuse_req_t req, int cmd, void *arg, if (tio.c_cflag & CRTSCTS) telnet_rfc2217_ctl(tty->tn, TNS_CTL_CTSRTS); -#if 1 - pthread_mutex_lock(&tty->tty_lock); - if (!(tty->mcr & TIOCM_DTR) && speed != B0) + if (!(tty->cmcr & TIOCM_DTR) && speed != B0) { - tty->mcr |= TIOCM_DTR; + tty->cmcr |= TIOCM_DTR; telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_ON); } - pthread_mutex_unlock(&tty->tty_lock); -#endif + DBG("termios: %u%c%u%u %cCTSRTS %cCREAD %cHUPCL %cCLOCAL\n", baudrate(speed), pstr[par], csize, sb, tio.c_cflag & CRTSCTS ? '+' : '-', @@ -747,63 +740,58 @@ ttynvt_ioctl(fuse_req_t req, int cmd, void *arg, case TIOCMGET: CHECK_BUF_OUT(sizeof(int)); pthread_mutex_lock(&tty->tty_lock); - fuse_reply_ioctl(req, 0, &tty->mcr, sizeof(int)); + mcr = tty->cmcr | tty->smcr; pthread_mutex_unlock(&tty->tty_lock); + fuse_reply_ioctl(req, 0, &mcr, sizeof(int)); break; case TIOCMBIS: CHECK_BUF_IN(sizeof(int)); tiocm = *(unsigned int *)in_buf; fuse_reply_ioctl(req, 0, 0, 0); DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm); - pthread_mutex_lock(&tty->tty_lock); if (tiocm & TIOCM_RTS) { - tty->mcr |= TIOCM_RTS; + tty->cmcr |= TIOCM_RTS; telnet_rfc2217_ctl(tty->tn, TNS_CTL_RTS_ON); } if (tiocm & TIOCM_DTR) { - tty->mcr |= TIOCM_DTR; + tty->cmcr |= TIOCM_DTR; telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_ON); } - pthread_mutex_unlock(&tty->tty_lock); goto show_mctl; case TIOCMBIC: CHECK_BUF_IN(sizeof(int)); tiocm = *(unsigned int *)in_buf; fuse_reply_ioctl(req, 0, 0, 0); DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm); - pthread_mutex_lock(&tty->tty_lock); if (tiocm & TIOCM_RTS) { - tty->mcr &= ~TIOCM_RTS; + tty->cmcr &= ~TIOCM_RTS; telnet_rfc2217_ctl(tty->tn, TNS_CTL_RTS_OFF); } if (tiocm & TIOCM_DTR) { - tty->mcr &= ~TIOCM_DTR; + tty->cmcr &= ~TIOCM_DTR; telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_OFF); } - pthread_mutex_unlock(&tty->tty_lock); goto show_mctl; case TIOCMSET: CHECK_BUF_IN(sizeof(int)); tiocm = *(unsigned int *)in_buf; fuse_reply_ioctl(req, 0, 0, 0); DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm); - pthread_mutex_lock(&tty->tty_lock); - tty->mcr &= ~(TIOCM_RTS | TIOCM_DTR); - tty->mcr |= tiocm & (TIOCM_RTS | TIOCM_DTR); + tty->cmcr &= ~(TIOCM_RTS | TIOCM_DTR); + tty->cmcr |= tiocm & (TIOCM_RTS | TIOCM_DTR); telnet_rfc2217_ctl(tty->tn, (tiocm & TIOCM_DTR) ? TNS_CTL_DTR_ON : TNS_CTL_DTR_OFF); telnet_rfc2217_ctl(tty->tn, (tiocm & TIOCM_RTS) ? TNS_CTL_RTS_ON : TNS_CTL_RTS_OFF); - pthread_mutex_unlock(&tty->tty_lock); goto show_mctl; show_mctl: DBG("MCR: DTR=%c RTS=%c\n", - tty->mcr & TIOCM_DTR ? '1' : '0', - tty->mcr & TIOCM_RTS ? '1' : '0'); + tty->cmcr & TIOCM_DTR ? '1' : '0', + tty->cmcr & TIOCM_RTS ? '1' : '0'); break; case TCSBRK: fuse_reply_ioctl(req, 0, 0, 0);