From: Shuanglei Tao Date: Sat, 6 Feb 2021 01:28:04 +0000 (+0800) Subject: protocol: fix uv handle closing X-Git-Url: http://git.prime8.dev/?a=commitdiff_plain;h=215849b5d031f9df255a75634f75f5631bb1c490;p=ttyd.git protocol: fix uv handle closing --- diff --git a/src/protocol.c b/src/protocol.c index 3b01ac2..f548fe1 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -151,13 +151,12 @@ static int pty_resize(int pty, int cols, int rows) { } static void close_cb(uv_handle_t *handle) { - struct pty_proc *proc = container_of((uv_pipe_t *)handle, struct pty_proc, out_pipe); - free(proc); + free(handle); } static void pty_proc_free(struct pty_proc *proc) { - uv_read_stop((uv_stream_t *)&proc->out_pipe); - if (proc->pty_fd >0) close(proc->pty_fd); + uv_read_stop((uv_stream_t *)proc->out_pipe); + if (proc->pty_fd >= 0) close(proc->pty_fd); if (proc->pty_buffer != NULL) { free(proc->pty_buffer); proc->pty_buffer = NULL; @@ -165,8 +164,9 @@ static void pty_proc_free(struct pty_proc *proc) { for (int i = 0; i < proc->argc; i++) { free(proc->args[i]); } - uv_close((uv_handle_t *)&proc->in_pipe, NULL); - uv_close((uv_handle_t *)&proc->out_pipe, close_cb); + uv_close((uv_handle_t *)proc->in_pipe, close_cb); + uv_close((uv_handle_t *)proc->out_pipe, close_cb); + free(proc); } static void alloc_cb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { @@ -262,8 +262,8 @@ static int spawn_process(struct pss_tty *pss) { proc->pty_fd = master; proc->pid = pid; - proc->out_pipe.data = pss; - if (fd_duplicate(master, &proc->in_pipe) || fd_duplicate(master, &proc->out_pipe)) + proc->out_pipe->data = pss; + if (fd_duplicate(master, proc->in_pipe) || fd_duplicate(master, proc->out_pipe)) return 1; lws_callback_on_writable(pss->wsi); @@ -335,10 +335,13 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, pss->proc = proc = xmalloc(sizeof(struct pty_proc)); memset(proc, 0, sizeof(struct pty_proc)); + proc->pty_fd = -1; proc->status = -1; proc->state = STATE_INIT; - uv_pipe_init(server->loop, &proc->in_pipe, 0); - uv_pipe_init(server->loop, &proc->out_pipe, 0); + proc->in_pipe = xmalloc(sizeof(uv_pipe_t)); + uv_pipe_init(server->loop, proc->in_pipe, 0); + proc->out_pipe = xmalloc(sizeof(uv_pipe_t)); + uv_pipe_init(server->loop, proc->out_pipe, 0); if (server->url_arg) { while (lws_hdr_copy_fragment(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_URI_ARGS, n++) > 0) { @@ -368,7 +371,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, if (!pss->initialized) { if (pss->initial_cmd_index == sizeof(initial_cmds)) { pss->initialized = true; - uv_read_start((uv_stream_t *)&proc->out_pipe, alloc_cb, read_cb); + uv_read_start((uv_stream_t *)proc->out_pipe, alloc_cb, read_cb); break; } if (send_initial_message(wsi, pss->initial_cmd_index) < 0) { @@ -400,7 +403,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, proc->pty_buffer = NULL; } - uv_read_start((uv_stream_t *)&proc->out_pipe, alloc_cb, read_cb); + uv_read_start((uv_stream_t *)proc->out_pipe, alloc_cb, read_cb); break; case LWS_CALLBACK_RECEIVE: @@ -430,7 +433,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, proc = pss->proc; switch (command) { case INPUT: - if (proc->pty_fd == 0) break; + if (proc->pty_fd < 0) break; if (server->readonly) break; char *data = xmalloc(pss->len - 1); @@ -440,7 +443,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, uv_write_t *req = xmalloc(sizeof(uv_write_t)); req->data = data; - int err = uv_write(req, (uv_stream_t *)&proc->in_pipe, &b, 1, write_cb); + int err = uv_write(req, (uv_stream_t *)proc->in_pipe, &b, 1, write_cb); if (err) { lwsl_err("uv_write: %s (%s)\n", uv_err_name(err), uv_strerror(err)); return -1; @@ -456,13 +459,13 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, } break; case PAUSE: if (proc->state == STATE_INIT) { - uv_read_stop((uv_stream_t *)&proc->out_pipe); + uv_read_stop((uv_stream_t *)proc->out_pipe); proc->state = STATE_PAUSE; } break; case RESUME: if (proc->state == STATE_PAUSE) { - uv_read_start((uv_stream_t *)&proc->out_pipe, alloc_cb, read_cb); + uv_read_start((uv_stream_t *)proc->out_pipe, alloc_cb, read_cb); proc->state = STATE_INIT; } break; @@ -510,7 +513,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, pty_proc_free(proc); } else { proc->state = STATE_KILL; - uv_read_stop((uv_stream_t *)&proc->out_pipe); + uv_read_stop((uv_stream_t *)proc->out_pipe); kill_process(proc); } diff --git a/src/server.c b/src/server.c index 08457a9..d2b1e97 100644 --- a/src/server.c +++ b/src/server.c @@ -200,6 +200,7 @@ static void server_free(struct server *ts) { } } uv_signal_stop(&ts->watcher); + uv_close((uv_handle_t *)&server->watcher, NULL); uv_loop_close(ts->loop); free(ts->loop); free(ts); diff --git a/src/server.h b/src/server.h index 0c04222..4ea753d 100644 --- a/src/server.h +++ b/src/server.h @@ -52,8 +52,8 @@ struct pty_proc { ssize_t pty_len; int err_count; - uv_pipe_t in_pipe; - uv_pipe_t out_pipe; + uv_pipe_t *in_pipe; + uv_pipe_t *out_pipe; LIST_ENTRY(pty_proc) entry; };