mirror of
https://github.com/tsl0922/ttyd.git
synced 2025-12-23 04:14:18 +01:00
server: improve signal handling
This commit is contained in:
@@ -106,21 +106,9 @@ check_host_origin(struct lws *wsi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_client_destroy(struct tty_client *client) {
|
tty_client_free(struct tty_client *client) {
|
||||||
if (client->pid <= 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
// kill process (group) and free resource
|
|
||||||
int pgid = getpgid(client->pid);
|
|
||||||
int pid = pgid > 0 ? -pgid : client->pid;
|
|
||||||
if (kill(pid, server->sig_code) != 0) {
|
|
||||||
if (errno == ESRCH)
|
|
||||||
goto cleanup;
|
|
||||||
lwsl_err("kill: %d, errno: %d (%s)\n", pid, errno, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
uv_read_stop((uv_stream_t *) &client->pipe);
|
uv_read_stop((uv_stream_t *) &client->pipe);
|
||||||
|
uv_signal_stop(&client->watcher);
|
||||||
|
|
||||||
close(client->pty);
|
close(client->pty);
|
||||||
|
|
||||||
@@ -164,6 +152,21 @@ read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
|
|||||||
uv_read_stop(stream);
|
uv_read_stop(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
child_cb(uv_signal_t *handle, int signum) {
|
||||||
|
struct tty_client *client;
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
client = (struct tty_client *) handle->data;
|
||||||
|
status = wait_proc(client->pid, &pid);
|
||||||
|
if (pid > 0) {
|
||||||
|
lwsl_notice("process exited with code %d, pid: %d\n", status, pid);
|
||||||
|
client->pid = 0;
|
||||||
|
tty_client_free(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spawn_process(struct tty_client *client) {
|
spawn_process(struct tty_client *client) {
|
||||||
// append url args to arguments
|
// append url args to arguments
|
||||||
@@ -177,6 +180,8 @@ spawn_process(struct tty_client *client) {
|
|||||||
}
|
}
|
||||||
argv[n] = NULL;
|
argv[n] = NULL;
|
||||||
|
|
||||||
|
uv_signal_start(&client->watcher, child_cb, SIGCHLD);
|
||||||
|
|
||||||
int pty;
|
int pty;
|
||||||
pid_t pid = forkpty(&pty, NULL, NULL, NULL);
|
pid_t pid = forkpty(&pty, NULL, NULL, NULL);
|
||||||
if (pid < 0) { /* error */
|
if (pid < 0) { /* error */
|
||||||
@@ -214,6 +219,18 @@ spawn_process(struct tty_client *client) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kill_process(pid_t pid, int sig) {
|
||||||
|
if (pid <= 0) return;
|
||||||
|
|
||||||
|
// kill process (group) and free resource
|
||||||
|
lwsl_notice("killing process %d with signal %d\n", pid, sig);
|
||||||
|
int pgid = getpgid(pid);
|
||||||
|
if (kill(pgid > 0 ? -pgid : pid, sig) != 0) {
|
||||||
|
lwsl_err("kill: %d, errno: %d (%s)\n", pid, errno, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
|
callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
|
||||||
void *user, void *in, size_t len) {
|
void *user, void *in, size_t len) {
|
||||||
@@ -250,8 +267,11 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
|
|||||||
client->buffer = NULL;
|
client->buffer = NULL;
|
||||||
client->pty_len = 0;
|
client->pty_len = 0;
|
||||||
client->argc = 0;
|
client->argc = 0;
|
||||||
|
client->loop = server->loop;
|
||||||
|
|
||||||
uv_pipe_init(server->loop, &client->pipe, 0);
|
uv_pipe_init(client->loop, &client->pipe, 0);
|
||||||
|
uv_signal_init(client->loop, &client->watcher);
|
||||||
|
client->watcher.data = client;
|
||||||
|
|
||||||
if (server->url_arg) {
|
if (server->url_arg) {
|
||||||
while (lws_hdr_copy_fragment(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_URI_ARGS, n++) > 0) {
|
while (lws_hdr_copy_fragment(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_URI_ARGS, n++) > 0) {
|
||||||
@@ -394,7 +414,7 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
|
|||||||
case LWS_CALLBACK_CLOSED:
|
case LWS_CALLBACK_CLOSED:
|
||||||
server->client_count--;
|
server->client_count--;
|
||||||
lwsl_notice("WS closed from %s, clients: %d\n", client->address, server->client_count);
|
lwsl_notice("WS closed from %s, clients: %d\n", client->address, server->client_count);
|
||||||
tty_client_destroy(client);
|
kill_process(client->pid, server->sig_code);
|
||||||
if (server->once && server->client_count == 0) {
|
if (server->once && server->client_count == 0) {
|
||||||
lwsl_notice("exiting due to the --once option.\n");
|
lwsl_notice("exiting due to the --once option.\n");
|
||||||
force_exit = true;
|
force_exit = true;
|
||||||
|
|||||||
10
src/server.c
10
src/server.c
@@ -174,8 +174,6 @@ tty_server_free(struct tty_server *ts) {
|
|||||||
void
|
void
|
||||||
signal_cb(uv_signal_t *watcher, int signum) {
|
signal_cb(uv_signal_t *watcher, int signum) {
|
||||||
char sig_name[20];
|
char sig_name[20];
|
||||||
pid_t pid;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
switch (watcher->signum) {
|
switch (watcher->signum) {
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
@@ -183,12 +181,6 @@ signal_cb(uv_signal_t *watcher, int signum) {
|
|||||||
get_sig_name(watcher->signum, sig_name, sizeof(sig_name));
|
get_sig_name(watcher->signum, sig_name, sizeof(sig_name));
|
||||||
lwsl_notice("received signal: %s (%d), exiting...\n", sig_name, watcher->signum);
|
lwsl_notice("received signal: %s (%d), exiting...\n", sig_name, watcher->signum);
|
||||||
break;
|
break;
|
||||||
case SIGCHLD:
|
|
||||||
status = wait_proc(-1, &pid);
|
|
||||||
if (pid > 0) {
|
|
||||||
lwsl_notice("process exited with code %d, pid: %d\n", status, pid);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
default:
|
default:
|
||||||
signal(SIGABRT, SIG_DFL);
|
signal(SIGABRT, SIG_DFL);
|
||||||
abort();
|
abort();
|
||||||
@@ -493,7 +485,7 @@ main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if LWS_LIBRARY_VERSION_MAJOR >= 3
|
#if LWS_LIBRARY_VERSION_MAJOR >= 3
|
||||||
int sig_nums[] = {SIGINT, SIGTERM, SIGCHLD};
|
int sig_nums[] = {SIGINT, SIGTERM};
|
||||||
int ns = sizeof(sig_nums)/sizeof(sig_nums[0]);
|
int ns = sizeof(sig_nums)/sizeof(sig_nums[0]);
|
||||||
uv_signal_t signals[ns];
|
uv_signal_t signals[ns];
|
||||||
for (int i = 0; i < ns; i++) {
|
for (int i = 0; i < ns; i++) {
|
||||||
|
|||||||
@@ -34,11 +34,12 @@ struct tty_client {
|
|||||||
|
|
||||||
int pid;
|
int pid;
|
||||||
int pty;
|
int pty;
|
||||||
int exit_status;
|
|
||||||
char *pty_buffer;
|
char *pty_buffer;
|
||||||
ssize_t pty_len;
|
ssize_t pty_len;
|
||||||
|
|
||||||
|
uv_loop_t *loop;
|
||||||
uv_pipe_t pipe;
|
uv_pipe_t pipe;
|
||||||
|
uv_signal_t watcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pss_http {
|
struct pss_http {
|
||||||
|
|||||||
Reference in New Issue
Block a user