Directory: | src/ |
---|---|
File: | src/signal.c |
Date: | 2024-04-25 03:45:42 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 31 | 38 | 81.6% |
Branches: | 5 | 10 | 50.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Copyright (c) 2022 Egor Tensin <egor@tensin.name> | ||
3 | * This file is part of the "cimple" project. | ||
4 | * For details, see https://github.com/egor-tensin/cimple. | ||
5 | * Distributed under the MIT License. | ||
6 | */ | ||
7 | |||
8 | #include "signal.h" | ||
9 | #include "file.h" | ||
10 | #include "log.h" | ||
11 | |||
12 | #include <signal.h> | ||
13 | #include <stddef.h> | ||
14 | #include <sys/signalfd.h> | ||
15 | |||
16 | static int sigterm_signals[] = {SIGINT, SIGTERM, SIGQUIT}; | ||
17 | |||
18 | 27703 | static void sigterms_mask(sigset_t *set) | |
19 | { | ||
20 | 27703 | sigemptyset(set); | |
21 |
2/2✓ Branch 0 taken 83109 times.
✓ Branch 1 taken 27703 times.
|
110812 | for (size_t i = 0; i < sizeof(sigterm_signals) / sizeof(sigterm_signals[0]); ++i) |
22 | 83109 | sigaddset(set, sigterm_signals[i]); | |
23 | 27703 | } | |
24 | |||
25 | 82943 | static int signal_set_mask_internal(const sigset_t *new, sigset_t *old) | |
26 | { | ||
27 | 82943 | int ret = 0; | |
28 | |||
29 | 82943 | ret = pthread_sigmask(SIG_SETMASK, new, old); | |
30 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 82943 times.
|
82943 | if (ret) { |
31 | ✗ | pthread_errno(ret, "pthread_sigmask"); | |
32 | ✗ | return ret; | |
33 | } | ||
34 | |||
35 | 82943 | return ret; | |
36 | } | ||
37 | |||
38 | 27620 | int signal_set_mask(const sigset_t *new) | |
39 | { | ||
40 | 27620 | return signal_set_mask_internal(new, NULL); | |
41 | } | ||
42 | |||
43 | 27620 | int signal_block_all(sigset_t *old) | |
44 | { | ||
45 | sigset_t new; | ||
46 | 27620 | sigfillset(&new); | |
47 | 27620 | return signal_set_mask_internal(&new, old); | |
48 | } | ||
49 | |||
50 | 27620 | int signal_block_sigterms(void) | |
51 | { | ||
52 | sigset_t set; | ||
53 | 27620 | sigterms_mask(&set); | |
54 | 27620 | return signal_set_mask_internal(&set, NULL); | |
55 | } | ||
56 | |||
57 | 83 | int signalfd_create(const sigset_t *set) | |
58 | { | ||
59 | static const int flags = SFD_CLOEXEC; | ||
60 | sigset_t old; | ||
61 | 83 | int ret = 0; | |
62 | |||
63 | 83 | ret = signal_set_mask_internal(set, &old); | |
64 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
|
83 | if (ret < 0) |
65 | ✗ | return ret; | |
66 | |||
67 | 83 | ret = signalfd(-1, set, flags); | |
68 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
|
83 | if (ret < 0) |
69 | ✗ | goto restore; | |
70 | |||
71 | 83 | return ret; | |
72 | |||
73 | ✗ | restore: | |
74 | ✗ | signal_set_mask_internal(&old, NULL); | |
75 | |||
76 | ✗ | return ret; | |
77 | } | ||
78 | |||
79 | 83 | int signalfd_create_sigterms(void) | |
80 | { | ||
81 | sigset_t set; | ||
82 | 83 | sigterms_mask(&set); | |
83 | 83 | return signalfd_create(&set); | |
84 | } | ||
85 | |||
86 | 83 | void signalfd_destroy(int fd) | |
87 | { | ||
88 | 83 | file_close(fd); | |
89 | 83 | } | |
90 |