Skip to content

Commit

Permalink
Remove dependency on signal() function
Browse files Browse the repository at this point in the history
Replaces uses of signal() with sigaction() which should be far
more portable.
  • Loading branch information
matt335672 committed Oct 9, 2023
1 parent bce303c commit d11617a
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 10 deletions.
135 changes: 126 additions & 9 deletions common/os_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -2987,10 +2987,28 @@ g_set_alarm(void (*func)(int), unsigned int secs)
#if defined(_WIN32)
return 0;
#else
struct sigaction action;

/* Cancel any previous alarm to prevent a race */
unsigned int rv = alarm(0);
signal(SIGALRM, func);
(void)alarm(secs);

if (func == NULL)
{
action.sa_handler = SIG_DFL;
action.sa_flags = 0;
}
else
{
action.sa_handler = func;
action.sa_flags = SA_RESTART;
}
sigemptyset (&action.sa_mask);

sigaction(SIGALRM, &action, NULL);
if (func != NULL && secs > 0)
{
(void)alarm(secs);
}
return rv;
#endif
}
Expand All @@ -3002,7 +3020,22 @@ g_signal_child_stop(void (*func)(int))
{
#if defined(_WIN32)
#else
signal(SIGCHLD, func);
struct sigaction action;

if (func == NULL)
{
action.sa_handler = SIG_DFL;
action.sa_flags = 0;
}
else
{
action.sa_handler = func;
// Don't need to know when children are stopped or started
action.sa_flags = (SA_RESTART | SA_NOCLDSTOP);
}
sigemptyset (&action.sa_mask);

sigaction(SIGCHLD, &action, NULL);
#endif
}

Expand All @@ -3013,7 +3046,21 @@ g_signal_segfault(void (*func)(int))
{
#if defined(_WIN32)
#else
signal(SIGSEGV, func);
struct sigaction action;

if (func == NULL)
{
action.sa_handler = SIG_DFL;
action.sa_flags = 0;
}
else
{
action.sa_handler = func;
action.sa_flags = SA_RESETHAND; // This is a one-shot
}
sigemptyset (&action.sa_mask);

sigaction(SIGSEGV, &action, NULL);
#endif
}

Expand All @@ -3024,7 +3071,21 @@ g_signal_hang_up(void (*func)(int))
{
#if defined(_WIN32)
#else
signal(SIGHUP, func);
struct sigaction action;

if (func == NULL)
{
action.sa_handler = SIG_DFL;
action.sa_flags = 0;
}
else
{
action.sa_handler = func;
action.sa_flags = SA_RESTART;
}
sigemptyset (&action.sa_mask);

sigaction(SIGHUP, &action, NULL);
#endif
}

Expand All @@ -3035,7 +3096,21 @@ g_signal_user_interrupt(void (*func)(int))
{
#if defined(_WIN32)
#else
signal(SIGINT, func);
struct sigaction action;

if (func == NULL)
{
action.sa_handler = SIG_DFL;
action.sa_flags = 0;
}
else
{
action.sa_handler = func;
action.sa_flags = SA_RESTART;
}
sigemptyset (&action.sa_mask);

sigaction(SIGINT, &action, NULL);
#endif
}

Expand All @@ -3046,7 +3121,21 @@ g_signal_terminate(void (*func)(int))
{
#if defined(_WIN32)
#else
signal(SIGTERM, func);
struct sigaction action;

if (func == NULL)
{
action.sa_handler = SIG_DFL;
action.sa_flags = 0;
}
else
{
action.sa_handler = func;
action.sa_flags = SA_RESTART;
}
sigemptyset (&action.sa_mask);

sigaction(SIGTERM, &action, NULL);
#endif
}

Expand All @@ -3057,7 +3146,21 @@ g_signal_pipe(void (*func)(int))
{
#if defined(_WIN32)
#else
signal(SIGPIPE, func);
struct sigaction action;

if (func == NULL)
{
action.sa_handler = SIG_DFL;
action.sa_flags = 0;
}
else
{
action.sa_handler = func;
action.sa_flags = SA_RESTART;
}
sigemptyset (&action.sa_mask);

sigaction(SIGPIPE, &action, NULL);
#endif
}

Expand All @@ -3068,7 +3171,21 @@ g_signal_usr1(void (*func)(int))
{
#if defined(_WIN32)
#else
signal(SIGUSR1, func);
struct sigaction action;

if (func == NULL)
{
action.sa_handler = SIG_DFL;
action.sa_flags = 0;
}
else
{
action.sa_handler = func;
action.sa_flags = SA_RESTART;
}
sigemptyset (&action.sa_mask);

sigaction(SIGUSR1, &action, NULL);
#endif
}

