diff --git a/ttynvt.c b/ttynvt.c index 303f5a4..1039e47 100644 --- a/ttynvt.c +++ b/ttynvt.c @@ -46,7 +46,6 @@ typedef struct ttynvt { pthread_mutex_t poll_lock; pthread_t thread_id; - pthread_mutex_t cond_lock; pthread_cond_t cond; struct fuse_pollhandle *ph; @@ -61,6 +60,7 @@ typedef struct ttynvt { size_t rxcnt; int txbuf_size; + int epipe; volatile sig_atomic_t error; tn_ctx_t *tn; @@ -97,7 +97,6 @@ static void ttynvt_release(fuse_req_t req, struct fuse_file_info *info) (void)pthread_join(tty->thread_id, NULL); (void)pthread_mutex_destroy(&tty->tty_lock); (void)pthread_mutex_destroy(&tty->poll_lock); - (void)pthread_mutex_destroy(&tty->cond_lock); (void)pthread_cond_destroy(&tty->cond); if (tty->ph) @@ -194,7 +193,6 @@ static void *ttynvt_read_net(void *arg) ttynvt_log("WARNING: rx buffer overflow\n"); } res = read(tty->fds[0].fd, tty->buf + tty->blen, read_avail); - if (res <= 0) { pthread_mutex_unlock(&tty->tty_lock); @@ -208,24 +206,22 @@ static void *ttynvt_read_net(void *arg) if (tn_res == 0) { tty->rxcnt = tty->blen; - pthread_mutex_unlock(&tty->tty_lock); ttynvt_notify(tty); } - else - { - pthread_mutex_unlock(&tty->tty_lock); - } + pthread_mutex_unlock(&tty->tty_lock); } } } - ttynvt_log("RX read error:%ld\n", res); + if (res == 0) + ttynvt_log("connection closed by remote host\n"); + else + ttynvt_log("RX read error:%s\n", strerror(errno)); tty->error = 1; - close(tty->fds[0].fd); ttynvt_notify(tty); - return NULL; + return 0; } static int ttynvt_connect(const char *host, unsigned int port) @@ -256,7 +252,8 @@ static int ttynvt_connect(const char *host, unsigned int port) if (connect (sockfd, (const struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) { - ttynvt_log("ERROR: failed to connecti: %s\n", strerror(errno)); + ttynvt_log("ERROR: failed to connect to: %s:%u:%s\n", + host, port, strerror(errno)); return -1; } return sockfd; @@ -372,7 +369,6 @@ static void ttynvt_open(fuse_req_t req, struct fuse_file_info *info) if (pthread_mutex_init(&tty->tty_lock, NULL) < 0 || pthread_mutex_init(&tty->poll_lock, NULL) < 0 || - pthread_mutex_init(&tty->cond_lock, NULL) < 0 || pthread_cond_init(&tty->cond, NULL) < 0 || pthread_create(&tty->thread_id, NULL, &ttynvt_read_net, tty)) { @@ -399,11 +395,23 @@ ttynvt_read(fuse_req_t req, size_t size, off_t off, if (tty->error) { - fuse_reply_err(req, EPIPE); + if (tty->epipe == 0) + { + ttynvt_log("RX EPIPE\n"); + tty->epipe = 1; + fuse_reply_buf(req, tty->buf, 0); + } + else + fuse_reply_err(req, EBADFD); + return; } pthread_mutex_lock(&tty->tty_lock); + if (tty->rxcnt == 0 && !(info->flags & O_NONBLOCK)) + { + pthread_cond_wait(&tty->cond, &tty->tty_lock); + } if (size > tty->rxcnt) size = tty->rxcnt; fuse_reply_buf(req, tty->buf, size); @@ -751,7 +759,12 @@ ttynvt_poll(fuse_req_t req, struct fuse_file_info *info, if (ttynvt_read_avail(tty) > 0) revents |= POLLIN; if (tty->error) - revents = POLLERR; + { + if (tty->epipe == 0) + revents = POLLHUP | POLLIN; + else + revents = 0; + } fuse_reply_poll(req, revents); }