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:
+54
-3
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user