1 /******************************************************************************/
2 /* Copyright (c) Crackerjack Project., 2007 */
3 /* */
4 /* This program is free software; you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation; either version 2 of the License, or */
7 /* (at your option) any later version. */
8 /* */
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
12 /* the GNU General Public License for more details. */
13 /* */
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program; if not, write to the Free Software Foundation, */
16 /* Inc., 59 Temple Place, Suite TEST_SIG0, Boston, MA 02111-1307 USA */
17 /* */
18 /* History: Porting from Crackerjack to LTP is done by */
19 /* Manas Kumar Nayak <maknayak@in.ibm.com> */
20 /******************************************************************************/
21
22 /******************************************************************************/
23 /* Description: This tests the rt_sigprocmask() syscall */
24 /* rt_sigprocmask changes the list of currently blocked signals. */
25 /* The set value stores the signal mask of the pending signals. */
26 /* The previous action on the signal is saved in oact. The value */
27 /* of how indicates how the call should behave; its values are */
28 /* as follows: */
29 /* */
30 /* SIG_BLOCK */
31 /* The set of blocked signals is the union of the current set*/
32 /* and the set argument. */
33 /* SIG_UNBLOCK */
34 /* The signals in set are removed from the current set of */
35 /* blocked signals. It is okay to unblock a signal that is */
36 /* not blocked. */
37 /* SIG_SETMASK */
38 /* The set of blocked signals is set to the set argument. */
39 /* sigsetsize should indicate the size of a sigset_t type. */
40 /******************************************************************************/
41
42 #include <stdio.h>
43 #include <signal.h>
44 #include <errno.h>
45
46 #include "test.h"
47 #include "lapi/syscalls.h"
48 #include "lapi/rt_sigaction.h"
49
50 char *TCID = "rt_sigprocmask01";
51 static int testno;
52 int TST_TOTAL = 8;
53
54 static volatile sig_atomic_t sig_count;
55
56 #define TEST_SIG SIGRTMIN+1
57
cleanup(void)58 static void cleanup(void)
59 {
60 tst_rmdir();
61 }
62
setup(void)63 static void setup(void)
64 {
65 TEST_PAUSE;
66 tst_tmpdir();
67 }
68
sig_handler(int sig)69 void sig_handler(int sig)
70 {
71 sig_count++;
72 }
73
main(int ac,char ** av)74 int main(int ac, char **av)
75 {
76 struct sigaction act, oact;
77 memset(&act, 0, sizeof(act));
78 memset(&oact, 0, sizeof(oact));
79 act.sa_handler = sig_handler;
80
81 sigset_t set, oset;
82 int lc;
83
84 tst_parse_opts(ac, av, NULL, NULL);
85
86 setup();
87
88 for (lc = 0; TEST_LOOPING(lc); ++lc) {
89 tst_count = 0;
90 for (testno = 0; testno < TST_TOTAL; ++testno) {
91
92 if (sigemptyset(&set) < 0)
93 tst_brkm(TFAIL | TERRNO, cleanup,
94 "sigemptyset call failed");
95
96 if (sigaddset(&set, TEST_SIG) < 0)
97 tst_brkm(TFAIL | TERRNO, cleanup,
98 "sigaddset call failed");
99
100 /* call rt_sigaction() */
101 TEST(ltp_rt_sigaction(TEST_SIG, &act, &oact,
102 SIGSETSIZE));
103 if (TEST_RETURN < 0)
104 tst_brkm(TFAIL | TTERRNO, cleanup,
105 "rt_sigaction call failed");
106
107 /* call rt_sigprocmask() to block signal#TEST_SIG */
108 TEST(ltp_syscall(__NR_rt_sigprocmask, SIG_BLOCK, &set,
109 &oset, SIGSETSIZE));
110 if (TEST_RETURN == -1)
111 tst_brkm(TFAIL | TTERRNO, cleanup,
112 "rt_sigprocmask call failed");
113
114 /* Make sure that the masked process is indeed
115 * masked. */
116 if (kill(getpid(), TEST_SIG) < 0)
117 tst_brkm(TFAIL | TERRNO, cleanup,
118 "call to kill() failed");
119
120 if (sig_count) {
121 tst_brkm(TFAIL | TERRNO, cleanup,
122 "rt_sigprocmask() failed to change "
123 "the process's signal mask");
124 } else {
125 /* call rt_sigpending() */
126 TEST(ltp_syscall(__NR_rt_sigpending, &oset,
127 SIGSETSIZE));
128 if (TEST_RETURN == -1)
129 tst_brkm(TFAIL | TTERRNO, cleanup,
130 "rt_sigpending call failed");
131
132 TEST(sigismember(&oset, TEST_SIG));
133 if (TEST_RETURN == 0)
134 tst_brkm(TFAIL | TTERRNO,
135 cleanup,
136 "sigismember call failed");
137
138 /* call rt_sigprocmask() to unblock
139 * signal#TEST_SIG */
140 TEST(ltp_syscall(__NR_rt_sigprocmask,
141 SIG_UNBLOCK, &set, &oset,
142 SIGSETSIZE));
143 if (TEST_RETURN == -1)
144 tst_brkm(TFAIL | TTERRNO,
145 cleanup,
146 "rt_sigprocmask call failed");
147
148 if (sig_count) {
149 tst_resm(TPASS,
150 "rt_sigprocmask "
151 "functionality passed");
152 break;
153 } else {
154 tst_brkm(TFAIL | TERRNO,
155 cleanup,
156 "rt_sigprocmask "
157 "functionality failed");
158 }
159 }
160
161 }
162
163 tst_count++;
164
165 }
166
167 cleanup();
168 tst_exit();
169 }
170