diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2022-08-28 18:17:23 +0200 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2022-08-28 19:42:28 +0200 |
commit | 4835e38f6f2005073e06907021d91dde2f4d2d4f (patch) | |
tree | 76d62a95b2eb080d3f5b9e12663971ee6f96098d /src | |
parent | add missing #include (diff) | |
download | cimple-4835e38f6f2005073e06907021d91dde2f4d2d4f.tar.gz cimple-4835e38f6f2005073e06907021d91dde2f4d2d4f.zip |
don't use the latest glibc features
pthread_attr_setsigmask_np is only available since 2.32, which is too
modern.
Diffstat (limited to '')
-rw-r--r-- | src/signal.c | 30 | ||||
-rw-r--r-- | src/signal.h | 6 | ||||
-rw-r--r-- | src/tcp_server.c | 18 |
3 files changed, 40 insertions, 14 deletions
diff --git a/src/signal.c b/src/signal.c index a0b9c3d..c3ea7c3 100644 --- a/src/signal.c +++ b/src/signal.c @@ -1,26 +1,36 @@ #include "signal.h" #include "log.h" -#include <pthread.h> #include <signal.h> volatile sig_atomic_t global_stop_flag = 0; -int signal_set_thread_attr(pthread_attr_t *attr) +int signal_set(const sigset_t *new, sigset_t *old) { int ret = 0; + ret = sigprocmask(SIG_SETMASK, new, old); + if (ret < 0) { + print_errno("sigprocmask"); + return ret; + } + + return ret; +} + +int signal_block_parent(sigset_t *old) +{ + sigset_t new; + sigfillset(&new); + return signal_set(&new, old); +} + +int signal_block_child() +{ sigset_t set; sigemptyset(&set); sigaddset(&set, SIGINT); sigaddset(&set, SIGQUIT); sigaddset(&set, SIGTERM); - - ret = pthread_attr_setsigmask_np(attr, &set); - if (ret) { - pthread_print_errno(ret, "pthread_attr_setsigmask_np"); - return ret; - } - - return ret; + return signal_set(&set, NULL); } diff --git a/src/signal.h b/src/signal.h index d06ab6d..95dca41 100644 --- a/src/signal.h +++ b/src/signal.h @@ -3,7 +3,6 @@ #include "compiler.h" -#include <pthread.h> #include <signal.h> #include <string.h> @@ -25,6 +24,9 @@ static __attribute__((constructor)) void signal_handler_install() sigaction(SIGTERM, &sa, NULL); } -int signal_set_thread_attr(pthread_attr_t *attr); +int signal_set(const sigset_t *new, sigset_t *old); + +int signal_block_parent(sigset_t *old); +int signal_block_child(); #endif diff --git a/src/tcp_server.c b/src/tcp_server.c index 47317e7..b536507 100644 --- a/src/tcp_server.c +++ b/src/tcp_server.c @@ -30,7 +30,15 @@ struct child_context { static void *connection_thread(void *_ctx) { struct child_context *ctx = (struct child_context *)_ctx; + int ret = 0; + + ret = signal_block_child(); + if (ret < 0) + goto close; + ctx->handler(ctx->fd, ctx->arg); + +close: check_errno(close(ctx->fd), "close"); free(ctx); return NULL; @@ -40,6 +48,7 @@ int tcp_server_accept(const struct tcp_server *server, tcp_server_conn_handler h { struct child_context *ctx; pthread_attr_t child_attr; + sigset_t old_mask; pthread_t child; int conn_fd, ret = 0; @@ -68,20 +77,25 @@ int tcp_server_accept(const struct tcp_server *server, tcp_server_conn_handler h goto destroy_attr; } - ret = signal_set_thread_attr(&child_attr); + ret = signal_block_parent(&old_mask); if (ret < 0) goto destroy_attr; ret = pthread_create(&child, &child_attr, connection_thread, ctx); if (ret) { pthread_print_errno(ret, "pthread_create"); - goto destroy_attr; + goto restore_mask; } + signal_set(&old_mask, NULL); + pthread_check(pthread_attr_destroy(&child_attr), "pthread_attr_destroy"); return ret; +restore_mask: + signal_set(&old_mask, NULL); + destroy_attr: pthread_check(pthread_attr_destroy(&child_attr), "pthread_attr_destroy"); |