Skip to content

Commit d11617a

Browse files
committed
Remove dependency on signal() function
Replaces uses of signal() with sigaction() which should be far more portable.
1 parent bce303c commit d11617a

File tree

6 files changed

+191
-10
lines changed

6 files changed

+191
-10
lines changed

common/os_calls.c

Lines changed: 126 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2987,10 +2987,28 @@ g_set_alarm(void (*func)(int), unsigned int secs)
29872987
#if defined(_WIN32)
29882988
return 0;
29892989
#else
2990+
struct sigaction action;
2991+
29902992
/* Cancel any previous alarm to prevent a race */
29912993
unsigned int rv = alarm(0);
2992-
signal(SIGALRM, func);
2993-
(void)alarm(secs);
2994+
2995+
if (func == NULL)
2996+
{
2997+
action.sa_handler = SIG_DFL;
2998+
action.sa_flags = 0;
2999+
}
3000+
else
3001+
{
3002+
action.sa_handler = func;
3003+
action.sa_flags = SA_RESTART;
3004+
}
3005+
sigemptyset (&action.sa_mask);
3006+
3007+
sigaction(SIGALRM, &action, NULL);
3008+
if (func != NULL && secs > 0)
3009+
{
3010+
(void)alarm(secs);
3011+
}
29943012
return rv;
29953013
#endif
29963014
}
@@ -3002,7 +3020,22 @@ g_signal_child_stop(void (*func)(int))
30023020
{
30033021
#if defined(_WIN32)
30043022
#else
3005-
signal(SIGCHLD, func);
3023+
struct sigaction action;
3024+
3025+
if (func == NULL)
3026+
{
3027+
action.sa_handler = SIG_DFL;
3028+
action.sa_flags = 0;
3029+
}
3030+
else
3031+
{
3032+
action.sa_handler = func;
3033+
// Don't need to know when children are stopped or started
3034+
action.sa_flags = (SA_RESTART | SA_NOCLDSTOP);
3035+
}
3036+
sigemptyset (&action.sa_mask);
3037+
3038+
sigaction(SIGCHLD, &action, NULL);
30063039
#endif
30073040
}
30083041

@@ -3013,7 +3046,21 @@ g_signal_segfault(void (*func)(int))
30133046
{
30143047
#if defined(_WIN32)
30153048
#else
3016-
signal(SIGSEGV, func);
3049+
struct sigaction action;
3050+
3051+
if (func == NULL)
3052+
{
3053+
action.sa_handler = SIG_DFL;
3054+
action.sa_flags = 0;
3055+
}
3056+
else
3057+
{
3058+
action.sa_handler = func;
3059+
action.sa_flags = SA_RESETHAND; // This is a one-shot
3060+
}
3061+
sigemptyset (&action.sa_mask);
3062+
3063+
sigaction(SIGSEGV, &action, NULL);
30173064
#endif
30183065
}
30193066

@@ -3024,7 +3071,21 @@ g_signal_hang_up(void (*func)(int))
30243071
{
30253072
#if defined(_WIN32)
30263073
#else
3027-
signal(SIGHUP, func);
3074+
struct sigaction action;
3075+
3076+
if (func == NULL)
3077+
{
3078+
action.sa_handler = SIG_DFL;
3079+
action.sa_flags = 0;
3080+
}
3081+
else
3082+
{
3083+
action.sa_handler = func;
3084+
action.sa_flags = SA_RESTART;
3085+
}
3086+
sigemptyset (&action.sa_mask);
3087+
3088+
sigaction(SIGHUP, &action, NULL);
30283089
#endif
30293090
}
30303091

@@ -3035,7 +3096,21 @@ g_signal_user_interrupt(void (*func)(int))
30353096
{
30363097
#if defined(_WIN32)
30373098
#else
3038-
signal(SIGINT, func);
3099+
struct sigaction action;
3100+
3101+
if (func == NULL)
3102+
{
3103+
action.sa_handler = SIG_DFL;
3104+
action.sa_flags = 0;
3105+
}
3106+
else
3107+
{
3108+
action.sa_handler = func;
3109+
action.sa_flags = SA_RESTART;
3110+
}
3111+
sigemptyset (&action.sa_mask);
3112+
3113+
sigaction(SIGINT, &action, NULL);
30393114
#endif
30403115
}
30413116

@@ -3046,7 +3121,21 @@ g_signal_terminate(void (*func)(int))
30463121
{
30473122
#if defined(_WIN32)
30483123
#else
3049-
signal(SIGTERM, func);
3124+
struct sigaction action;
3125+
3126+
if (func == NULL)
3127+
{
3128+
action.sa_handler = SIG_DFL;
3129+
action.sa_flags = 0;
3130+
}
3131+
else
3132+
{
3133+
action.sa_handler = func;
3134+
action.sa_flags = SA_RESTART;
3135+
}
3136+
sigemptyset (&action.sa_mask);
3137+
3138+
sigaction(SIGTERM, &action, NULL);
30503139
#endif
30513140
}
30523141

@@ -3057,7 +3146,21 @@ g_signal_pipe(void (*func)(int))
30573146
{
30583147
#if defined(_WIN32)
30593148
#else
3060-
signal(SIGPIPE, func);
3149+
struct sigaction action;
3150+
3151+
if (func == NULL)
3152+
{
3153+
action.sa_handler = SIG_DFL;
3154+
action.sa_flags = 0;
3155+
}
3156+
else
3157+
{
3158+
action.sa_handler = func;
3159+
action.sa_flags = SA_RESTART;
3160+
}
3161+
sigemptyset (&action.sa_mask);
3162+
3163+
sigaction(SIGPIPE, &action, NULL);
30613164
#endif
30623165
}
30633166

