summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2022-09-02 08:36:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2022-09-02 08:36:00 +0000
commit01b623a2f80953e6156ede3f0f082ebb4a5cf0c8 (patch)
tree77c2df3aa8e4730cd15d083e1217d08a12f3179b /src
parentAdding upstream version 1.7.0. (diff)
downloadttyd-01b623a2f80953e6156ede3f0f082ebb4a5cf0c8.tar.xz
ttyd-01b623a2f80953e6156ede3f0f082ebb4a5cf0c8.zip
Adding upstream version 1.7.1.upstream/1.7.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src')
-rw-r--r--src/protocol.c69
-rw-r--r--src/pty.c76
-rw-r--r--src/pty.h21
-rw-r--r--src/server.h5
4 files changed, 87 insertions, 84 deletions
diff --git a/src/protocol.c b/src/protocol.c
index ca1e086..5341c3d 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -51,9 +51,7 @@ static bool check_host_origin(struct lws *wsi) {
char buf[256];
memset(buf, 0, sizeof(buf));
int len = lws_hdr_copy(wsi, buf, (int)sizeof(buf), WSI_TOKEN_ORIGIN);
- if (len <= 0) {
- return false;
- }
+ if (len <= 0) return false;
const char *prot, *address, *path;
int port;
@@ -71,26 +69,43 @@ static bool check_host_origin(struct lws *wsi) {
return len > 0 && strcasecmp(buf, host_buf) == 0;
}
-static void process_read_cb(void *ctx, pty_buf_t *buf, bool eof) {
- struct pss_tty *pss = (struct pss_tty *)ctx;
- if (eof && !process_running(pss->process))
- pss->lws_close_status = pss->process->exit_code == 0 ? 1000 : 1006;
- else
- pss->pty_buf = buf;
+static pty_ctx_t *pty_ctx_init(struct pss_tty *pss) {
+ pty_ctx_t *ctx = xmalloc(sizeof(pty_ctx_t));
+ ctx->pss = pss;
+ ctx->ws_closed = false;
+ return ctx;
+}
- lws_callback_on_writable(pss->wsi);
+static void pty_ctx_free(pty_ctx_t *ctx) { free(ctx); }
+
+static void process_read_cb(pty_process *process, pty_buf_t *buf, bool eof) {
+ pty_ctx_t *ctx = (pty_ctx_t *)process->ctx;
+ if (ctx->ws_closed) {
+ pty_buf_free(buf);
+ return;
+ }
+
+ if (eof && !process_running(process))
+ ctx->pss->lws_close_status = process->exit_code == 0 ? 1000 : 1006;
+ else
+ ctx->pss->pty_buf = buf;
+ lws_callback_on_writable(ctx->pss->wsi);
}
-static void process_exit_cb(void *ctx, pty_process *process) {
- struct pss_tty *pss = (struct pss_tty *)ctx;
- pss->process = NULL;
- if (process->killed) {
+static void process_exit_cb(pty_process *process) {
+ pty_ctx_t *ctx = (pty_ctx_t *)process->ctx;
+ if (ctx->ws_closed) {
lwsl_notice("process killed with signal %d, pid: %d\n", process->exit_signal, process->pid);
- } else {
- lwsl_notice("process exited with code %d, pid: %d\n", process->exit_code, process->pid);
- pss->lws_close_status = process->exit_code == 0 ? 1000 : 1006;
- lws_callback_on_writable(pss->wsi);
+ goto done;
}
+
+ lwsl_notice("process exited with code %d, pid: %d\n", process->exit_code, process->pid);
+ ctx->pss->process = NULL;
+ ctx->pss->lws_close_status = process->exit_code == 0 ? 1000 : 1006;
+ lws_callback_on_writable(ctx->pss->wsi);
+
+done:
+ pty_ctx_free(ctx);
}
static char **build_args(struct pss_tty *pss) {
@@ -133,7 +148,7 @@ static char **build_env(struct pss_tty *pss) {
}
static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows) {
- pty_process *process = process_init((void *)pss, server->loop, build_args(pss), build_env(pss));
+ pty_process *process = process_init((void *)pty_ctx_init(pss), server->loop, build_args(pss), build_env(pss));
if (server->cwd != NULL) process->cwd = strdup(server->cwd);
if (columns > 0) process->columns = columns;
if (rows > 0) process->rows = rows;
@@ -348,17 +363,19 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
server->client_count--;
lwsl_notice("WS closed from %s, clients: %d\n", pss->address, server->client_count);
- if (pss->buffer != NULL) {
- free(pss->buffer);
- }
+ if (pss->buffer != NULL) free(pss->buffer);
+ if (pss->pty_buf != NULL) pty_buf_free(pss->pty_buf);
for (int i = 0; i < pss->argc; i++) {
free(pss->args[i]);
}
- if (process_running(pss->process)) {
- pty_pause(pss->process);
- lwsl_notice("killing process, pid: %d\n", pss->process->pid);
- pty_kill(pss->process, server->sig_code);
+ if (pss->process != NULL) {
+ ((pty_ctx_t *)pss->process->ctx)->ws_closed = true;
+ if (process_running(pss->process)) {
+ pty_pause(pss->process);
+ lwsl_notice("killing process, pid: %d\n", pss->process->pid);
+ pty_kill(pss->process, server->sig_code);
+ }
}
if (server->once && server->client_count == 0) {
diff --git a/src/pty.c b/src/pty.c
index b046a6a..7bf62f4 100644
--- a/src/pty.c
+++ b/src/pty.c
@@ -51,20 +51,21 @@ pty_buf_t *pty_buf_init(char *base, size_t len) {
}
void pty_buf_free(pty_buf_t *buf) {
- free(buf->base);
+ if (buf == NULL) return;
+ if (buf->base != NULL) free(buf->base);
free(buf);
}
static void read_cb(uv_stream_t *stream, ssize_t n, const uv_buf_t *buf) {
uv_read_stop(stream);
- pty_io_t *io = (pty_io_t *) stream->data;
+ pty_process *process = (pty_process *) stream->data;
if (n <= 0) {
if (n == UV_ENOBUFS || n == 0) return;
if (n != UV_EOF) printf("== uv_read failed with error %ld: %s\n", n, uv_strerror(n));
- io->read_cb(io->ctx, NULL, true);
+ process->read_cb(process, NULL, true);
goto done;
}
- io->read_cb(io->ctx, pty_buf_init(buf->base, (size_t) n), false);
+ process->read_cb(process, pty_buf_init(buf->base, (size_t) n), false);
done:
free(buf->base);
@@ -76,24 +77,6 @@ static void write_cb(uv_write_t *req, int unused) {
free(req);
}
-static pty_io_t *pty_io_init(pty_process *process, pty_read_cb read_cb) {
- pty_io_t *io = xmalloc(sizeof(pty_io_t));
- io->in = xmalloc(sizeof(uv_pipe_t));
- io->out = xmalloc(sizeof(uv_pipe_t));
- uv_pipe_init(process->loop, io->in, 0);
- uv_pipe_init(process->loop, io->out, 0);
- io->paused = true;
- io->read_cb = read_cb;
- io->ctx = process->ctx;
- return io;
-}
-
-static void pty_io_free(pty_io_t *io) {
- uv_close((uv_handle_t *) io->in, close_cb);
- uv_close((uv_handle_t *) io->out, close_cb);
- free(io);
-}
-
pty_process *process_init(void *ctx, uv_loop_t *loop, char *argv[], char *envp[]) {
pty_process *process = xmalloc(sizeof(pty_process));
memset(process, 0, sizeof(pty_process));
@@ -121,9 +104,11 @@ void process_free(pty_process *process) {
if (process->pty != NULL) pClosePseudoConsole(process->pty);
if (process->handle != NULL) CloseHandle(process->handle);
#else
+ close(process->pty);
uv_thread_join(&process->tid);
#endif
- if (process->io != NULL) pty_io_free(process->io);
+ if (process->in != NULL) uv_close((uv_handle_t *) process->in, close_cb);
+ if (process->out != NULL) uv_close((uv_handle_t *) process->out, close_cb);
if (process->argv != NULL) free(process->argv);
if (process->cwd != NULL) free(process->cwd);
char **p = process->envp;
@@ -134,17 +119,15 @@ void process_free(pty_process *process) {
void pty_pause(pty_process *process) {
if (process == NULL) return;
- pty_io_t *io = process->io;
- if (io->paused) return;
- uv_read_stop((uv_stream_t *) io->out);
+ if (process->paused) return;
+ uv_read_stop((uv_stream_t *) process->out);
}
void pty_resume(pty_process *process) {
if (process == NULL) return;
- pty_io_t *io = process->io;
- if (!io->paused) return;
- io->out->data = io;
- uv_read_start((uv_stream_t *) io->out, alloc_cb, read_cb);
+ if (!process->paused) return;
+ process->out->data = process;
+ uv_read_start((uv_stream_t *) process->out, alloc_cb, read_cb);
}
int pty_write(pty_process *process, pty_buf_t *buf) {
@@ -152,11 +135,10 @@ int pty_write(pty_process *process, pty_buf_t *buf) {
pty_buf_free(buf);
return UV_ESRCH;
}
- pty_io_t *io = process->io;
uv_buf_t b = uv_buf_init(buf->base, buf->len);
uv_write_t *req = xmalloc(sizeof(uv_write_t));
req->data = buf;
- return uv_write(req, (uv_stream_t *) io->in, &b, 1, write_cb);
+ return uv_write(req, (uv_stream_t *) process->in, &b, 1, write_cb);
}
bool pty_resize(pty_process *process) {
@@ -173,7 +155,6 @@ bool pty_resize(pty_process *process) {
bool pty_kill(pty_process *process, int sig) {
if (process == NULL) return false;
- process->killed = true;
#ifdef _WIN32
return TerminateProcess(process->handle, 1) != 0;
#else
@@ -324,7 +305,7 @@ static void async_cb(uv_async_t *async) {
GetExitCodeProcess(process->handle, &exit_code);
process->exit_code = (int) exit_code;
process->exit_signal = 1;
- process->exit_cb(process->ctx, process);
+ process->exit_cb(process);
uv_close((uv_handle_t *) async, NULL);
process_free(process);
@@ -341,12 +322,15 @@ int pty_spawn(pty_process *process, pty_read_cb read_cb, pty_exit_cb exit_cb) {
SetConsoleCtrlHandler(NULL, FALSE);
int status = 1;
- pty_io_t *io = pty_io_init(process, read_cb);
+ process->in = xmalloc(sizeof(uv_pipe_t));
+ process->out = xmalloc(sizeof(uv_pipe_t));
+ uv_pipe_init(process->loop, process->in, 0);
+ uv_pipe_init(process->loop, process->out, 0);
uv_connect_t *in_req = xmalloc(sizeof(uv_connect_t));
uv_connect_t *out_req = xmalloc(sizeof(uv_connect_t));
- uv_pipe_connect(in_req, io->in, in_name, connect_cb);
- uv_pipe_connect(out_req, io->out, out_name, connect_cb);
+ uv_pipe_connect(in_req, process->in, in_name, connect_cb);
+ uv_pipe_connect(out_req, process->out, out_name, connect_cb);
PROCESS_INFORMATION pi = {0};
WCHAR *cmdline, *cwd;
@@ -373,14 +357,14 @@ int pty_spawn(pty_process *process, pty_read_cb read_cb, pty_exit_cb exit_cb) {
process->pid = pi.dwProcessId;
process->handle = pi.hProcess;
- process->io = io;
+ process->paused = true;
+ process->read_cb = read_cb;
process->exit_cb = exit_cb;
process->async.data = process;
uv_async_init(process->loop, &process->async, async_cb);
if (!RegisterWaitForSingleObject(&process->wait, pi.hProcess, conpty_exit, process, INFINITE, WT_EXECUTEONLYONCE)) {
print_error("RegisterWaitForSingleObject");
- pty_io_free(io);
goto cleanup;
}
@@ -434,7 +418,7 @@ static void wait_cb(void *arg) {
static void async_cb(uv_async_t *async) {
pty_process *process = (pty_process *) async->data;
- process->exit_cb(process->ctx, process);
+ process->exit_cb(process);
uv_close((uv_handle_t *) async, NULL);
process_free(process);
@@ -479,16 +463,20 @@ int pty_spawn(pty_process *process, pty_read_cb read_cb, pty_exit_cb exit_cb) {
goto error;
}
- pty_io_t *io = pty_io_init(process, read_cb);
- if (!fd_duplicate(master, io->in) || !fd_duplicate(master, io->out)) {
+ process->in = xmalloc(sizeof(uv_pipe_t));
+ process->out = xmalloc(sizeof(uv_pipe_t));
+ uv_pipe_init(process->loop, process->in, 0);
+ uv_pipe_init(process->loop, process->out, 0);
+
+ if (!fd_duplicate(master, process->in) || !fd_duplicate(master, process->out)) {
status = -errno;
- pty_io_free(io);
goto error;
}
process->pty = master;
process->pid = pid;
- process->io = io;
+ process->paused = true;
+ process->read_cb = read_cb;
process->exit_cb = exit_cb;
process->async.data = process;
uv_async_init(process->loop, &process->async, async_cb);
diff --git a/src/pty.h b/src/pty.h
index dbe5a30..c3f761c 100644
--- a/src/pty.h
+++ b/src/pty.h
@@ -21,25 +21,14 @@ typedef struct {
size_t len;
} pty_buf_t;
-typedef void (*pty_read_cb)(void *, pty_buf_t *, bool);
-
-typedef struct {
- uv_pipe_t *in;
- uv_pipe_t *out;
- bool paused;
-
- pty_read_cb read_cb;
- void *ctx;
-} pty_io_t;
-
struct pty_process_;
typedef struct pty_process_ pty_process;
-typedef void (*pty_exit_cb)(void *, pty_process *);
+typedef void (*pty_read_cb)(pty_process *, pty_buf_t *, bool);
+typedef void (*pty_exit_cb)(pty_process *);
struct pty_process_ {
int pid, exit_code, exit_signal;
uint16_t columns, rows;
- bool killed;
#ifdef _WIN32
STARTUPINFOEXW si;
HPCON pty;
@@ -55,7 +44,11 @@ struct pty_process_ {
uv_loop_t *loop;
uv_async_t async;
- pty_io_t *io;
+ uv_pipe_t *in;
+ uv_pipe_t *out;
+ bool paused;
+
+ pty_read_cb read_cb;
pty_exit_cb exit_cb;
void *ctx;
};
diff --git a/src/server.h b/src/server.h
index b122d1c..794965a 100644
--- a/src/server.h
+++ b/src/server.h
@@ -56,6 +56,11 @@ struct pss_tty {
int lws_close_status;
};
+typedef struct {
+ struct pss_tty *pss;
+ bool ws_closed;
+} pty_ctx_t ;
+
struct server {
int client_count; // client count
char *prefs_json; // client preferences