blob: a65e5fff3636f5d5b98e36d6ff2626ae6edd51f3 [file] [log] [blame]
robbiew0dc07652005-06-03 16:29:48 +00001/*
2 * Copyright (c) 2003, Intel Corporation. All rights reserved.
3 * Created by: salwan.searty REMOVE-THIS AT intel DOT com
4 * This file is licensed under the GPL license. For the full content
Garrett Cooper2c282152010-12-16 00:55:50 -08005 * of this license, see the COPYING file at the top level of this
robbiew0dc07652005-06-03 16:29:48 +00006 * source tree.
7
8 Assumption: The test assumes that this program is run under normal conditions,
9 and not when the processor and other resources are too stressed.
10
11 Steps:
12 1. Fork() a child process. In the child, add SIGUSR1 to the process's signal mask.
13 This is its original signal mask. Now suspend the child, passing sigsuspend another
14 signal mask. One that doesn't contain SIGUSR1, but contains SIGUSR2.
Garrett Cooper2c282152010-12-16 00:55:50 -080015 2. From the parent, send the child a SIGUSR1 signal so that the child returns from
robbiew0dc07652005-06-03 16:29:48 +000016 suspension.
17 3. Once the sigsuspend returns, have the child probe the signal mask using the is_changed()
18 function which basically verifies that the signal mask is restored to what it was originally
19 before the call to sigsuspend. I.e. SIGUSR1 in the mask and SIGUSR2 not in the mask. Have
20 the child return to the parent process with:
21 - a return value of 1 if the original signal mask was not restored, or
22 - a return value of 0 if the original signal mask was successfully restored.
23 4. Finally from the parent, return a PTS_PASS if recieved the return value of the child was not
24 a 1.
25
26*/
27
28#include <signal.h>
29#include <sys/types.h>
30#include <sys/wait.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <unistd.h>
34#include "posixtest.h"
35
Garrett Coopera1a92072011-01-16 18:07:18 -080036#define NUMSIGNALS (sizeof(siglist) / sizeof(siglist[0]))
robbiew0dc07652005-06-03 16:29:48 +000037
38void handler(int signo)
39{
robbiew0dc07652005-06-03 16:29:48 +000040}
41
42int is_changed(sigset_t set, int sig) {
Garrett Cooper2c282152010-12-16 00:55:50 -080043
robbiew0dc07652005-06-03 16:29:48 +000044 int i;
Garrett Cooper2c282152010-12-16 00:55:50 -080045 int siglist[] = {SIGABRT, SIGALRM, SIGBUS, SIGCHLD,
46 SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT,
47 SIGPIPE, SIGQUIT, SIGSEGV,
48 SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU,
Garrett Cooperd3df7e02011-01-16 17:55:25 -080049 SIGUSR1, SIGUSR2,
50#ifdef SIGPOLL
51 SIGPOLL,
52#endif
53#ifdef SIGPROF
54 SIGPROF,
55#endif
56 SIGSYS,
robbiew0dc07652005-06-03 16:29:48 +000057 SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ };
58
59 if (sigismember(&set, sig) != 1) {
60 return 1;
61 }
62 for (i=0; i<NUMSIGNALS; i++) {
63 if ((siglist[i] != sig)) {
64 if (sigismember(&set, siglist[i]) != 0) {
65 return 1;
66 }
67 }
68 }
69 return 0;
70}
71
72int main()
73{
74 pid_t pid;
75 pid = fork();
76
77 if (pid == 0) {
78 /* child */
79
80 sigset_t tempmask, originalmask, currentmask;
81
82 struct sigaction act;
83
84 act.sa_handler = handler;
85 act.sa_flags=0;
86 sigemptyset(&act.sa_mask);
87
88 sigemptyset(&tempmask);
89 sigaddset(&tempmask, SIGUSR2);
90
Garrett Coopera1a92072011-01-16 18:07:18 -080091 if (sigaction(SIGUSR1, &act, 0) == -1) {
robbiew0dc07652005-06-03 16:29:48 +000092 perror("Unexpected error while attempting to pre-conditions");
93 return PTS_UNRESOLVED;
94 }
95
96 sigemptyset(&originalmask);
97 sigaddset(&originalmask, SIGUSR1);
98 sigprocmask(SIG_SETMASK, &originalmask, NULL);
99
100 printf("suspending child\n");
101 if (sigsuspend(&tempmask) != -1)
102 perror("sigsuspend error");
103
104 printf("returned from suspend\n");
105
106 sigprocmask(SIG_SETMASK, NULL, &currentmask);
107
108 if (is_changed(currentmask, SIGUSR1) != 0) {
109 printf("signal mask was not restored properly after sigsuspend returned\n");
110 return 1;
111 }
Garrett Cooper58c769b2010-12-19 17:40:59 -0800112 return 0;
robbiew0dc07652005-06-03 16:29:48 +0000113
114 } else {
Garrett Cooper2c282152010-12-16 00:55:50 -0800115 int s;
robbiew0dc07652005-06-03 16:29:48 +0000116 int exit_status;
117
118 /* parent */
119 sleep(1);
120
121 printf("parent sending child a SIGUSR1 signal\n");
122 kill (pid, SIGUSR1);
123
124 if (wait(&s) == -1) {
125 perror("Unexpected error while setting up test "
126 "pre-conditions");
127 return PTS_UNRESOLVED;
128 }
129
130 if (!WIFEXITED(s)) {
131 printf("Test FAILED: Did not exit normally\n");
Garrett Cooper2c282152010-12-16 00:55:50 -0800132 return PTS_FAIL;
robbiew0dc07652005-06-03 16:29:48 +0000133 }
134
135 exit_status = WEXITSTATUS(s);
136
137 printf("Exit status from child is %d\n", exit_status);
138
139 if (exit_status == 1) {
140 return PTS_FAIL;
141 }
142
143 printf("Test PASSED\n");
144 return PTS_PASS;
145 }
Garrett Cooperd3df7e02011-01-16 17:55:25 -0800146}