Skip to content

Commit 75105f6

Browse files
committed
protocol: use 2 pipe for read and write
1 parent 5d1b86d commit 75105f6

File tree

4 files changed

+47
-32
lines changed

4 files changed

+47
-32
lines changed

src/protocol.c

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,24 @@ static bool check_host_origin(struct lws *wsi) {
9797
return len > 0 && strcasecmp(buf, host_buf) == 0;
9898
}
9999

100-
pid_t pty_fork(int *pty, const char *file, char *const argv[], const char *term) {
100+
static bool fd_set_cloexec(const int fd) {
101+
int flags = fcntl(fd, F_GETFD);
102+
if (flags < 0) return false;
103+
return (flags & FD_CLOEXEC) == 0 || fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1;
104+
}
105+
106+
static int fd_duplicate(int fd, uv_pipe_t *pipe) {
107+
int fd_dup = dup(fd);
108+
if (fd_dup < 0) return -errno;
109+
110+
fd_set_cloexec(fd_dup);
111+
112+
int status = uv_pipe_open(pipe, fd_dup);
113+
if(status) close(fd_dup);
114+
return status;
115+
}
116+
117+
static pid_t pty_fork(int *pty, const char *file, char *const argv[], const char *term) {
101118
pid_t pid = forkpty(pty, NULL, NULL, NULL);
102119

103120
if (pid < 0) {
@@ -122,7 +139,7 @@ pid_t pty_fork(int *pty, const char *file, char *const argv[], const char *term)
122139
return pid;
123140
}
124141

125-
int pty_resize(int pty, int cols, int rows) {
142+
static int pty_resize(int pty, int cols, int rows) {
126143
struct winsize size;
127144

128145
size.ws_col = (unsigned short)cols;
@@ -134,21 +151,22 @@ int pty_resize(int pty, int cols, int rows) {
134151
}
135152

136153
static void close_cb(uv_handle_t *handle) {
137-
struct pty_proc *proc = container_of((uv_pipe_t *)handle, struct pty_proc, pipe);
154+
struct pty_proc *proc = container_of((uv_pipe_t *)handle, struct pty_proc, out_pipe);
138155
free(proc);
139156
}
140157

141158
static void pty_proc_free(struct pty_proc *proc) {
142-
uv_read_stop((uv_stream_t *)&proc->pipe);
143-
close(proc->pty);
159+
uv_read_stop((uv_stream_t *)&proc->out_pipe);
160+
if (proc->pty_fd >0) close(proc->pty_fd);
144161
if (proc->pty_buffer != NULL) {
145162
free(proc->pty_buffer);
146163
proc->pty_buffer = NULL;
147164
}
148165
for (int i = 0; i < proc->argc; i++) {
149166
free(proc->args[i]);
150167
}
151-
uv_close((uv_handle_t *)&proc->pipe, close_cb);
168+
uv_close((uv_handle_t *)&proc->in_pipe, NULL);
169+
uv_close((uv_handle_t *)&proc->out_pipe, close_cb);
152170
}
153171

154172
static void alloc_cb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
@@ -232,16 +250,21 @@ static int spawn_process(struct pss_tty *pss) {
232250
fd_set_cloexec(lws_get_socket_fd(pss->wsi));
233251

234252
// create process with pseudo-tty
235-
proc->pid = pty_fork(&proc->pty, argv[0], argv, server->terminal_type);
236-
if (proc->pid < 0) {
253+
uv_disable_stdio_inheritance();
254+
int master, pid;
255+
pid = pty_fork(&master, argv[0], argv, server->terminal_type);
256+
if (pid < 0) {
237257
lwsl_err("pty_fork: %d (%s)\n", errno, strerror(errno));
238258
return 1;
239259
}
240260

241-
lwsl_notice("started process, pid: %d\n", proc->pid);
261+
lwsl_notice("started process, pid: %d\n", pid);
242262

243-
proc->pipe.data = pss;
244-
uv_pipe_open(&proc->pipe, proc->pty);
263+
proc->pty_fd = master;
264+
proc->pid = pid;
265+
proc->out_pipe.data = pss;
266+
if (fd_duplicate(master, &proc->in_pipe) || fd_duplicate(master, &proc->out_pipe))
267+
return 1;
245268

246269
lws_callback_on_writable(pss->wsi);
247270

@@ -314,7 +337,8 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
314337
memset(proc, 0, sizeof(struct pty_proc));
315338
proc->status = -1;
316339
proc->state = STATE_INIT;
317-
uv_pipe_init(server->loop, &proc->pipe, 0);
340+
uv_pipe_init(server->loop, &proc->in_pipe, 0);
341+
uv_pipe_init(server->loop, &proc->out_pipe, 0);
318342

319343
if (server->url_arg) {
320344
while (lws_hdr_copy_fragment(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_URI_ARGS, n++) > 0) {
@@ -344,7 +368,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
344368
if (!pss->initialized) {
345369
if (pss->initial_cmd_index == sizeof(initial_cmds)) {
346370
pss->initialized = true;
347-
uv_read_start((uv_stream_t *)&proc->pipe, alloc_cb, read_cb);
371+
uv_read_start((uv_stream_t *)&proc->out_pipe, alloc_cb, read_cb);
348372
break;
349373
}
350374
if (send_initial_message(wsi, pss->initial_cmd_index) < 0) {
@@ -376,7 +400,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
376400
proc->pty_buffer = NULL;
377401
}
378402

379-
uv_read_start((uv_stream_t *)&proc->pipe, alloc_cb, read_cb);
403+
uv_read_start((uv_stream_t *)&proc->out_pipe, alloc_cb, read_cb);
380404
break;
381405

382406
case LWS_CALLBACK_RECEIVE:
@@ -406,7 +430,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
406430
proc = pss->proc;
407431
switch (command) {
408432
case INPUT:
409-
if (proc->pty == 0) break;
433+
if (proc->pty_fd == 0) break;
410434
if (server->readonly) break;
411435

412436
char *data = xmalloc(pss->len - 1);
@@ -416,7 +440,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
416440
uv_write_t *req = xmalloc(sizeof(uv_write_t));
417441
req->data = data;
418442

419-
int err = uv_write(req, (uv_stream_t *)&proc->pipe, &b, 1, write_cb);
443+
int err = uv_write(req, (uv_stream_t *)&proc->in_pipe, &b, 1, write_cb);
420444
if (err) {
421445
lwsl_err("uv_write: %s (%s)\n", uv_err_name(err), uv_strerror(err));
422446
return -1;
@@ -425,20 +449,20 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
425449
case RESIZE_TERMINAL: {
426450
int cols, rows;
427451
if (parse_window_size(pss, &cols, &rows)) {
428-
if (pty_resize(proc->pty, cols, rows) < 0) {
452+
if (pty_resize(proc->pty_fd, cols, rows) < 0) {
429453
lwsl_err("pty_resize: %d (%s)\n", errno, strerror(errno));
430454
}
431455
}
432456
} break;
433457
case PAUSE:
434458
if (proc->state == STATE_INIT) {
435-
uv_read_stop((uv_stream_t *)&proc->pipe);
459+
uv_read_stop((uv_stream_t *)&proc->out_pipe);
436460
proc->state = STATE_PAUSE;
437461
}
438462
break;
439463
case RESUME:
440464
if (proc->state == STATE_PAUSE) {
441-
uv_read_start((uv_stream_t *)&proc->pipe, alloc_cb, read_cb);
465+
uv_read_start((uv_stream_t *)&proc->out_pipe, alloc_cb, read_cb);
442466
proc->state = STATE_INIT;
443467
}
444468
break;
@@ -486,7 +510,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
486510
pty_proc_free(proc);
487511
} else {
488512
proc->state = STATE_KILL;
489-
uv_read_stop((uv_stream_t *)&proc->pipe);
513+
uv_read_stop((uv_stream_t *)&proc->out_pipe);
490514
kill_process(proc);
491515
}
492516

src/server.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ struct pty_proc {
4747
int status;
4848
proc_state state;
4949

50-
int pty;
50+
int pty_fd;
5151
char *pty_buffer;
5252
ssize_t pty_len;
5353
int err_count;
5454

55-
uv_pipe_t pipe;
55+
uv_pipe_t in_pipe;
56+
uv_pipe_t out_pipe;
5657

5758
LIST_ENTRY(pty_proc) entry;
5859
};

src/utils.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,6 @@ int get_sig(const char *sig_name) {
7474
return atoi(sig_name);
7575
}
7676

77-
bool fd_set_cloexec(const int fd) {
78-
int flags = fcntl(fd, F_GETFD);
79-
if (flags < 0) return false;
80-
return (flags & FD_CLOEXEC) == 0 ||
81-
fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1;
82-
}
83-
8477
int open_uri(char *uri) {
8578
#ifdef __APPLE__
8679
char command[256];

src/utils.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ int get_sig_name(int sig, char *buf, size_t len);
2525
// Get signal code from string like SIGHUP
2626
int get_sig(const char *sig_name);
2727

28-
// Set the given file descriptor close-on-exec
29-
bool fd_set_cloexec(const int fd);
30-
3128
// Open uri with the default application of system
3229
int open_uri(char *uri);
3330

0 commit comments

Comments
 (0)