blob: 8f525bb245c82f866c3c0e5749606cce71661a8f [file] [log] [blame]
subrata_modak89d3b4a2008-09-11 11:50:23 +00001/*
2 *
3 * Copyright (c) Red Hat Inc., 2008
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
subrata_modak89d3b4a2008-09-11 11:50:23 +000018 */
19
20/*
21 * NAME
22 * signalfd01.c
23 *
24 * DESCRIPTION
25 * Check signalfd can receive signals
26 *
27 * USAGE
28 * signalfd01
29 *
30 * HISTORY
31 * 9/2008 Initial version by Masatake YAMATO <yamato@redhat.com>
32 *
33 * RESTRICTIONS
34 * None
35 */
Wanlong Gao354ebb42012-12-07 10:10:04 +080036#define _GNU_SOURCE
subrata_modak89d3b4a2008-09-11 11:50:23 +000037
subrata_modak3d8666c2008-11-11 08:31:27 +000038#include "config.h"
39
subrata_modak89d3b4a2008-09-11 11:50:23 +000040#include "test.h"
subrata_modak89d3b4a2008-09-11 11:50:23 +000041
42#include <errno.h>
43#include <signal.h>
subrata_modak89d3b4a2008-09-11 11:50:23 +000044#include <unistd.h>
45#include <fcntl.h>
yaberauneya6b83f262009-11-26 12:43:45 +000046#include <inttypes.h>
47#include "ltp_signal.h"
subrata_modak89d3b4a2008-09-11 11:50:23 +000048
subrata_modak89d3b4a2008-09-11 11:50:23 +000049TCID_DEFINE(signalfd01);
50int TST_TOTAL = 1;
subrata_modak89d3b4a2008-09-11 11:50:23 +000051
subrata_modake94ba552008-11-20 09:35:07 +000052#ifndef HAVE_SIGNALFD
53#define USE_STUB
subrata_modak4bb656a2009-02-26 12:02:09 +000054#endif
subrata_modakec61b342008-10-23 06:54:59 +000055
subrata_modak3d8666c2008-11-11 08:31:27 +000056#if defined HAVE_SYS_SIGNALFD_H
subrata_modak89d3b4a2008-09-11 11:50:23 +000057#include <sys/signalfd.h>
subrata_modak3d8666c2008-11-11 08:31:27 +000058#elif defined HAVE_LINUX_SIGNALFD_H
Wanlong Gao354ebb42012-12-07 10:10:04 +080059#if defined HAVE_LINUX_TYPES_H
60#include <linux/types.h>
61#endif
subrata_modak45d47502008-09-18 11:30:37 +000062#include <linux/signalfd.h>
subrata_modake94ba552008-11-20 09:35:07 +000063#define USE_OWNIMPL
subrata_modak3d8666c2008-11-11 08:31:27 +000064#elif defined HAVE_SIGNALFD_H
subrata_modak45d47502008-09-18 11:30:37 +000065#include <signalfd.h>
subrata_modak3d8666c2008-11-11 08:31:27 +000066#else
67#define USE_STUB
68#endif
subrata_modak45d47502008-09-18 11:30:37 +000069
subrata_modake94ba552008-11-20 09:35:07 +000070#if defined HAVE_STRUCT_SIGNALFD_SIGINFO_SSI_SIGNO
Wanlong Gao354ebb42012-12-07 10:10:04 +080071#define SIGNALFD_PREFIX(FIELD) ssi_##FIELD
subrata_modake94ba552008-11-20 09:35:07 +000072#elif defined HAVE_STRUCT_SIGNALFD_SIGINFO_SIGNO
Wanlong Gao354ebb42012-12-07 10:10:04 +080073#define SIGNALFD_PREFIX(FIELD) FIELD
subrata_modak3d8666c2008-11-11 08:31:27 +000074#else
Wanlong Gao354ebb42012-12-07 10:10:04 +080075#define USE_STUB
subrata_modak3d8666c2008-11-11 08:31:27 +000076#endif
77
78#ifdef USE_STUB
vapier0dca7e52008-11-12 19:25:18 +000079int main(int argc, char **argv)
subrata_modak3d8666c2008-11-11 08:31:27 +000080{
Cyril Hrubis526fdf82014-12-04 14:35:01 +010081 tst_brkm(TCONF, NULL, "System doesn't support execution of the test");
subrata_modak3d8666c2008-11-11 08:31:27 +000082}
subrata_modak3d8666c2008-11-11 08:31:27 +000083
subrata_modakc28532e2008-12-30 14:38:12 +000084#else
85#if defined USE_OWNIMPL
vapier2ba926e2008-11-14 07:39:21 +000086#include "linux_syscall_numbers.h"
87int signalfd(int fd, const sigset_t * mask, int flags)
88{
89 /* Taken from GLIBC. */
Jan Stancek359980f2013-02-15 10:16:05 +010090 return ltp_syscall(__NR_signalfd, fd, mask, SIGSETSIZE);
vapier2ba926e2008-11-14 07:39:21 +000091}
subrata_modakc28532e2008-12-30 14:38:12 +000092#endif
vapier2ba926e2008-11-14 07:39:21 +000093
subrata_modak89d3b4a2008-09-11 11:50:23 +000094void cleanup(void);
95void setup(void);
96
vapier0dca7e52008-11-12 19:25:18 +000097int do_test1(int ntst, int sig)
subrata_modak89d3b4a2008-09-11 11:50:23 +000098{
99 int sfd_for_next;
100 int sfd;
101 sigset_t mask;
102 pid_t pid;
103 struct signalfd_siginfo fdsi;
vapier0dca7e52008-11-12 19:25:18 +0000104 ssize_t s;
105
subrata_modak89d3b4a2008-09-11 11:50:23 +0000106 sigemptyset(&mask);
107 sigaddset(&mask, sig);
108 if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
109 tst_brkm(TBROK, cleanup,
110 "sigprocmask() Failed: errno=%d : %s",
vapier0dca7e52008-11-12 19:25:18 +0000111 errno, strerror(errno));
subrata_modak89d3b4a2008-09-11 11:50:23 +0000112 }
vapier0dca7e52008-11-12 19:25:18 +0000113
subrata_modak89d3b4a2008-09-11 11:50:23 +0000114 TEST(signalfd(-1, &mask, 0));
vapier0dca7e52008-11-12 19:25:18 +0000115
subrata_modak89d3b4a2008-09-11 11:50:23 +0000116 if ((sfd = TEST_RETURN) == -1) {
117 tst_resm(TFAIL,
118 "signalfd() Failed, errno=%d : %s",
119 TEST_ERRNO, strerror(TEST_ERRNO));
120 sfd_for_next = -1;
121 return sfd_for_next;
vapier0dca7e52008-11-12 19:25:18 +0000122
Cyril Hrubise38b9612014-06-02 17:20:57 +0200123 } else {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000124 tst_resm(TPASS, "signalfd is created successfully");
125 sfd_for_next = sfd;
126 goto out;
127 }
subrata_modak89d3b4a2008-09-11 11:50:23 +0000128
129 if (fcntl(sfd, F_SETFL, O_NONBLOCK) == -1) {
130 close(sfd);
131 tst_brkm(TBROK, cleanup,
132 "setting signalfd nonblocking mode failed: errno=%d : %s",
vapier0dca7e52008-11-12 19:25:18 +0000133 errno, strerror(errno));
subrata_modak89d3b4a2008-09-11 11:50:23 +0000134 }
135
subrata_modak89d3b4a2008-09-11 11:50:23 +0000136 pid = getpid();
137 if (kill(pid, sig) == -1) {
138 close(sfd);
139 tst_brkm(TBROK, cleanup,
140 "kill(self, %s) failed: errno=%d : %s",
vapier0dca7e52008-11-12 19:25:18 +0000141 strsignal(sig), errno, strerror(errno));
subrata_modak89d3b4a2008-09-11 11:50:23 +0000142 }
143
144 s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
145 if ((s > 0) && (s != sizeof(struct signalfd_siginfo))) {
146 tst_resm(TFAIL,
147 "getting incomplete signalfd_siginfo data: "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800148 "actual-size=%" PRId32 ", expected-size=%" PRId32,
subrata_modak89d3b4a2008-09-11 11:50:23 +0000149 s, sizeof(struct signalfd_siginfo));
150 sfd_for_next = -1;
151 close(sfd);
152 goto out;
vapier0dca7e52008-11-12 19:25:18 +0000153 } else if (s < 0) {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000154 if (errno == EAGAIN) {
155 tst_resm(TFAIL,
156 "signalfd_siginfo data is not delivered yet");
157 sfd_for_next = -1;
158 close(sfd);
159 goto out;
160 } else {
161 close(sfd);
162 tst_brkm(TBROK, cleanup,
163 "read signalfd_siginfo data failed: errno=%d : %s",
vapier0dca7e52008-11-12 19:25:18 +0000164 errno, strerror(errno));
subrata_modak89d3b4a2008-09-11 11:50:23 +0000165 }
vapier0dca7e52008-11-12 19:25:18 +0000166 } else if (s == 0) {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000167 tst_resm(TFAIL, "got EOF unexpectedly");
168 sfd_for_next = -1;
169 close(sfd);
170 goto out;
171 }
vapier0dca7e52008-11-12 19:25:18 +0000172
vapier48c51ee2008-11-12 19:27:33 +0000173 if (fdsi.SIGNALFD_PREFIX(signo) == sig) {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000174 tst_resm(TPASS, "got expected signal");
175 sfd_for_next = sfd;
176 goto out;
vapier0dca7e52008-11-12 19:25:18 +0000177 } else {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000178 tst_resm(TFAIL, "got unexpected signal: signal=%d : %s",
subrata_modake94ba552008-11-20 09:35:07 +0000179 fdsi.SIGNALFD_PREFIX(signo),
vapier48c51ee2008-11-12 19:27:33 +0000180 strsignal(fdsi.SIGNALFD_PREFIX(signo)));
subrata_modak89d3b4a2008-09-11 11:50:23 +0000181 sfd_for_next = -1;
182 close(sfd);
183 goto out;
184 }
185
Wanlong Gao354ebb42012-12-07 10:10:04 +0800186out:
subrata_modak89d3b4a2008-09-11 11:50:23 +0000187 return sfd_for_next;
188}
189
vapier0dca7e52008-11-12 19:25:18 +0000190void do_test2(int ntst, int fd, int sig)
subrata_modak89d3b4a2008-09-11 11:50:23 +0000191{
192 int sfd;
193 sigset_t mask;
194 pid_t pid;
195 struct signalfd_siginfo fdsi;
vapier0dca7e52008-11-12 19:25:18 +0000196 ssize_t s;
subrata_modak89d3b4a2008-09-11 11:50:23 +0000197
198 sigemptyset(&mask);
199 sigaddset(&mask, sig);
200 if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
201 close(fd);
202 tst_brkm(TBROK, cleanup,
203 "sigprocmask() Failed: errno=%d : %s",
vapier0dca7e52008-11-12 19:25:18 +0000204 errno, strerror(errno));
subrata_modak89d3b4a2008-09-11 11:50:23 +0000205 }
vapier0dca7e52008-11-12 19:25:18 +0000206
subrata_modak89d3b4a2008-09-11 11:50:23 +0000207 TEST(signalfd(fd, &mask, 0));
vapier0dca7e52008-11-12 19:25:18 +0000208
subrata_modak89d3b4a2008-09-11 11:50:23 +0000209 if ((sfd = TEST_RETURN) == -1) {
210 tst_resm(TFAIL,
211 "reassignment the file descriptor by signalfd() failed, errno=%d : %s",
212 TEST_ERRNO, strerror(TEST_ERRNO));
213 return;
214 } else if (sfd != fd) {
215 tst_resm(TFAIL,
216 "different fd is returned in reassignment: expected-fd=%d, actual-fd=%d",
217 fd, sfd);
218 close(sfd);
219 return;
vapier0dca7e52008-11-12 19:25:18 +0000220
Cyril Hrubise38b9612014-06-02 17:20:57 +0200221 } else {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000222 tst_resm(TPASS, "signalfd is successfully reassigned");
223 goto out;
224 }
vapier0dca7e52008-11-12 19:25:18 +0000225
subrata_modak89d3b4a2008-09-11 11:50:23 +0000226 pid = getpid();
227 if (kill(pid, sig) == -1) {
228 close(sfd);
229 tst_brkm(TBROK, cleanup,
230 "kill(self, %s) failed: errno=%d : %s",
vapier0dca7e52008-11-12 19:25:18 +0000231 strsignal(sig), errno, strerror(errno));
subrata_modak89d3b4a2008-09-11 11:50:23 +0000232 }
233
234 s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
235 if ((s > 0) && (s != sizeof(struct signalfd_siginfo))) {
236 tst_resm(TFAIL,
237 "getting incomplete signalfd_siginfo data: "
Wanlong Gao354ebb42012-12-07 10:10:04 +0800238 "actual-size=%" PRId32 ", expected-size= %" PRId32,
subrata_modak89d3b4a2008-09-11 11:50:23 +0000239 s, sizeof(struct signalfd_siginfo));
240 goto out;
vapier0dca7e52008-11-12 19:25:18 +0000241 } else if (s < 0) {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000242 if (errno == EAGAIN) {
243 tst_resm(TFAIL,
244 "signalfd_siginfo data is not delivered yet");
245 goto out;
246 } else {
247 close(sfd);
248 tst_brkm(TBROK, cleanup,
249 "read signalfd_siginfo data failed: errno=%d : %s",
vapier0dca7e52008-11-12 19:25:18 +0000250 errno, strerror(errno));
subrata_modak89d3b4a2008-09-11 11:50:23 +0000251 }
vapier0dca7e52008-11-12 19:25:18 +0000252 } else if (s == 0) {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000253 tst_resm(TFAIL, "got EOF unexpectedly");
254 goto out;
255 }
vapier0dca7e52008-11-12 19:25:18 +0000256
vapier48c51ee2008-11-12 19:27:33 +0000257 if (fdsi.SIGNALFD_PREFIX(signo) == sig) {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000258 tst_resm(TPASS, "got expected signal");
259 goto out;
vapier0dca7e52008-11-12 19:25:18 +0000260 } else {
subrata_modak89d3b4a2008-09-11 11:50:23 +0000261 tst_resm(TFAIL, "got unexpected signal: signal=%d : %s",
vapier48c51ee2008-11-12 19:27:33 +0000262 fdsi.SIGNALFD_PREFIX(signo),
263 strsignal(fdsi.SIGNALFD_PREFIX(signo)));
subrata_modak89d3b4a2008-09-11 11:50:23 +0000264 goto out;
265 }
vapier0dca7e52008-11-12 19:25:18 +0000266
Wanlong Gao354ebb42012-12-07 10:10:04 +0800267out:
subrata_modak89d3b4a2008-09-11 11:50:23 +0000268 return;
269}
270
vapier0dca7e52008-11-12 19:25:18 +0000271int main(int argc, char **argv)
subrata_modak89d3b4a2008-09-11 11:50:23 +0000272{
273 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200274 const char *msg;
subrata_modak89d3b4a2008-09-11 11:50:23 +0000275 int sfd;
276
vapier0dca7e52008-11-12 19:25:18 +0000277 if ((tst_kvercmp(2, 6, 22)) < 0) {
278 tst_resm(TWARN,
279 "This test can only run on kernels that are 2.6.22 and higher");
subrata_modak89d3b4a2008-09-11 11:50:23 +0000280 exit(0);
281 }
subrata_modak89d3b4a2008-09-11 11:50:23 +0000282
283 if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -0800284 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modak89d3b4a2008-09-11 11:50:23 +0000285 }
286
vapier0dca7e52008-11-12 19:25:18 +0000287 setup();
subrata_modak89d3b4a2008-09-11 11:50:23 +0000288 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800289 tst_count = 0;
subrata_modak89d3b4a2008-09-11 11:50:23 +0000290
291 sfd = do_test1(lc, SIGUSR1);
292 if (sfd < 0)
293 continue;
vapier0dca7e52008-11-12 19:25:18 +0000294
subrata_modak89d3b4a2008-09-11 11:50:23 +0000295 do_test2(lc, sfd, SIGUSR2);
296 close(sfd);
297 }
vapier0dca7e52008-11-12 19:25:18 +0000298
subrata_modak89d3b4a2008-09-11 11:50:23 +0000299 cleanup();
300
Garrett Cooper2c282152010-12-16 00:55:50 -0800301 tst_exit();
subrata_modak89d3b4a2008-09-11 11:50:23 +0000302}
303
304/*
305 * setup() - performs all the ONE TIME setup for this test.
306 */
vapier0dca7e52008-11-12 19:25:18 +0000307void setup(void)
subrata_modak89d3b4a2008-09-11 11:50:23 +0000308{
Garrett Cooper2c282152010-12-16 00:55:50 -0800309
subrata_modak89d3b4a2008-09-11 11:50:23 +0000310 TEST_PAUSE;
311}
312
313/*
314 * cleanup() - performs all the ONE TIME cleanup for this test at completion
315 * or premature exit.
316 */
vapier0dca7e52008-11-12 19:25:18 +0000317void cleanup(void)
subrata_modak89d3b4a2008-09-11 11:50:23 +0000318{
subrata_modak89d3b4a2008-09-11 11:50:23 +0000319
subrata_modak89d3b4a2008-09-11 11:50:23 +0000320}
321
Chris Dearmanec6edca2012-10-17 19:54:01 -0700322#endif