Expand Down
51 changes: 51 additions & 0 deletions common/os_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,14 @@ g_sck_get_peer_ip_address(int sck,
const char *
g_sck_get_peer_description(int sck,
char *desc, unsigned int bytes);
/**
* Sleep for the specified number of milli-seconds
* @param msecs Milli-seconds
*
* If a signal is processed, it is possible that this call will
* sleep for less than the specified number of milli-seconds. This
* is platform-specific
*/
void g_sleep(int msecs);
int g_pipe(int fd[2]);

Expand Down Expand Up @@ -275,13 +283,56 @@ int g_execvp(const char *p1, char *args[]);
*/
int g_execvp_list(const char *file, struct list *argv);
int g_execlp3(const char *a1, const char *a2, const char *a3);
/**
* Set an alarm using SIGALRM
* @param func Signal handler, or NULL to cancel an alarm
* @param secs Number of seconds until an alarm is raised
* @return Number of seconds remaining before a previously requested
* alarm is raised
*/
unsigned int g_set_alarm(void (*func)(int), unsigned int secs);
/**
* Set a handler up for SIGCHLD
* @param func signal handler, or NULL to restore the default handler
* The handler remains in place until explicitly replaced.
*/
void g_signal_child_stop(void (*func)(int));
/**
* Set a handler up for SIGSEGV
* @param func signal handler, or NULL to restore the default handler
* The handler can only be called once, at which point the
* default handler is restored. This is to avoid infinite loops
*/
void g_signal_segfault(void (*func)(int));
/**
* Set a handler up for SIGHUP
* @param func signal handler, or NULL to restore the default handler
* The handler remains in place until explicitly replaced.
*/
void g_signal_hang_up(void (*func)(int));
/**
* Set a handler up for SIGINT
* @param func signal handler, or NULL to restore the default handler
* The handler remains in place until explicitly replaced.
*/
void g_signal_user_interrupt(void (*func)(int));
/**
* Set a handler up for SIGTERM
* @param func signal handler, or NULL to restore the default handler
* The handler remains in place until explicitly replaced.
*/
void g_signal_terminate(void (*func)(int));
/**
* Set a handler up for SIGPIPE
* @param func signal handler, or NULL to restore the default handler
* The handler remains in place until explicitly replaced.
*/
void g_signal_pipe(void (*func)(int));
/**
* Set a handler up for SIGUSR1
* @param func signal handler, or NULL to restore the default handler
* The handler remains in place until explicitly replaced.
*/
void g_signal_usr1(void (*func)(int));
int g_fork(void);
int g_setgid(int pid);
Expand Down
1 change: 1 addition & 0 deletions tests/common/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ test_common_SOURCES = \
test_list_calls.c \
test_string_calls.c \
test_os_calls.c \
test_os_calls_signals.c \
test_ssl_calls.c \
test_base64.c \
test_guid.c
Expand Down
5 changes: 5 additions & 0 deletions tests/common/test_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ Suite *make_suite_test_ssl_calls(void);
Suite *make_suite_test_base64(void);
Suite *make_suite_test_guid(void);

TCase *make_tcase_test_os_calls_signals(void);

void os_calls_signals_init(void);
void os_calls_signals_deinit(void);

#endif /* TEST_COMMON_H */
5 changes: 4 additions & 1 deletion tests/common/test_common_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,17 @@ int main (void)
* reporting when running in libcheck fork mode */
setvbuf(stdout, NULL, _IONBF, 0);

/* Initialise the ssl module */
/* Initialise modules */
ssl_init();
os_calls_signals_init();

srunner_run_all (sr, CK_ENV);
number_failed = srunner_ntests_failed(sr);
srunner_free(sr);

ssl_finish();
os_calls_signals_deinit();

log_end();
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
4 changes: 4 additions & 0 deletions tests/common/test_os_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,5 +512,9 @@ make_suite_test_os_calls(void)
tcase_add_test(tc_os_calls, test_g_file_is_open);
tcase_add_test(tc_os_calls, test_g_sck_fd_passing);
tcase_add_test(tc_os_calls, test_g_sck_fd_overflow);

// Add other test cases in other files
suite_add_tcase(s, make_tcase_test_os_calls_signals());

return s;
}

0 comments on commit d11617a

Please sign in to comment.