diff --git a/src/ttynvt.c b/src/ttynvt.c index d427cc3..4305e1a 100644 --- a/src/ttynvt.c +++ b/src/ttynvt.c @@ -83,11 +83,6 @@ typedef struct { tn_ctx_t *tn; } ttynvt_t; -static void _fd_close(int fd) -{ - if (fd >= 0) - close(fd); -} static volatile char _is_interrupted = 0; @@ -134,32 +129,10 @@ static int _check_dev(void) } -static void ttynvt_release(fuse_req_t req, struct fuse_file_info *info) +static void _fd_close(int fd) { - ttynvt_t *tty = (ttynvt_t *) (uintptr_t) info->fh; - - DBG("%s\n", __func__); - - tty->rel_pending = 1; - - pthread_cancel(tty->ptid_poll); - pthread_join(tty->ptid_poll, NULL); - pthread_mutex_destroy(&tty->tty_lock); - pthread_mutex_destroy(&tty->poll_lock); - - _fd_close(tty->fds[FD_NET].fd); - _fd_close(tty->fds[FD_MASTER].fd); - _fd_close(tty->fds[FD_SLAVE].fd); - - if (tty->ph) - fuse_pollhandle_destroy(tty->ph); - - free(tty->tn); - free(tty); - fuse_reply_err(req, 0); - - nvt_log(LOG_INFO, "Disconnected from server: %s:%d\n", - ttynvt_param.host, ttynvt_param.port); + if (fd >= 0) + close(fd); } static void _notify(ttynvt_t * tty) @@ -423,6 +396,37 @@ static void ttynvt_init(void *userdata, struct fuse_conn_info *conn) set_signal_handler(); } +static ttynvt_t *_ttynvt_ctx_create(void) +{ + ttynvt_t *tty; + int i; + + tty = calloc(1, sizeof(ttynvt_t)); + if (!tty) + return NULL; + + tty->tn = telnet_ctx_init(tty, _srv_write, _srv_read, _modem_status_cb); + if (!tty->tn) + { + free(tty); + return NULL; + } + + for (i = 0; i < 3; i++) + tty->fds[i].fd = -1; + + tty->pollout = 1; + + return tty; +} + +static void _ttynvt_ctx_destroy(ttynvt_t * tty) +{ + if (tty) + free(tty->tn); + free(tty); +} + static void ttynvt_open(fuse_req_t req, struct fuse_file_info *info) { ttynvt_t *tty; @@ -436,32 +440,18 @@ static void ttynvt_open(fuse_req_t req, struct fuse_file_info *info) nvt_log(LOG_INFO, "Connecting to server: %s:%d\n", ttynvt_param.host, ttynvt_param.port); - tty = calloc(1, sizeof(*tty)); + tty = _ttynvt_ctx_create(); if (!tty) { fuse_reply_err(req, ENOMEM); return; } - for (n = 0; n < 3; n++) - tty->fds[n].fd = -1; - - tty->pollout = 1; - - tty->tn = telnet_ctx_init(tty, _srv_write, _srv_read, _modem_status_cb); - if (!tty->tn) - { - free(tty); - fuse_reply_err(req, ENOMEM); - return; - } sockfd = _srv_connect(ttynvt_param.host, ttynvt_param.port); if (sockfd < 0) { - free(tty->tn); - free(tty); - fuse_reply_err(req, EHOSTUNREACH); - return; + errno = EHOSTUNREACH; + goto open_err; } tty->fds[FD_NET].fd = sockfd; @@ -523,19 +513,18 @@ static void ttynvt_open(fuse_req_t req, struct fuse_file_info *info) ttynvt_param.host, ttynvt_param.port); fuse_reply_open(req, info); - return; open_err: - nvt_log(LOG_ERR, "Connection to server: %s:%d failed: %m\n", - ttynvt_param.host, ttynvt_param.port); - for (n = 0; n < 3; n++) _fd_close(tty->fds[n].fd); - free(tty->tn); - free(tty); + _ttynvt_ctx_destroy(tty); + fuse_reply_err(req, errno); + + nvt_log(LOG_ERR, "Connection to server: %s:%d failed: %m\n", + ttynvt_param.host, ttynvt_param.port); } static void @@ -1120,6 +1109,34 @@ ttynvt_poll(fuse_req_t req, struct fuse_file_info *info, fuse_reply_poll(req, revents); } +static void ttynvt_release(fuse_req_t req, struct fuse_file_info *info) +{ + ttynvt_t *tty = (ttynvt_t *) (uintptr_t) info->fh; + + DBG("%s\n", __func__); + + tty->rel_pending = 1; + + pthread_cancel(tty->ptid_poll); + pthread_join(tty->ptid_poll, NULL); + pthread_mutex_destroy(&tty->tty_lock); + pthread_mutex_destroy(&tty->poll_lock); + + _fd_close(tty->fds[FD_NET].fd); + _fd_close(tty->fds[FD_MASTER].fd); + _fd_close(tty->fds[FD_SLAVE].fd); + + if (tty->ph) + fuse_pollhandle_destroy(tty->ph); + + _ttynvt_ctx_destroy(tty); + + fuse_reply_err(req, 0); + + nvt_log(LOG_INFO, "Disconnected from server: %s:%d\n", + ttynvt_param.host, ttynvt_param.port); +} + static const struct cuse_lowlevel_ops ttynvt_op = { .init = ttynvt_init, .open = ttynvt_open,