aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2022-08-28 18:17:23 +0200
committerEgor Tensin <Egor.Tensin@gmail.com>2022-08-28 19:42:28 +0200
commit4835e38f6f2005073e06907021d91dde2f4d2d4f (patch)
tree76d62a95b2eb080d3f5b9e12663971ee6f96098d /src
parentadd missing #include (diff)
downloadcimple-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.c30
-rw-r--r--src/signal.h6
-rw-r--r--src/tcp_server.c18
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");