]> prime8.dev >> repos - ttyd.git/commitdiff
protocol: fix uv handle closing
authorShuanglei Tao <tsl0922@gmail.com>
Sat, 6 Feb 2021 01:28:04 +0000 (09:28 +0800)
committerShuanglei Tao <tsl0922@gmail.com>
Sat, 6 Feb 2021 01:28:04 +0000 (09:28 +0800)
src/protocol.c
src/server.c
src/server.h

index 3b01ac2c76ce47d0de92a84b448c935404c3a1c9..f548fe119544c5c99f4005d1e798347c21c5a26f 100644 (file)
@@ -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);
       }
 
index 08457a968ddc9d207fcdb038af9cc53e638bbd69..d2b1e97ab7a5110a7eb8140dcc763fb40f3b06db 100644 (file)
@@ -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);
index 0c042221202c46e994ef51a53b82767f3f418560..4ea753d884bb03343bf4e91c9cb360ea9b3d6200 100644 (file)
@@ -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;
 };