support for blocking devices.
- and better handling of broken network connections.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user