Merge branch 'signals-tests-2' into 'master'

Add a WIP signals test suite

See merge request redox-os/relibc!652
This commit is contained in:
Jeremy Soller
2025-04-20 20:00:00 +00:00
58 changed files with 2997 additions and 3 deletions
+54 -3
View File
@@ -29,14 +29,12 @@ EXPECT_NAMES=\
locale \
math \
netdb/getaddrinfo \
ptrace \
regex \
select \
setjmp \
sigaction \
sigaltstack \
signal \
sigsetjmp \
stdio/all \
stdio/buffer \
stdio/dprintf \
@@ -122,7 +120,6 @@ EXPECT_NAMES=\
unistd/fsync \
unistd/ftruncate \
unistd/getopt \
unistd/getopt_long \
unistd/pipe \
unistd/rmdir \
waitpid \
@@ -130,6 +127,7 @@ EXPECT_NAMES=\
kill-waitpid \
# unistd/sleep \
unistd/swab \
unistd/getopt_long \
unistd/write \
wchar/fgetwc \
wchar/fwide \
@@ -183,6 +181,59 @@ NAMES=\
pwd \
sa_restart \
sigchld \
signals/kill-self \
signals/kill0-self \
signals/kill-invalid \
signals/kill-permission \
signals/killpg-esrch \
signals/killpg-invalid \
signals/killpg0-self \
signals/kill-group \
signals/kill-child \
signals/killpg-child \
signals/killpg-self \
signals/pthread_kill-invalid \
signals/pthread_kill-child \
signals/pthread_kill-self \
signals/pthread_kill0-self \
signals/raise-compliance \
signals/sigismember-invalid \
signals/sigismember-valid \
signals/sigaddset-add \
signals/sigdelset-delete \
signals/signal-h \
signals/signal-h-2 \
signals/signal-handle_return \
signals/signal-handler \
signals/signal-handler2 \
signals/signal-ignore \
signals/signal-invalid \
signals/signal-uncatchable \
signals/sigprocmask-3 \
signals/sigprocmask-4 \
signals/sigprocmask-5 \
signals/sigprocmask-6 \
signals/sigprocmask-7 \
signals/sigprocmask-8 \
signals/sigprocmask-9 \
signals/sigprocmask-10 \
signals/sigprocmask-11 \
signals/sigprocmask-12 \
signals/sigpause-invalid \
signals/sigpause-revert \
signals/sigpause-suspend \
signals/sigprocmask-blocksingle \
signals/sigprocmask-block \
signals/sigrelse-1 \
signals/sigrelse-2 \
signals/sigrelse-3 \
signals/sigset-1 \
signals/sigset-10 \
signals/sigset-2 \
signals/sigset-3 \
signals/sigset-4 \
signals/sigset-5 \
signals/sigset-9 \
stdio/ctermid \
stdio/tempnam \
stdio/tmpnam \
+26
View File
@@ -168,6 +168,32 @@ STATUS_NAMES=(\
sigchld \
stdio/ctermid \
sigqueue \
signals/kill-self \
signals/kill0-self \
signals/kill-invalid \
signals/kill-permission \
signals/killpg-esrch \
signals/killpg-invalid \
signals/killpg0-self \
signals/pthread_kill-invalid \
signals/pthread_kill0-self \
signals/raise-compliance \
signals/sigismember-invalid \
signals/sigismember-valid \
signals/signal-handle_return \
signals/signal-handler \
signals/signal-handler2 \
signals/signal-ignore \
signals/signal-invalid \
signals/signal-uncatchable \
signals/sigprocmask-6 \
signals/sigprocmask-7 \
signals/sigprocmask-8 \
signals/sigprocmask-9 \
signals/sigprocmask-11 \
signals/sigprocmask-blocksingle \
signals/sigrelse-2 \
signals/sigrelse-3 \
stdio/tempnam \
stdio/tmpnam \
stdlib/bsearch \
+96
View File
@@ -0,0 +1,96 @@
#include <assert.h>
#include <signal.h>
#include <sys/wait.h>
#include "signals_list.h"
#include "../test_helpers.h"
/*
* Test signal catching when being signalled from parent.
* Skip SIGKILL and SIGSTOP as these are not catchable.
*/
volatile sig_atomic_t sig_handled = 0;
void sig_handler(int signo)
{
(void) signo;
sig_handled = 1;
}
void child_proc(int signum)
{
sigset_t sig_set;
int status;
sig_handled = 0;
status = sigemptyset(&sig_set);
ERROR_IF(sigemptyset, status, == -1);
status = sigaddset(&sig_set, signum);
ERROR_IF(sigaddset, status, == -1);
struct sigaction act;
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(signum, &act, NULL);
status = sleep(10);
ERROR_IF(sleep, status, == 0);
assert(sig_handled != 0);
exit(EXIT_SUCCESS);
}
void parent(int signum, pid_t pid)
{
int status;
sleep(1);
status = kill(pid, signum);
ERROR_IF(kill, status, != 0);
pid = wait(&status);
ERROR_IF(wait, pid, == (pid_t)-1);
if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS)
{
printf("Child did not exit normally.\n");
exit(EXIT_FAILURE);
}
else
{
return;
}
}
void kill_child(int signum)
{
int pid;
if ((pid = fork()) == 0)
{
child_proc(signum);
}
else
{
parent(signum, pid);
}
}
int main()
{
for (long unsigned int i = 1; i < sizeof(signals_list)/sizeof(signals_list[0]); i++)
{
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP)
{
continue;
}
printf("Testing for signal %s (%d)\n", strsignal(sig), sig);
kill_child(sig);
}
return EXIT_SUCCESS;
}
+61
View File
@@ -0,0 +1,61 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "signals_list.h"
#include "../test_helpers.h"
// this test is to make sure that when a negative pid is supplied to kill, all the processes in that group will be killed
int handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
handler_called = 1;
return;
}
int kill_group(int signum)
{
int pgrp;
struct sigaction act;
int status;
act.sa_handler=sig_handler;
act.sa_flags=0;
status = sigemptyset(&act.sa_mask);
ERROR_IF(sigemptyset, status, == -1);
status = sigaction(signum, &act, 0);
ERROR_IF(sigaction, status, == -1);
status = getpgrp();
pgrp = status;
ERROR_IF(getpgrp, status, == -1);
status = kill(-pgrp, signum);
ERROR_IF(kill, status, != 0);
ERROR_IF(kill, handler_called, !=1);
handler_called = 0;
return EXIT_SUCCESS;
}
int main()
{
// Ensure we don't kill what was already in the process group.
int status = setpgid(0, 0);
ERROR_IF(setpgid, status, == -1);
for (unsigned int i = 0; i < sizeof(signals_list)/sizeof(signals_list[0]); i++)
{
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP)
{
continue;
}
kill_group(sig);
}
return EXIT_SUCCESS;
}
+22
View File
@@ -0,0 +1,22 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include "../test_helpers.h"
//this test ensures that sending an invalid signal will set errno to esrch
int main()
{
/*
* ESRCH
*/
int status;
status = kill(999999, 0);
ERROR_IF(kill, status, != -1);
ERROR_IF(kill, errno, != ESRCH);
return EXIT_SUCCESS;
}
+20
View File
@@ -0,0 +1,20 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include "../test_helpers.h"
// makes sure that a process is not killed if the user doesn't have permission to kill the process
int main(void)
{
int status;
// This is added in case user is root. If user is normal user, then it has no effect on the tests
setuid(1000);
status = kill(1, 0);
ERROR_IF(kill, status, != -1);
ERROR_IF(kill, errno, != EPERM);
return EXIT_SUCCESS;
}
+56
View File
@@ -0,0 +1,56 @@
#include <assert.h>
#include <signal.h>
#include "signals_list.h"
#include "../test_helpers.h"
/*
* Test signal catching when signalling self.
* Ensure all signals can be caught (other than SIGKILL and SIGSTOP).
*/
volatile sig_atomic_t handler_called = 0;
void sig_handler(int sig)
{
(void) sig;
handler_called = 1;
}
int kill_self(int sig)
{
struct sigaction act;
int status;
handler_called = 0;
act.sa_handler = sig_handler;
act.sa_flags = 0;
status = sigemptyset(&act.sa_mask);
ERROR_IF(sigemptyset, status, == -1);
status = sigaction(sig, &act, NULL);
ERROR_IF(sigaction, status, == -1);
status = kill(getpid(), sig);
ERROR_IF(kill, status, != 0);
assert(handler_called == 1);
return EXIT_SUCCESS;
}
int main()
{
for (unsigned int i = 1; i < sizeof(signals_list)/sizeof(signals_list[0]); i++)
{
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP)
{
continue;
}
kill_self(sig);
}
return EXIT_SUCCESS;
}
+16
View File
@@ -0,0 +1,16 @@
#include <signal.h>
#include "../test_helpers.h"
/*
* Send signal 0 to self. This just reports whether a signal can be sent.
*/
int main()
{
int status = 0;
status = kill(getpid(), 0);
ERROR_IF(kill, status, != 0);
return EXIT_SUCCESS;
}
+82
View File
@@ -0,0 +1,82 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include "signals_list.h"
#include "../test_helpers.h"
// test killing a child process
void sig_handler (int signo) {
(void) signo;
exit(EXIT_SUCCESS);
}
int killpg_test2(int signum)
{
int child_pid, child_pgid;
printf("we are on signal %d\n ", signum);
if ((child_pid = fork()) == 0) {
/* child here */
struct sigaction act;
act.sa_handler=sig_handler;
act.sa_flags=0;
sigemptyset(&act.sa_mask);
sigaction(signum, &act, 0);
/* change child's process group id */
setpgrp();
sigpause(SIGABRT);
return EXIT_FAILURE;
} else {
/* parent here */
int i;
sigignore(signum);
sleep(1);
child_pgid = getpgid(child_pid);
ERROR_IF(getpgid, child_pgid, == -1);
int status;
status = killpg(child_pgid, signum);
ERROR_IF(killpg, status, != 0);
status = wait(&i);
ERROR_IF(wait, status, == -1);
if (WEXITSTATUS(i) == EXIT_SUCCESS) {
printf("Child exited normally\n");
printf("Test PASSED\n");
return EXIT_SUCCESS;
} else {
printf("Child did not exit normally.\n");
printf("Test FAILED\n");
exit(EXIT_FAILURE);
}
}
return EXIT_FAILURE;
}
int main(){
int x;
for (unsigned int i = 1; i < sizeof(signals_list)/sizeof(signals_list[0]); i++)
{
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP || sig == SIGCHLD || sig == SIGINT || sig == SIGQUIT)
{
continue;
}
x = killpg_test2(sig);
if (x == EXIT_FAILURE){
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
+19
View File
@@ -0,0 +1,19 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "../test_helpers.h"
// if a user tries to kill a process that does not exist the esrch error will be returned
int main()
{
int status;
status = killpg(999999, 0);
ERROR_IF(killpg, status, !=-1);
ERROR_IF(killpg, errno, != ESRCH);
return EXIT_SUCCESS;
}
+23
View File
@@ -0,0 +1,23 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "../test_helpers.h"
// the test makes sure that if an invalid signal is passed it will return the EINVAL error
int main()
{
int pgrp;
pgrp = getpgrp();
ERROR_IF(getpgrp, pgrp, == -1);
int status;
status = killpg(pgrp, -1);
ERROR_IF(killpg, status, != -1);
ERROR_IF(killpg, errno, != EINVAL);
return EXIT_SUCCESS;
}
+57
View File
@@ -0,0 +1,57 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "signals_list.h"
#include "../test_helpers.h"
// Test that the killpg() function shall send signal sig to the process
// group specified by prgp.
void sig_handler(int signo)
{
// printf("Caught signal %d being tested!\n", signo);
// printf("Test PASSED\n");
(void) signo;
return;
}
int killpg_test1(int signum)
{
int pgrp;
struct sigaction act;
act.sa_handler=sig_handler;
act.sa_flags=0;
int status = sigemptyset(&act.sa_mask);
ERROR_IF(sigemptyset, status, == -1);
status = sigaction(signum, &act, 0);
ERROR_IF(sigaction, status, == -1);
pgrp = getpgrp();
ERROR_IF(getpgrp, pgrp, == -1);
status = killpg(pgrp, signum);
ERROR_IF(killpg, status, != 0);
return EXIT_SUCCESS;
}
int main(){
// UB if pg == 1, so set it here first
int status = setpgid(0, 0);
ERROR_IF(setpgid, status, == -1);
for (unsigned int i = 0; i < sizeof(signals_list)/sizeof(signals_list[0]); i++)
{
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP)
{
continue;
}
killpg_test1(sig);
}
return EXIT_SUCCESS;
}
+25
View File
@@ -0,0 +1,25 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../test_helpers.h"
// test sending signal 0 to self will killpg
int main()
{
// UB if pg == 1, so set it here first
int err = setpgid(0, 0);
ERROR_IF(setpgid, err, == -1);
int pgrp;
pgrp = getpgrp();
ERROR_IF(getpgrp, pgrp, == -1);
int status;
status = killpg(pgrp, 0);
ERROR_IF(killpg, status, != 0);
return EXIT_SUCCESS;
}
+46
View File
@@ -0,0 +1,46 @@
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "../test_helpers.h"
//test with pthread_kill to kill a child process
void * thread_function(void *arg)
{
/* Does nothing */
(void) arg;
pthread_exit((void*)0);
/* To please some compilers */
return NULL;
}
int main()
{
pthread_t child_thread;
pthread_t invalid_tid;
int rc;
rc = pthread_create(&child_thread, NULL,
thread_function, NULL);
ERROR_IF(pthread_create, rc, != 0);
rc = pthread_join(child_thread, NULL);
ERROR_IF(pthread_join, rc, != 0);
// Now the child_thread exited, it is an invalid tid
memcpy(&invalid_tid, &child_thread,
sizeof(pthread_t));
sleep(3);
int status;
status = pthread_kill(invalid_tid, 0);
ERROR_IF(pthread_kill, status, != ESRCH);
exit(EXIT_SUCCESS);
}
+23
View File
@@ -0,0 +1,23 @@
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include "../test_helpers.h"
//test with pthread_kill making sure sending an invalid signal returns einval
int main()
{
pthread_t main_thread;
main_thread = pthread_self();
int status;
status = pthread_kill(main_thread, -1);
ERROR_IF(pthread_kill, status, != EINVAL);
return EXIT_SUCCESS;
}
+94
View File
@@ -0,0 +1,94 @@
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
//test pthread_kill on self
# define INTHREAD 0
# define INMAIN 1
# define SIGTOTEST SIGABRT
int sem1; /* Manual semaphore */
volatile sig_atomic_t handler_called = 0;
int count = 1;
struct signal {
int signum;
};
void handler() {
handler_called = 1;
return;
}
void *a_thread_func( void *arg)
{
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
sigaction(((struct signal *)arg)->signum, &act, 0);
sem1=INMAIN;
while(sem1==INMAIN)
sleep(1);
// sleep(50);
handler_called=-1;
pthread_exit(0);
return NULL;
}
int pthread_kill_test1(int signum)
{
pthread_t new_th;
sem1=INTHREAD;
struct signal arg;
arg.signum = signum;
int status;
status = pthread_create(&new_th, NULL, a_thread_func, &arg);
ERROR_IF(pthread_create, status, != 0);
while(sem1==INTHREAD)
sleep(1);
status = pthread_kill(new_th, signum);
ERROR_IF(pthread_kill, status, != 0);
sleep(2);
sem1=INTHREAD;
while(handler_called==0)
sleep(1);
ERROR_IF(pthread_kill, handler_called, == -1);
ERROR_IF(pthread_kill, handler_called, == 0);
handler_called = 0;
return EXIT_SUCCESS;
}
int main(){
for (unsigned int i = 0; i < sizeof(signals_list)/sizeof(signals_list[0]); i++)
{
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP)
{
continue;
}
pthread_kill_test1(sig);
}
return EXIT_SUCCESS;
}
+21
View File
@@ -0,0 +1,21 @@
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../test_helpers.h"
// test sending 0 with pthread_kill to self
int main()
{
pthread_t main_thread;
main_thread = pthread_self();
int status;
status = pthread_kill(main_thread, 0);
ERROR_IF(pthread_kill, status, != 0);
return EXIT_SUCCESS;
}
+48
View File
@@ -0,0 +1,48 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
// The raise() function shall send the signal sig to the executing [CX] [Option Start] thread or process. [Option End] If a signal handler is called, the raise() function shall not return until after the signal handler does.
// [CX] [Option Start] The effect of the raise() function shall be equivalent to calling: pthread_kill(pthread_self(), sig);
void sig_hand(int i)
{
if (i < 1 || i > 32){
printf("an invalid signal was given: %d", i);
}
static int count = 1;
count++;
printf("%d \n", count);
if (count == 32) {
printf("reached 32nd signal\n");
return;
}
else{
printf("count is %d\n", count);
}
}
void raise_test(int sig){
signal(sig, sig_hand);
raise(sig);
}
int main(void)
{
for (int i = 0; i < N_SIGNALS; i++)
{
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP)
{
continue;
}
raise_test(sig);
}
return EXIT_SUCCESS;
}
+39
View File
@@ -0,0 +1,39 @@
#define _OPEN_SYS
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include "signals_list.h"
#include "../test_helpers.h"
// The sigaddset() function adds the individual signal specified by the signo to the signal set pointed to by set.
// Applications shall call either sigemptyset() or sigfillset() at least once for each object of type sigset_t prior to any other use of that object. If such an object is not initialized in this way, but is nonetheless supplied as an argument to any of pthread_sigmask(), sigaction(), sigaddset(), sigdelset(), sigismember(), sigpending(), sigprocmask(), sigsuspend(), sigtimedwait(), sigwait(), or sigwaitinfo(), the results are undefined.
void addset_test(sigset_t *sigset, int signal){
int status;
status = sigismember(sigset, signal);
ERROR_IF(sigismember, status, != 0);
status = sigaddset(sigset, signal);
ERROR_IF(sigaddset, status, != 0);
status = sigismember(sigset, signal);
ERROR_IF(sigismember, status, != 1);
}
int main() {
sigset_t sigset;
sigemptyset(&sigset);
for (int i = 1; i < N_SIGNALS; i++){
int sig = signals_list[i-1].signal;
addset_test(&sigset, sig);
}
}
+36
View File
@@ -0,0 +1,36 @@
#define _OPEN_SYS
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include "signals_list.h"
#include "../test_helpers.h"
// The sigdelset() function deletes the individual signal specified by signo from the signal set pointed to by set.
// Applications should call either sigemptyset() or sigfillset() at least once for each object of type sigset_t prior to any other use of that object. If such an object is not initialized in this way, but is nonetheless supplied as an argument to any of pthread_sigmask(), sigaction(), sigaddset(), sigdelset(), sigismember(), sigpending(), sigprocmask(), sigsuspend(), sigtimedwait(), sigwait(), or sigwaitinfo(), the results are undefined.
void delset_test(sigset_t *sigset, int signal){
int status;
status = sigismember(sigset, signal);
ERROR_IF(sigismember, status, != 1);
status = sigdelset(sigset, signal);
ERROR_IF(sigdelset, status, != 0);
status = sigismember(sigset, signal);
ERROR_IF(sigismember, status, != 0);
}
int main() {
sigset_t sigset;
sigfillset(&sigset);
for (int i = 1; i < N_SIGNALS; i++){
int sig = signals_list[i-1].signal;
delset_test(&sigset, sig);
}
}
+21
View File
@@ -0,0 +1,21 @@
#define _OPEN_SYS
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include "../test_helpers.h"
// test to make sure that if you pass an invalid signal to sigismember it will return EINVAL
int main() {
sigset_t sigset;
int status;
sigfillset(&sigset);
status = sigismember(&sigset, -1);
ERROR_IF(sigismember, status, != -1);
ERROR_IF(sigismember, errno, != EINVAL);
return EXIT_SUCCESS;
}
+42
View File
@@ -0,0 +1,42 @@
#define _OPEN_SYS
#include <stdio.h>
#include <signal.h>
#include "signals_list.h"
#include "../test_helpers.h"
// The sigismember() function shall test whether the signal specified by signo is a member of the set pointed to by set.
// Applications should call either sigemptyset() or sigfillset() at least once for each object of type sigset_t prior to any other use of that object. If such an object is not initialized in this way, but is nonetheless supplied as an argument to any of pthread_sigmask(), sigaction(), sigaddset(), sigdelset(), sigismember(), sigpending(), sigprocmask(), sigsuspend(), sigtimedwait(), sigwait(), or sigwaitinfo(), the results are undefined.
void check_full(sigset_t set, int signum) {
if (!sigismember(&set, signum)) {
exit(EXIT_FAILURE);
}
}
void check_empty(sigset_t set, int signum) {
if (sigismember(&set, signum)) {
exit(EXIT_FAILURE);
}
}
int main() {
sigset_t sigset;
sigfillset(&sigset);
for (int i=1; i<N_SIGNALS; i++){
int sig = signals_list[i-1].signal;
check_full(sigset, sig);
}
sigemptyset(&sigset);
for (int i=1; i<N_SIGNALS; i++){
int sig = signals_list[i-1].signal;
check_empty(sigset, sig);
}
}
+32
View File
@@ -0,0 +1,32 @@
#include "../test_helpers.h"
#include <signal.h>
/*
* This is a test to ensure all required items for signal.h are defined.
* The definitions follow the order described in
* <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/signal.h.html>
*/
void handler(int sig_num)
{
(void)sig_num;
}
void action(int sig_num, siginfo_t *info, void *context)
{
(void)sig_num;
(void)info;
(void)context;
}
int main()
{
int (*sh)(int) __attribute__((unused)) = sighold;
int (*sigig)(int) __attribute__((unused)) = sigignore;
int (*sigintr)(int, int) __attribute__((unused)) = siginterrupt;
int (*paws)(int) __attribute__((unused)) = sigpause;
int (*srls)(int) __attribute__((unused)) = sigrelse;
void (*(*sset)(int, void (*)(int)))(int) __attribute__((unused)) = sigset;
return EXIT_SUCCESS;
}
+232
View File
@@ -0,0 +1,232 @@
#include "../test_helpers.h"
#include <signal.h>
/*
* This is a test to ensure all required items for signal.h are defined.
* The definitions follow the order described in
* <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/signal.h.html>
*/
void handler(int sig_num)
{
(void)sig_num;
}
void action(int sig_num, siginfo_t *info, void *context)
{
(void)sig_num;
(void)info;
(void)context;
}
int main()
{
void (*sig_dfl)(int) __attribute__((unused)) = SIG_DFL;
void (*sig_err)(int) __attribute__((unused)) = SIG_ERR;
void (*sig_ign)(int) __attribute__((unused)) = SIG_IGN;
pthread_t pthread_num __attribute__((unused)) = 0;
size_t size __attribute__((unused)) = 0;
uid_t uid __attribute__((unused)) = 0;
sig_atomic_t atomic __attribute__((unused)) = 0;
sigset_t sig_set __attribute__((unused)) ;
pid_t pid __attribute__((unused)) = 0;
pthread_attr_t *attr __attribute__((unused)) = NULL;
// struct sigevent sev;
union sigval sv;
sv.sival_int = (int)0;
sv.sival_ptr = (void *)0;
// sev.sigev_notify = (int)0;
// sev.sigev_notify = SIGEV_NONE;
// sev.sigev_notify = SIGEV_SIGNAL;
// sev.sigev_notify = SIGEV_THREAD;
// sev.sigev_signo = (int)0;
// sev.sigev_value = sv;
// sev.sigev_value.sival_int = (int)0;
// sev.sigev_value.sival_ptr = (void *)0;
// sev.sigev_notify_function = (void (*)(union sigval))0;
// sev.sigev_notify_attributes = (pthread_attr_t *)0;
int rt_sig_num __attribute__((unused)) = SIGRTMIN;
rt_sig_num = SIGRTMAX;
// rt_sig_num = SIG2STR_MAX;
// sev.sigev_signo = SIGABRT;
// sev.sigev_signo = SIGALRM;
// sev.sigev_signo = SIGBUS;
// sev.sigev_signo = SIGCHLD;
// sev.sigev_signo = SIGCONT;
// sev.sigev_signo = SIGFPE;
// sev.sigev_signo = SIGHUP;
// sev.sigev_signo = SIGILL;
// sev.sigev_signo = SIGINT;
// sev.sigev_signo = SIGKILL;
// sev.sigev_signo = SIGPIPE;
// sev.sigev_signo = SIGQUIT;
// sev.sigev_signo = SIGSEGV;
// sev.sigev_signo = SIGSTOP;
// sev.sigev_signo = SIGTERM;
// sev.sigev_signo = SIGTSTP;
// sev.sigev_signo = SIGTTIN;
// sev.sigev_signo = SIGTTOU;
// sev.sigev_signo = SIGUSR1;
// sev.sigev_signo = SIGUSR2;
// sev.sigev_signo = SIGWINCH;
// sev.sigev_signo = SIGPOLL;
// sev.sigev_signo = SIGPROF;
// sev.sigev_signo = SIGSYS;
// sev.sigev_signo = SIGTRAP;
// sev.sigev_signo = SIGURG;
// sev.sigev_signo = SIGVTALRM;
// sev.sigev_signo = SIGXCPU;
// sev.sigev_signo = SIGXFSZ;
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sa.sa_handler = SIG_DFL;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = (int)0;
sa.sa_sigaction = action;
#ifndef SA_NOCLDSTOP
#error "Required constant not defined SA_NOCLDSTOP"
#endif
#ifndef SIG_BLOCK
#error "Required constant not defined SIG_BLOCK"
#endif
#ifndef SIG_UNBLOCK
#error "Required constant not defined SIG_UNBLOCK"
#endif
#ifndef SIG_SETMASK
#error "Required constant not defined SIG_SETMASK"
#endif
#ifndef SA_ONSTACK
#error "Required constant not defined SA_ONSTACK"
#endif
#ifndef SA_RESETHAND
#error "Required constant not defined SA_RESETHAND"
#endif
#ifndef SA_RESTART
#error "Required constant not defined SA_RESTART"
#endif
#ifndef SA_SIGINFO
#error "Required constant not defined SA_SIGINFO"
#endif
#ifndef SA_NOCLDWAIT
#error "Required constant not defined SA_NOCLDWAIT"
#endif
#ifndef SA_NODEFER
#error "Required constant not defined SA_NODEFER"
#endif
#ifndef SS_ONSTACK
#error "Required constant not defined SS_ONSTACK"
#endif
#ifndef SS_DISABLE
#error "Required constant not defined SS_DISABLE"
#endif
#ifndef MINSIGSTKSZ
#error "Required constant not defined MINSIGSTKSZ"
#endif
#ifndef SIGSTKSZ
#error "Required constant not defined SIGSTKSZ"
#endif
// struct ucontext_t uc;
mcontext_t mc __attribute__((unused));
// add parts to ucontext_t
// uc.uc_link = NULL;
// uc.uc_sigmask = 0;
// uc.uc_stack = NULL;
// uc.uc_mcontext = NULL;
stack_t st __attribute__((unused));
st.ss_sp = NULL;
st.ss_size = (size_t)0;
st.ss_flags = (int)0;
siginfo_t si __attribute__((unused));
si.si_signo = SIGHUP;
si.si_code = (int)0;
si.si_errno = (int)0;
si.si_pid = (pid_t)0;
si.si_uid = (uid_t)0;
si.si_addr = NULL;
si.si_status = (int)0;
si.si_value = sv;
// si.si_code = ILL_ILLOPC;
// si.si_code = ILL_ILLOPN;
// si.si_code = ILL_ILLADR;
// si.si_code = ILL_ILLTRP;
// si.si_code = ILL_PRVOPC;
// si.si_code = ILL_PRVREG;
// si.si_code = ILL_COPROC;
// si.si_code = ILL_BADSTK;
// si.si_code = FPE_INTDIV;
// si.si_code = FPE_INTOVF;
// si.si_code = FPE_FLTDIV;
// si.si_code = FPE_FLTOVF;
// si.si_code = FPE_FLTUND;
// si.si_code = FPE_FLTRES;
// si.si_code = FPE_FLTINV;
// si.si_code = FPE_FLTSUB;
// si.si_code = SEGV_MAPERR;
// si.si_code = SEGV_ACCERR;
// si.si_code = BUS_ADRALN;
// si.si_code = BUS_ADRERR;
// si.si_code = BUS_OBJERR;
// si.si_code = TRAP_BRKPT;
// si.si_code = TRAP_TRACE;
// si.si_code = CLD_EXITED;
// si.si_code = CLD_KILLED;
// si.si_code = CLD_DUMPED;
// si.si_code = CLD_TRAPPED;
// si.si_code = CLD_STOPPED;
// si.si_code = CLD_CONTINUED;
// si.si_code = SI_USER;
// si.si_code = SI_QUEUE;
// si.si_code = SI_TIMER;
// si.si_code = SI_ASYNCIO;
// si.si_code = SI_MESGQ;
// void (*(*bs)(int, void (*)(int)))(int) = bsd_signal;
int (*k)(pid_t, int) __attribute__((unused))= kill;
int (*kpg)(pid_t, int) __attribute__((unused))= killpg;
void (*psig)(const siginfo_t *, const char *) __attribute__((unused))= psiginfo;
void (*ps)(int, const char *) __attribute__((unused))= psignal;
int (*ptk)(pthread_t, int) __attribute__((unused))= pthread_kill;
int (*ptsm)(int, const sigset_t *, sigset_t *) __attribute__((unused))= pthread_sigmask;
int (*r)(int) __attribute__((unused))= raise;
// int (*s2s)(int, char*) = sig2str;
int (*sact)(int, const struct sigaction *restrict,
struct sigaction *restrict) __attribute__((unused)) = sigaction;
int (*sas)(sigset_t *, int) __attribute__((unused))= sigaddset;
int (*sastk)(const stack_t *restrict, stack_t *restrict) __attribute__((unused))= sigaltstack;
int (*sds)(sigset_t *, int) __attribute__((unused))= sigdelset;
int (*ses)(sigset_t *) __attribute__((unused))= sigemptyset;
int (*sfs)(sigset_t *) __attribute__((unused))= sigfillset;
int (*ismem)(const sigset_t *, int) __attribute__((unused))= sigismember;
void ( *(*sgnl)(int, void (*)(int)))(int) __attribute__((unused))= signal;
int (*pend)(sigset_t *) __attribute__((unused))= sigpending;
int (*spmsk)(int, const sigset_t *restrict, sigset_t *restrict) __attribute__((unused))= sigprocmask;
int (*sigq)(pid_t, int, const union sigval) __attribute__((unused))= sigqueue;
int (*susp)(const sigset_t *) __attribute__((unused))= sigsuspend;
int (*stmwt)(const sigset_t *restrict, siginfo_t *restrict,
const struct timespec *restrict) __attribute__((unused))= sigtimedwait;
int (*swt)(const sigset_t *restrict, int *restrict) __attribute__((unused))= sigwait;
int (*swtinfo)(const sigset_t *restrict, siginfo_t *restrict) __attribute__((unused))= sigwaitinfo;
// int (*str2s)(const char *restrict, int *restrict) = str2sig;
return EXIT_SUCCESS;
}
+35
View File
@@ -0,0 +1,35 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "../test_helpers.h"
void SIGUSR1_handler(int signo)
{
(void) signo;
printf("do nothing useful\n");
}
void SIGUSR2_handler(int signo)
{
(void) signo;
printf("do nothing useful\n");
}
int main()
{
void (*status) (int);
status = signal(SIGUSR1, SIGUSR1_handler);
ERROR_IF(signal, status, == SIG_ERR);
status = signal(SIGUSR2, SIGUSR2_handler);
ERROR_IF(signal, status, == SIG_ERR);
status = signal(SIGUSR1,SIG_IGN);
// printf("status is %d\n", status);
// printf("SIGUSR1_handler is %d\n", SIGUSR1_handler);
ERROR_IF(signal, status, != SIGUSR1_handler);
//this seems to be a weird comparison error
return EXIT_SUCCESS;
}
+33
View File
@@ -0,0 +1,33 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "../test_helpers.h"
int handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
printf("SIGCHLD called. Inside handler\n");
handler_called = 1;
}
int main()
{
void (*status) (int);
status = signal(SIGCHLD, sig_handler);
ERROR_IF(signal, status, == SIG_ERR);
status = signal(SIGCHLD,SIG_DFL);
ERROR_IF(signal, status, != sig_handler);
//same comparison error from handle_return
raise(SIGCHLD);
if (handler_called == 1) {
return EXIT_FAILURE;
}
handler_called = 0;
return EXIT_SUCCESS;
}
+37
View File
@@ -0,0 +1,37 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
int handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
// printf("%d called. Inside handler\n", signo);
handler_called = 1;
}
int signal_test3(int signum)
{
void (*status) (int);
status = signal(signum, sig_handler);
ERROR_IF(signal, status, == SIG_ERR);
raise(signum);
ERROR_IF(raise, handler_called, != 1);
return EXIT_SUCCESS;
}
int main(){
for (unsigned int i = 0; i < sizeof(signals_list)/sizeof(signals_list[0]); i++){
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP){
continue;
}
signal_test3(sig);
}
return EXIT_SUCCESS;
}
+45
View File
@@ -0,0 +1,45 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
int handler_called = 0;
void sig_handler(int signo)
{
printf("%d called. Inside handler\n", signo);
handler_called = 1;
}
int signal_test2(int signum)
{
void (*status) (int);
status = signal(signum, sig_handler);
ERROR_IF(signal, status, == SIG_ERR);
status = signal(signum, SIG_IGN);
ERROR_IF(signal, status, != sig_handler);
// same issue as handle_return
raise(signum);
ERROR_IF(raise, handler_called, == 1);
handler_called = 0;
return EXIT_SUCCESS;
}
int main(){
for (unsigned int i = 0; i < sizeof(signals_list)/sizeof(signals_list[0]); i++){
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP){
continue;
}
signal_test2(sig);
}
return EXIT_SUCCESS;
}
+25
View File
@@ -0,0 +1,25 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "../test_helpers.h"
// test to make sure sending an invalid signal sets errno
void sig_handler(int signo)
{
(void) signo;
printf("handler does nothing useful.\n");
}
int main()
{
errno = -1;
void (*status) (int);
status = signal(-1, sig_handler);
ERROR_IF(signal, status, != SIG_ERR);
ERROR_IF(signal, errno, <= 0);
return EXIT_SUCCESS;
}
+25
View File
@@ -0,0 +1,25 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "../test_helpers.h"
//make sure you can't catch uncatchable signals
void sig_handler(int signo)
{
(void) signo;
printf("handler does nothing useful.\n");
}
int main()
{
errno = -1;
void (*status) (int);
status = signal(SIGKILL, sig_handler);
ERROR_IF(signal, status, != SIG_ERR);
ERROR_IF(signal, errno, <= 0);
return EXIT_SUCCESS;
}
+79
View File
@@ -0,0 +1,79 @@
#ifndef _SIGNALS_LIST
#define _SIGNALS_LIST 1
#include <signal.h>
#ifdef SIGSTKFLT
#endif
const int N_SIGNALS = (28
#ifdef SIGSTKFLT
+ 1
#endif
#ifdef SIGWINCH
+ 1
#endif
#ifdef SIGIO
+ 1
#endif
#ifdef SIGPWR
+ 1
#endif
#ifdef SIGUNUSED
+ 1
#endif
);
struct signalAction
{
int signal;
char action;
};
const struct signalAction signals_list[] = {
{SIGABRT, 'A'},
{SIGALRM, 'T'},
{SIGBUS, 'A'},
{SIGCHLD, 'I'},
{SIGCONT, 'C'},
{SIGFPE, 'A'},
{SIGHUP, 'T'},
{SIGILL, 'A'},
{SIGINT, 'T'},
{SIGKILL, 'T'},
{SIGPIPE, 'T'},
{SIGQUIT, 'A'},
{SIGSEGV, 'A'},
{SIGSTOP, 'S'},
{SIGTERM, 'T'},
{SIGTSTP, 'S'},
{SIGTTIN, 'S'},
{SIGTTOU, 'S'},
{SIGUSR1, 'T'},
{SIGUSR2, 'T'},
// {SIGPOLL, 'T'},
{SIGPROF, 'T'},
{SIGSYS, 'A'},
{SIGTRAP, 'A'},
{SIGURG, 'I'},
{SIGVTALRM, 'T'},
{SIGXCPU, 'A'},
{SIGXFSZ, 'A'},
#ifdef SIGSTKFLT
{SIGSTKFLT, 'T'},
#endif
#ifdef SIGWINCH
{SIGWINCH, 'I'},
#endif
#ifdef SIGIO
{SIGIO, 'T'},
#endif
#ifdef SIGPWR
{SIGPWR, 'T'},
#endif
#ifdef SIGUNUSED
{SIGUNUSED, 'A'},
#endif
};
#endif /* _SIGNALS_LIST */
+103
View File
@@ -0,0 +1,103 @@
#define _XOPEN_SOURCE 700
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
// This program verifies that sigpause() returns -1 and sets errno to EINTR
// when it returns.
#define INMAIN 0
#define INTHREAD 1
int handler_called = 0;
int returned = 0;
int return_value = 2;
int result = 2;
int sem = INMAIN;
void handler() {
// printf("signal was called\n");
handler_called = 1;
return;
}
void *d_thread_func(void *sig)
{
int signum = *(int *)sig;
printf("%d Pausing signal \n", signum);
int return_value = 0;
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
sigaction(signum, &act, 0);
return_value = sigpause(signum);
ERROR_IF(sigpause, return_value, != -1);
ERROR_IF(sigpause, errno, != EINTR);
result = 0;
if (return_value == -1) {
if (errno == EINTR) {
printf ("Test PASSED: sigpause returned -1 and set errno to EINTR\n");
result = 0;
} else {
printf ("Test FAILED: sigpause did not set errno to EINTR\n");
result = 1;
}
} else {
if (errno == EINTR) {
printf ("Test FAILED: sigpause did not return -1\n");
}
printf ("Test FAILED: sigpause did not set errno to EINTR\n");
printf ("Test FAILED: sigpause did not return -1\n");
result = 1;
}
sem = INMAIN;
return NULL;
}
int sigpause_error(int signum){
pthread_t new_th;
int status;
status = pthread_create(&new_th, NULL, d_thread_func, (void *)&signum);
ERROR_IF(pthread_create, status, != 0);
sleep(1);
status = pthread_kill(new_th, signum);
ERROR_IF(pthread_kill, status, != 0);
sem = INTHREAD;
while (sem == INTHREAD)
sleep(1);
if(result == 2) {
exit(EXIT_FAILURE);
}
if(result == 1) {
exit(EXIT_FAILURE);
}
printf("Test PASSED\n");
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
if (i == SIGKILL || i == SIGSTOP){
continue;
}
sigpause_error(i);
}
return EXIT_SUCCESS;
}
+58
View File
@@ -0,0 +1,58 @@
#define _XOPEN_SOURCE 700
#include "../test_helpers.h"
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
// This program verifies that sigpause() returns -1 and sets errno to EINVAL
// if passed an invalid signal number.
#define INMAIN 0
#define INTHREAD 1
volatile sig_atomic_t handler_called = 0;
int returned = 0;
int return_value = 2;
int result = 2;
int sem = INMAIN;
void handler() {
// printf("signal was called\n");
handler_called = 1;
return;
}
int sigpause_invalid(){
int return_value = 0;
return_value = sigpause(-1);
if (return_value == -1) {
if (errno == EINVAL) {
printf ("Test PASSED: sigpause returned -1 and set errno to EINVAL\n");
return EXIT_SUCCESS;
} else {
printf ("Test FAILED: sigpause did not set errno to EINVAL\n");
exit(EXIT_FAILURE);
}
} else {
printf ("Test FAILED: sigpause did not return -1\n");
if (errno == EINVAL) {
printf ("Test FAILED: sigpause did not set errno to EINVAL\n");
}
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
int main(){
sigpause_invalid();
return EXIT_SUCCESS;
}
+75
View File
@@ -0,0 +1,75 @@
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
// This program verifies that sigpause() removes sig from the signal mask.
int handler_called = 0;
void handler() {
handler_called = 1;
return;
}
void *a_thread_func(void *sig)
{
int status;
int signum = *(int *)sig;
printf("Pausing signal %s\n", signum);
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = handler;
status = sigemptyset(&act.sa_mask);
ERROR_IF(sigemptyset, status, != 0);
status = sigaction(signum, &act, 0);
ERROR_IF(sigaction, status, != 0);
status = sighold(signum);
ERROR_IF(sighold, status, != 0);
status = sigpause(signum);
ERROR_IF(sigpause, status, != 0);
return NULL;
}
int sigpause_basic(int signum)
{
pthread_t new_th;
int status;
status = pthread_create(&new_th, NULL, a_thread_func, (void *)&signum);
ERROR_IF(pthread_create, status, != 0);
sleep(1);
status = pthread_kill(new_th, signum);
ERROR_IF(pthread_kill, status, != 0);
sleep(1);
if (handler_called != 1){
prinft("handler wasn't called\n");
exit(EXIT_FAILURE);
}
handler_called = 0;
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP){
continue;
}
sigpause_basic(sig);
}
return EXIT_SUCCESS;
}
+110
View File
@@ -0,0 +1,110 @@
#define _XOPEN_SOURCE 700
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
// This program verifies that sigpause() restores sig to the signal mask before
// returning.
volatile sig_atomic_t handler_called = false;
void handler() {
handler_called = true;
return;
}
void *c_thread_func(void *sig)
{
int signum = *(int *)sig;
printf("%d !!!\n", signum);
sigset_t pendingset;
puts("before sigpause");
assert(!handler_called);
if ((sigpause(signum) != -1) || (errno != EINTR)) {
puts("Test UNRESOLVED: sigpause didn't return -1 and/or didn't set errno correctly.");
exit(2);
return NULL;
}
assert(handler_called);
handler_called = false;
int status = raise(signum);
ERROR_IF(raise, status, == -1);
assert(!handler_called);
sigpending(&pendingset);
if (sigismember(&pendingset, signum) == 1) {
puts("Test PASSED: signal mask was restored when sigpause returned.");
}
return NULL;
}
int sigpause_revert(int signum) {
pthread_t new_th;
int status;
struct sigaction act;
// Ensure thread inherits mask with signum blocked.
status = sighold(signum);
ERROR_IF(sighold, status, == -1);
act.sa_flags = 0;
act.sa_handler = handler;
status = sigemptyset(&act.sa_mask);
ERROR_IF(sigemptyset, status, == -1);
status = sigaction(signum, &act, NULL);
ERROR_IF(sigaction, status, == -1);
if((status = pthread_create(&new_th, NULL, c_thread_func, (void *)&signum)) != 0)
{
errno = status;
perror("Error creating thread");
exit(EXIT_FAILURE);
}
sleep(1);
if((status = pthread_kill(new_th, signum)) != 0)
{
errno = status;
perror("Test UNRESOLVED: Couldn't send signal to thread");
exit(EXIT_FAILURE);
}
if ((status = pthread_join(new_th, NULL)) != 0) {
errno = status;
perror("failed to join thread");
return EXIT_FAILURE;
}
puts("Test PASSED");
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
if (i == SIGKILL || i == SIGSTOP){
continue;
}
printf("Testing signal %s\n", strsignal(i));
sigpause_revert(i);
}
return EXIT_SUCCESS;
}
+94
View File
@@ -0,0 +1,94 @@
#include <assert.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
// This program verifies that sigpause() suspends the calling process
// until it receives a signal.
#define INMAIN 0
#define INTHREAD 1
volatile sig_atomic_t handler_called = 0;
volatile atomic_bool completed = false;
void handler() {
handler_called = 1;
return;
}
void *b_thread_func(void *code_raw) {
int *code = code_raw;
printf("Pausing signal %s\n", strsignal(*code));
sigpause(*code);
assert(handler_called != 0);
*code = 0;
atomic_store(&completed, true);
return NULL;
}
int sigpause_suspend(int signum)
{
atomic_store(&completed, false);
int status;
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
status = sigaction(signum, &act, 0);
ERROR_IF(sigaction, status, == -1);
pthread_t new_th;
int code = signum;
if ((status = pthread_create(&new_th, NULL, b_thread_func, (void *)&code)) != 0) {
errno = status;
perror("failed to create thread");
return EXIT_FAILURE;
}
sleep(1);
assert(!atomic_load(&completed));
if ((status = pthread_kill(new_th, signum)) != 0) {
errno = status;
perror("failed to kill thread");
return EXIT_FAILURE;
}
if ((status = pthread_join(new_th, NULL)) != 0) {
errno = status;
perror("failed to join thread");
return EXIT_FAILURE;
}
assert(code == 0);
assert(atomic_load(&completed));
return EXIT_SUCCESS;
}
int main(){
// TODO: upper limit for i (gives OOB otherwise)
for (int i=1; i<31; i++){
int sig = signals_list[i].signal;
if (sig == SIGKILL || sig == SIGSTOP){
continue;
}
printf("For signal %s (%d)\n", strsignal(sig), sig);
sigpause_suspend(sig);
}
return EXIT_SUCCESS;
}
+68
View File
@@ -0,0 +1,68 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "../test_helpers.h"
// The thread's signal mask shall not be changed, if sigprocmask( ) fails.
#define NUMSIGNALS 24
int is_changed(sigset_t set) {
int i;
int siglist[] = {SIGALRM, SIGBUS, SIGCHLD,
SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT,
SIGPIPE, SIGQUIT, SIGSEGV,
SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU,
SIGUSR1, SIGUSR2, SIGPROF, SIGSYS,
SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ };
for (i=0; i<NUMSIGNALS; i++) {
if (sigismember(&set, siglist[i]) != 0)
return 1;
}
return 0;
}
int get_rand() {
int r;
r=rand();
while ((r == SIG_BLOCK) || (r == SIG_SETMASK) || (r == SIG_UNBLOCK)) {
r = get_rand();
}
return r;
}
int main() {
int r=get_rand();
sigset_t actl, oactl;
int status;
sigemptyset(&actl);
sigemptyset(&oactl);
status = sigaddset(&actl, SIGABRT);
ERROR_IF(sigaddset, status, != 0);
status = sigprocmask(SIG_SETMASK, &actl, NULL);
ERROR_IF(sigprocmask, status, != 0);
status = sigaddset(&actl, SIGALRM);
ERROR_IF(sigaddset, status, != 0);
status = sigprocmask(r, &actl, NULL);
ERROR_IF(sigprocmask, status, != -1);
status = sigprocmask(SIG_SETMASK, NULL, &oactl);
ERROR_IF(sigprocmask, status, != 0);
status = sigismember(&oactl, SIGABRT);
ERROR_IF(sigismember, status, != 1);
if (is_changed(oactl)) {
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
+22
View File
@@ -0,0 +1,22 @@
#define _XOPEN_SOURCE 600
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include "../test_helpers.h"
// sigprocmask( ) shall return 0, Upon successful completion; otherwise, it shall return -1
// and errno shall be set to indicate the error, and the process' signal mask shall be unchanged.
int main()
{
sigset_t set;
sigaddset (&set, SIGABRT);
int status;
status = sigprocmask(SIG_SETMASK, &set, NULL);
ERROR_IF(sigprocmask, status, != 0);
return EXIT_SUCCESS;
}
+63
View File
@@ -0,0 +1,63 @@
#define _XOPEN_SOURCE 600
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include "../test_helpers.h"
// An errno value of [EINVAL] shall be returned and the sigprocmask() function shall fail, if the value of
// the how argument is not equal to one of the defined values.
int main(int argc, char *argv[])
{
int signo;
(void) signo;
int r=rand();
sigset_t set;
if (argc < 2) {
printf("Usage: %s [1|2|3|4]\n", argv[0]);
exit(EXIT_FAILURE);
}
/*
Various error conditions
*/
switch (argv[1][0]) {
case '1':
signo=-1;
break;
case '2':
signo=-10000;
break;
case '3':
signo=INT32_MIN+1;
break;
case '4':
signo=INT32_MIN;
break;
default:
printf("Usage: %s [1|2|3|4]\n", argv[0]);
exit(EXIT_FAILURE);
}
sigaddset(&set, SIGABRT);
int status;
status = sigprocmask(r, &set, NULL);
ERROR_IF(sigprocmask, status, != -1);
ERROR_IF(sigprocmask, errno, != EINVAL);
// if (sigprocmask(r, &set, NULL) == -1) {
// if (EINVAL == errno) {
// printf ("errno set to EINVAL\n");
// return EXIT_SUCCESS;
// } else {
// printf ("errno not set to EINVAL\n");
// exit(EXIT_FAILURE);
// }
// }
exit(EXIT_FAILURE);
}
+88
View File
@@ -0,0 +1,88 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
// The resulting set shall be the union of the current set and the signal
// set pointed to by set, if the value of the argument how is SIG_BLOCK.
volatile sig_atomic_t handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
handler_called = 1;
}
int sigprocmask_block(int signum)
{
int defaultsig = SIGALRM;
if (signum == SIGALRM) {
defaultsig = SIGHUP;
}
struct sigaction act;
sigset_t set1, set2, pending_set;
sigemptyset(&set1);
sigemptyset(&set2);
sigaddset(&set1, defaultsig);
sigaddset(&set2, signum);
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
int status;
status = sigaction(signum, &act, 0);
ERROR_IF(sigaction, status, == -1);
status = sigaction(defaultsig, &act, 0);
ERROR_IF(sigaction, status, == -1);
status = sigprocmask(SIG_SETMASK, &set1, NULL);
ERROR_IF(sigprocmask, status, == -1);
status = sigprocmask(SIG_UNBLOCK, &set2, NULL);
ERROR_IF(sigprocmask, status, == -1);
printf("Raising %s\n", strsignal(signum));
status = raise(signum);
ERROR_IF(raise, status, == -1);
ERROR_IF(raise, handler_called, != 1);
handler_called = 0;
printf("Raising %s\n", strsignal(defaultsig));
status = raise(defaultsig);
ERROR_IF(raise, defaultsig, == -1);
ERROR_IF(raise, handler_called, == 1);
status = sigpending(&pending_set);
ERROR_IF(sigpending, status, == -1);
status = sigismember(&pending_set, defaultsig);
ERROR_IF(sigismember, status, != 1);
status = sigismember(&pending_set, signum);
ERROR_IF(sigismemeber, status, != 0);
// printf("Test PASSED: signal was added to the process's signal mask\n");
act.sa_handler = SIG_IGN;
sigaction(signum, &act, 0);
sigaction(defaultsig, &act, 0);
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
if (i == SIGKILL || i == SIGSTOP){
continue;
}
printf("Testing signal %s (%d)\n", strsignal(i), i);
sigprocmask_block(i);
}
return 0;
}
+42
View File
@@ -0,0 +1,42 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
// The previous mask shall be stored in the location pointed to by oset, if the argument oset is not a null pointer.
#define NUMSIGNALS 26
int main()
{
sigset_t oactl, tempset;
int i, j, test_failed=0;
int siglist[] = {SIGABRT, SIGALRM, SIGBUS, SIGCHLD,
SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT,
SIGPIPE, SIGQUIT, SIGSEGV,
SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU,
SIGUSR1, SIGUSR2, SIGPROF, SIGSYS,
SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ };
for (i=0; i<NUMSIGNALS; i++) {
sigemptyset(&oactl);
sigemptyset(&tempset);
sigaddset(&tempset, siglist[i]);
sigprocmask(SIG_BLOCK, &tempset, &oactl);
if (i > 0) {
for (j=0; j<i; j++) {
if (sigismember(&oactl, siglist[j]) != 1) {
test_failed = 1;
}
}
}
}
if (test_failed != 0) {
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
+49
View File
@@ -0,0 +1,49 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
// The value of the argument how is not significant and the process's signal mask shall be unchanged, and
// thus the call can be used to enquire about currently blocked signals, if the argument set is a null
// pointer.
#define NUMSIGNALS 25
int is_changed(sigset_t set, int sig) {
int i;
int siglist[] = {SIGABRT, SIGALRM, SIGBUS, SIGCHLD,
SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT,
SIGPIPE, SIGQUIT, SIGSEGV,
SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU,
SIGUSR1, SIGUSR2, SIGPROF, SIGSYS,
SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ };
if (sigismember(&set, sig) != 1) {
return 1;
}
for (i=0; i<NUMSIGNALS; i++) {
if ((siglist[i] != sig)) {
if (sigismember(&set, siglist[i]) != 0) {
return 1;
}
}
}
return 0;
}
int main() {
sigset_t actl, oactl;
sigemptyset(&actl);
sigemptyset(&oactl);
sigaddset(&actl, SIGABRT);
sigprocmask(SIG_SETMASK, &actl, NULL);
sigprocmask(SIG_BLOCK, NULL, &oactl);
if (is_changed(oactl, SIGABRT)) {
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
+46
View File
@@ -0,0 +1,46 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#define NUMSIGNALS 25
int is_changed(sigset_t set, int sig) {
int i;
int siglist[] = {SIGABRT, SIGALRM, SIGBUS, SIGCHLD,
SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT,
SIGPIPE, SIGQUIT, SIGSEGV,
SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU,
SIGUSR1, SIGUSR2, SIGPROF, SIGSYS,
SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ };
if (sigismember(&set, sig) != 1) {
return 1;
}
for (i=0; i<NUMSIGNALS; i++) {
if ((siglist[i] != sig)) {
if (sigismember(&set, siglist[i]) != 0) {
return 1;
}
}
}
return 0;
}
int main() {
sigset_t actl, oactl;
sigemptyset(&actl);
sigemptyset(&oactl);
sigaddset(&actl, SIGABRT);
sigprocmask(SIG_SETMASK, &actl, NULL);
sigprocmask(SIG_SETMASK, NULL, &oactl);
if (is_changed(oactl, SIGABRT)) {
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
+45
View File
@@ -0,0 +1,45 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#define NUMSIGNALS 25
int is_changed(sigset_t set, int sig) {
int i;
int siglist[] = {SIGABRT, SIGALRM, SIGBUS, SIGCHLD,
SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT,
SIGPIPE, SIGQUIT, SIGSEGV,
SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU,
SIGUSR1, SIGUSR2, SIGPROF, SIGSYS,
SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ };
if (sigismember(&set, sig) != 1) {
return 1;
}
for (i=0; i<NUMSIGNALS; i++) {
if ((siglist[i] != sig)) {
if (sigismember(&set, siglist[i]) != 0) {
return 1;
}
}
}
return 0;
}
int main() {
sigset_t actl, oactl;
sigemptyset(&actl);
sigemptyset(&oactl);
sigaddset(&actl, SIGABRT);
sigprocmask(SIG_SETMASK, &actl, NULL);
sigprocmask(SIG_UNBLOCK, NULL, &oactl);
if (is_changed(oactl, SIGABRT)) {
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
+51
View File
@@ -0,0 +1,51 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "../test_helpers.h"
// After the call to sigprocmask(), if there are any pending unblocked signals, at least one of those
// signals shall be delivered before the call to sigprocmask() returns.
int handler_called = 0;
int sigprocmask_return_val = 1; /* some value that's not a 1 or 0 */
void sig_handler(int signo)
{
(void) signo;
handler_called = 1;
if (sigprocmask_return_val != 1) {
printf("FAIL: sigprocmask() returned before signal was delivered.\n");
exit(EXIT_FAILURE);
}
}
int main()
{
struct sigaction act;
sigset_t blocked_set1;
sigemptyset(&blocked_set1);
sigaddset(&blocked_set1, SIGABRT);
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
int status;
status = sigaction(SIGABRT, &act, 0);
ERROR_IF(sigaction, status, == -1);
status = sigprocmask(SIG_SETMASK, &blocked_set1, NULL);
ERROR_IF(sigprocmask, status, == -1);
status = raise(SIGABRT);
ERROR_IF(raise, status, == -1);
sigprocmask_return_val = sigprocmask(SIG_UNBLOCK, &blocked_set1, NULL);
ERROR_IF(sigprocmask, sigprocmask_return_val, != 0);
ERROR_IF(raise, handler_called, != 1);
return EXIT_SUCCESS;
}
+28
View File
@@ -0,0 +1,28 @@
#include "../test_helpers.h"
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
// Attempt to add SIGKILL and SIGSTOP to the process's signal mask and
// verify that:
// - They do not get added.
// - sigprocmask() does not return -1.
int main() {
sigset_t set1, set2;
int ret;
sigemptyset(&set1);
sigemptyset(&set2);
sigaddset(&set1, SIGKILL);
sigaddset(&set1, SIGSTOP);
ret = sigprocmask(SIG_SETMASK, &set1, NULL);
ERROR_IF(sigprocmask, ret, == -1);
ret = sigprocmask(SIG_SETMASK, NULL, &set2);
ERROR_IF(sigprocmask, ret, == -1);
assert(!sigismember(&set2, SIGKILL));
assert(!sigismember(&set2, SIGSTOP));
}
+77
View File
@@ -0,0 +1,77 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
int handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
handler_called = 1;
}
int sigprocmask_block(int signum)
{
int defaultsig = SIGALRM;
if (signum == SIGALRM) {
defaultsig = SIGHUP;
}
struct sigaction act;
sigset_t blocked_set1, blocked_set2, pending_set;
sigemptyset(&blocked_set1);
sigemptyset(&blocked_set2);
sigaddset(&blocked_set1, signum);
sigaddset(&blocked_set2, defaultsig);
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
int status;
status = sigaction(signum, &act, 0);
ERROR_IF(sigaction, status, == -1);
status = sigaction(defaultsig, &act, 0);
ERROR_IF(sigaction, status, == -1);
status = sigprocmask(SIG_SETMASK, &blocked_set1, NULL);
ERROR_IF(sigprocmask, status, == -1);
status = sigprocmask(SIG_BLOCK, &blocked_set2, NULL);
ERROR_IF(sigprocmask, status, == -1);
ERROR_IF(raise, signum, == -1);
ERROR_IF(raise, defaultsig, == -1);
if (handler_called) {
printf("FAIL: Signal was not blocked\n");
exit(EXIT_FAILURE);
}
status = sigpending(&pending_set);
ERROR_IF(sigpending, status, == -1);
status = sigismember(&pending_set, signum);
ERROR_IF(sigismember, status, != 1);
status = sigismember(&pending_set, defaultsig);
ERROR_IF(sigismember, status, != 1);
act.sa_handler = SIG_IGN;
sigaction(signum, &act, 0);
sigaction(defaultsig, &act, 0);
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
if (i == SIGKILL || i == SIGSTOP){
continue;
}
sigprocmask_block(i);
}
return EXIT_SUCCESS;
}
+64
View File
@@ -0,0 +1,64 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
int handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
handler_called = 1;
}
int sigprocmask_block(int signum)
{
struct sigaction act;
sigset_t blocked_set, pending_set;
sigemptyset(&blocked_set);
sigaddset(&blocked_set, signum);
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
int status;
status = sigaction(signum, &act, 0);
ERROR_IF(sigaction, status, == -1);
status = sigprocmask(SIG_SETMASK, &blocked_set, NULL);
ERROR_IF(sigprocmask, status, == -1);
status = raise(signum);
ERROR_IF(raise, status, == -1);
if (handler_called) {
printf("FAIL: Signal was not blocked\n");
exit(EXIT_FAILURE);
}
status = sigpending(&pending_set);
ERROR_IF(sigpending, status, == -1);
status = sigismember(&pending_set, signum);
ERROR_IF(sigismember, status, != 1);
act.sa_handler = SIG_IGN;
sigaction(signum, &act, 0);
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
int sig = signals_list[i-1].signal;
if (sig == SIGKILL || sig == SIGSTOP){
continue;
}
printf("Testing signal %s (%d)\n", strsignal(i), i);
sigprocmask_block(sig);
}
return EXIT_SUCCESS;
}
+71
View File
@@ -0,0 +1,71 @@
// The sigrelse() function shall remove sig from the signal mask of the calling process.
#include <assert.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
#define _XOPEN_SOURCE 700
volatile sig_atomic_t handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
handler_called = 1;
}
int sigrelse_test(int signum)
{
// needs to be reset
handler_called = 0;
struct sigaction act;
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
int status;
status = sigaction(signum, &act, NULL);
ERROR_IF(sigaction, status, == -1);
status = sighold(signum);
ERROR_IF(sighold, status, == -1);
assert(handler_called == 0);
status = raise(signum);
ERROR_IF(raise, status, == -1);
assert(handler_called == 0);
status = sigrelse(signum);
ERROR_IF(sigrelse, status, == -1);
assert(handler_called == 1);
// if (handler_called) {
// printf("PASS: %d successfully removed from signal mask\n", signum);
// handler_called = 0;
// return EXIT_SUCCESS;
// }
// printf("FAIL\n");
// exit(EXIT_FAILURE);
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
if (i == SIGKILL || i == SIGSTOP){
continue;
}
printf("For signal %s\n", strsignal(i));
sigrelse_test(i);
}
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include "../test_helpers.h"
int main()
{
int status;
status = (int)sigrelse(SIGABRT);
ERROR_IF(sigrelse, status, != 0);
return EXIT_SUCCESS;
}
+14
View File
@@ -0,0 +1,14 @@
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include "../test_helpers.h"
int main()
{
int status;
status = (int)sigrelse(100000);
ERROR_IF(sigrelse, status, != -1);
ERROR_IF(sigrelse, errno, != EINVAL);
return EXIT_SUCCESS;
}
+48
View File
@@ -0,0 +1,48 @@
#define _XOPEN_SOURCE 600
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
int handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
printf("SIGURG called. Inside handler\n");
handler_called = 1;
}
int sigset_test(int signum)
{
struct sigaction act;
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
if (sigaction(signum, &act, 0) != 0) {
perror("Unexpected error while using sigaction()");
exit(EXIT_FAILURE);
}
if (sigset(signum,SIG_DFL) != sig_handler) {
perror("Unexpected error while using signal()");
exit(EXIT_FAILURE);
}
raise(signum);
if (handler_called == 1) {
printf("Test FAILED: handler was called even though default was expected\n");
exit(EXIT_FAILURE);
}
printf("test passed, the signal was ignored\n");
return EXIT_SUCCESS;
}
int main(){
sigset_test(SIGURG);
return EXIT_SUCCESS;
}
+27
View File
@@ -0,0 +1,27 @@
#define _XOPEN_SOURCE 600
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "../test_helpers.h"
int main()
{
void (*status) (int);
status = sigset(SIGKILL,SIG_IGN);
assert(status == SIG_ERR);
assert(errno == EINVAL);
// if (sigset(SIGKILL,SIG_IGN) == SIG_ERR) {
// if (errno != EINVAL) {
// printf("Test FAILED: sigset() returned SIG_ERR but didn't set errno to EINVAL\n");
// exit(EXIT_FAILURE);
// }
// } else {
// printf("Test FAILED: sigset() didn't return SIG_ERROR even though SIGKILL was passed to it\n");
// exit(EXIT_FAILURE);
// }
// printf("test passed: error was set successfully\n");
return EXIT_SUCCESS;
}
+54
View File
@@ -0,0 +1,54 @@
#define _XOPEN_SOURCE 600
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
int handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
printf("SIGUSR1 called. Inside handler\n");
handler_called = 1;
}
int sigset_test2(int signum)
{
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = sig_handler;
sigemptyset(&act.sa_mask);
if (sigaction(signum, &act, 0) != 0) {
perror("Unexpected error while using sigaction()");
exit(EXIT_FAILURE);
}
if (sigset(signum,SIG_IGN) != sig_handler) {
perror("Unexpected error while using signal()");
exit(EXIT_FAILURE);
}
raise(signum);
if (handler_called == 1) {
printf("Test FAILED: handler was called even though ignore was expected\n");
exit(EXIT_FAILURE);
}
printf("test %d passed, the signal was ignored\n", signum);
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
if (i == SIGKILL || i == SIGSTOP){
continue;
}
sigset_test2(i);
}
return EXIT_SUCCESS;
}
+45
View File
@@ -0,0 +1,45 @@
#define _XOPEN_SOURCE 600
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
int handler_called = 0;
void sig_handler(int signo)
{
(void) signo;
// printf("SIGCHLD called. Inside handler\n");
handler_called = 1;
}
int sigset_test3(int signum)
{
if (sigset(signum, sig_handler) == SIG_ERR) {
perror("Unexpected error while using sigset()");
exit(EXIT_FAILURE);
}
raise(signum);
if (handler_called != 1) {
printf("Test FAILED: handler wasn't called even though it was expected\n");
exit(EXIT_FAILURE);
}
printf("test %d passed, handler was called\n", signum);
handler_called = 0;
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
if (i == SIGKILL || i == SIGSTOP){
continue;
}
sigset_test3(i);
}
return EXIT_SUCCESS;
}
+56
View File
@@ -0,0 +1,56 @@
#define _XOPEN_SOURCE 600
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
int signal_blocked = 0;
int count = 1;
void sig_handler(int signo)
{
(void) signo;
// printf("SIGCHLD called. Inside handler\n");
sigset_t mask;
sigprocmask(SIG_SETMASK, NULL, &mask);
if (count == SIGKILL || count == SIGSTOP){
count++;
}
if(sigismember(&mask, count)) {
signal_blocked = 1;
}
count++;
}
int sigset_test4(int signum)
{
if (sigset(signum, sig_handler) == SIG_ERR) {
perror("Unexpected error while using sigset()");
exit(EXIT_FAILURE);
}
raise(signum);
if (signal_blocked != 1) {
printf("Test FAILED: signal was not added to the mask before the handler was executed\n");
exit(EXIT_FAILURE);
}
signal_blocked = 0;
printf("test %d passed: the singal was added to the mask before the handler was executed\n", signum);
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
if (i == SIGKILL || i == SIGSTOP){
continue;
}
sigset_test4(i);
}
return EXIT_SUCCESS;
}
+72
View File
@@ -0,0 +1,72 @@
#define _XOPEN_SOURCE 600
#include <assert.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
#define NUMSIGNALS 26
bool is_empty(sigset_t *set) {
int i;
int siglist[25] = {SIGABRT, SIGALRM, SIGBUS, SIGCHLD,
SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT,
SIGPIPE, SIGQUIT, SIGSEGV,
SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU,
SIGUSR1, SIGUSR2, SIGPROF, SIGSYS,
SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ };
for (i=0; i<25; i++) {
if (sigismember(set, siglist[i]) != 0)
return false;
}
return true;
}
void sig_handler(int signo)
{
printf("%d called. Inside handler\n", signo);
}
int sigset_test5(int signum)
{
sigset_t mask;
sigemptyset(&mask);
sigprocmask(SIG_SETMASK, &mask, NULL);
void (*status) (int);
status = sigset(signum, sig_handler);
ERROR_IF(sigset, status, == SIG_ERR);
// if (sigset(signum, sig_handler) == SIG_ERR) {
// perror("Unexpected error while using sigset()");
// exit(EXIT_FAILURE);
// }
raise(signum);
sigprocmask(SIG_SETMASK, NULL, &mask);
bool status1 = is_empty(&mask);
assert(status1);
// if (is_empty(&mask) != 1) {
// printf("Test FAILED: signal mask should be empty\n");
// exit(EXIT_FAILURE);
// }
// printf("sig %d was successfully removed from the mask when handler returned\n", signum);
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
printf("Testing for sig %s (%d)\n", strsignal(i), i);
if (i == SIGKILL || i == SIGSTOP){
continue;
}
sigset_test5(i);
}
return 0;
}
+45
View File
@@ -0,0 +1,45 @@
#define _XOPEN_SOURCE 600
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals_list.h"
#include "../test_helpers.h"
void sig_handler(int signo)
{
(void) signo;
printf("SIGUSR1 called. Inside handler\n");
}
int sigset_test9(int signum)
{
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = sig_handler;
sigemptyset(&act.sa_mask);
if (sigaction(signum, &act, 0) != 0) {
perror("Unexpected error while using sigaction()");
exit(EXIT_FAILURE);
}
if (sigset(signum,SIG_DFL) != sig_handler) {
printf("Test FAILED: sigset didn't return myhandler even though it was SIGUSR1's original disposition\n");
exit(EXIT_FAILURE);
}
printf("test %d passed \n", signum);
return EXIT_SUCCESS;
}
int main(){
for (int i=1; i<N_SIGNALS; i++){
if (i == SIGKILL || i == SIGSTOP){
continue;
}
sigset_test9(i);
}
return EXIT_SUCCESS;
}