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_mutex_t poll_lock;
|
||||||
pthread_t thread_id;
|
pthread_t thread_id;
|
||||||
|
|
||||||
pthread_mutex_t cond_lock;
|
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
|
|
||||||
struct fuse_pollhandle *ph;
|
struct fuse_pollhandle *ph;
|
||||||
@@ -61,6 +60,7 @@ typedef struct ttynvt {
|
|||||||
size_t rxcnt;
|
size_t rxcnt;
|
||||||
|
|
||||||
int txbuf_size;
|
int txbuf_size;
|
||||||
|
int epipe;
|
||||||
volatile sig_atomic_t error;
|
volatile sig_atomic_t error;
|
||||||
|
|
||||||
tn_ctx_t *tn;
|
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_join(tty->thread_id, NULL);
|
||||||
(void)pthread_mutex_destroy(&tty->tty_lock);
|
(void)pthread_mutex_destroy(&tty->tty_lock);
|
||||||
(void)pthread_mutex_destroy(&tty->poll_lock);
|
(void)pthread_mutex_destroy(&tty->poll_lock);
|
||||||
(void)pthread_mutex_destroy(&tty->cond_lock);
|
|
||||||
(void)pthread_cond_destroy(&tty->cond);
|
(void)pthread_cond_destroy(&tty->cond);
|
||||||
|
|
||||||
if (tty->ph)
|
if (tty->ph)
|
||||||
@@ -194,7 +193,6 @@ static void *ttynvt_read_net(void *arg)
|
|||||||
ttynvt_log("WARNING: rx buffer overflow\n");
|
ttynvt_log("WARNING: rx buffer overflow\n");
|
||||||
}
|
}
|
||||||
res = read(tty->fds[0].fd, tty->buf + tty->blen, read_avail);
|
res = read(tty->fds[0].fd, tty->buf + tty->blen, read_avail);
|
||||||
|
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&tty->tty_lock);
|
pthread_mutex_unlock(&tty->tty_lock);
|
||||||
@@ -208,24 +206,22 @@ static void *ttynvt_read_net(void *arg)
|
|||||||
if (tn_res == 0)
|
if (tn_res == 0)
|
||||||
{
|
{
|
||||||
tty->rxcnt = tty->blen;
|
tty->rxcnt = tty->blen;
|
||||||
pthread_mutex_unlock(&tty->tty_lock);
|
|
||||||
ttynvt_notify(tty);
|
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;
|
tty->error = 1;
|
||||||
close(tty->fds[0].fd);
|
|
||||||
ttynvt_notify(tty);
|
ttynvt_notify(tty);
|
||||||
|
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ttynvt_connect(const char *host, unsigned int port)
|
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
|
if (connect
|
||||||
(sockfd, (const struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
|
(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 -1;
|
||||||
}
|
}
|
||||||
return sockfd;
|
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 ||
|
if (pthread_mutex_init(&tty->tty_lock, NULL) < 0 ||
|
||||||
pthread_mutex_init(&tty->poll_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_cond_init(&tty->cond, NULL) < 0 ||
|
||||||
pthread_create(&tty->thread_id, NULL, &ttynvt_read_net, tty))
|
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)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&tty->tty_lock);
|
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)
|
if (size > tty->rxcnt)
|
||||||
size = tty->rxcnt;
|
size = tty->rxcnt;
|
||||||
fuse_reply_buf(req, tty->buf, size);
|
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)
|
if (ttynvt_read_avail(tty) > 0)
|
||||||
revents |= POLLIN;
|
revents |= POLLIN;
|
||||||
if (tty->error)
|
if (tty->error)
|
||||||
revents = POLLERR;
|
{
|
||||||
|
if (tty->epipe == 0)
|
||||||
|
revents = POLLHUP | POLLIN;
|
||||||
|
else
|
||||||
|
revents = 0;
|
||||||
|
}
|
||||||
|
|
||||||
fuse_reply_poll(req, revents);
|
fuse_reply_poll(req, revents);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user