@@ -3068,7 +3171,21 @@ g_signal_usr1(void (*func)(int))
30683171
{
30693172
#if defined(_WIN32)
30703173
#else
3071-
signal(SIGUSR1, func);
3174+
struct sigaction action;
3175+
3176+
if (func == NULL)
3177+
{
3178+
action.sa_handler = SIG_DFL;
3179+
action.sa_flags = 0;
3180+
}
3181+
else
3182+
{
3183+
action.sa_handler = func;
3184+
action.sa_flags = SA_RESTART;
3185+
}
3186+
sigemptyset (&action.sa_mask);
3187+
3188+
sigaction(SIGUSR1, &action, NULL);
30723189
#endif
30733190
}
30743191

common/os_calls.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ g_sck_get_peer_ip_address(int sck,
176176
const char *
177177
g_sck_get_peer_description(int sck,
178178
char *desc, unsigned int bytes);
179+
/**
180+
* Sleep for the specified number of milli-seconds
181+
* @param msecs Milli-seconds
182+
*
183+
* If a signal is processed, it is possible that this call will
184+
* sleep for less than the specified number of milli-seconds. This
185+
* is platform-specific
186+
*/
179187
void g_sleep(int msecs);
180188
int g_pipe(int fd[2]);
181189

@@ -275,13 +283,56 @@ int g_execvp(const char *p1, char *args[]);
275283
*/
276284
int g_execvp_list(const char *file, struct list *argv);
277285
int g_execlp3(const char *a1, const char *a2, const char *a3);
286+
/**
287+
* Set an alarm using SIGALRM
288+
* @param func Signal handler, or NULL to cancel an alarm
289+
* @param secs Number of seconds until an alarm is raised
290+
* @return Number of seconds remaining before a previously requested
291+
* alarm is raised
292+
*/
278293
unsigned int g_set_alarm(void (*func)(int), unsigned int secs);
294+
/**
295+
* Set a handler up for SIGCHLD
296+
* @param func signal handler, or NULL to restore the default handler
297+
* The handler remains in place until explicitly replaced.
298+
*/
279299
void g_signal_child_stop(void (*func)(int));
300+
/**
301+
* Set a handler up for SIGSEGV
302+
* @param func signal handler, or NULL to restore the default handler
303+
* The handler can only be called once, at which point the
304+
* default handler is restored. This is to avoid infinite loops
305+
*/
280306
void g_signal_segfault(void (*func)(int));
307+
/**
308+
* Set a handler up for SIGHUP
309+
* @param func signal handler, or NULL to restore the default handler
310+
* The handler remains in place until explicitly replaced.
311+
*/
281312
void g_signal_hang_up(void (*func)(int));
313+
/**
314+
* Set a handler up for SIGINT
315+
* @param func signal handler, or NULL to restore the default handler
316+
* The handler remains in place until explicitly replaced.
317+
*/
282318
void g_signal_user_interrupt(void (*func)(int));
319+
/**
320+
* Set a handler up for SIGTERM
321+
* @param func signal handler, or NULL to restore the default handler
322+
* The handler remains in place until explicitly replaced.
323+
*/
283324
void g_signal_terminate(void (*func)(int));
325+
/**
326+
* Set a handler up for SIGPIPE
327+
* @param func signal handler, or NULL to restore the default handler
328+
* The handler remains in place until explicitly replaced.
329+
*/
284330
void g_signal_pipe(void (*func)(int));
331+
/**
332+
* Set a handler up for SIGUSR1
333+
* @param func signal handler, or NULL to restore the default handler
334+
* The handler remains in place until explicitly replaced.
335+
*/
285336
void g_signal_usr1(void (*func)(int));
286337
int g_fork(void);
287338
int g_setgid(int pid);

tests/common/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ test_common_SOURCES = \
1818
test_list_calls.c \
1919
test_string_calls.c \
2020
test_os_calls.c \
21+
test_os_calls_signals.c \
2122
test_ssl_calls.c \
2223
test_base64.c \
2324
test_guid.c

tests/common/test_common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@ Suite *make_suite_test_ssl_calls(void);
1515
Suite *make_suite_test_base64(void);
1616
Suite *make_suite_test_guid(void);
1717

18+
TCase *make_tcase_test_os_calls_signals(void);
19+
20+
void os_calls_signals_init(void);
21+
void os_calls_signals_deinit(void);
22+
1823
#endif /* TEST_COMMON_H */

tests/common/test_common_main.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,17 @@ int main (void)
6464
* reporting when running in libcheck fork mode */
6565
setvbuf(stdout, NULL, _IONBF, 0);
6666

67-
/* Initialise the ssl module */
67+
/* Initialise modules */
6868
ssl_init();
69+
os_calls_signals_init();
6970

7071
srunner_run_all (sr, CK_ENV);
7172
number_failed = srunner_ntests_failed(sr);
7273
srunner_free(sr);
7374

7475
ssl_finish();
76+
os_calls_signals_deinit();
77+
7578
log_end();
7679
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
7780
}

tests/common/test_os_calls.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,5 +512,9 @@ make_suite_test_os_calls(void)
512512
tcase_add_test(tc_os_calls, test_g_file_is_open);
513513
tcase_add_test(tc_os_calls, test_g_sck_fd_passing);
514514
tcase_add_test(tc_os_calls, test_g_sck_fd_overflow);
515+
516+
// Add other test cases in other files
517+
suite_add_tcase(s, make_tcase_test_os_calls_signals());
518+
515519
return s;
516520
}

0 commit comments

Comments
 (0)