blob: 9ebc6e261ebfabb7944f6b1e4a880a0303b15953 [file] [log] [blame]
subrata_modakbeedd5d2009-05-29 12:09:53 +00001/******************************************************************************/
2/* Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd */
3/* Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, */
4/* Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, */
5/* Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> */
6/* */
7/* This program is free software; you can redistribute it and/or modify */
8/* it under the terms of the GNU General Public License as published by */
9/* the Free Software Foundation; either version 2 of the License, or */
10/* (at your option) any later version. */
11/* */
12/* This program is distributed in the hope that it will be useful, */
13/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
14/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
15/* the GNU General Public License for more details. */
16/* */
17/* You should have received a copy of the GNU General Public License */
18/* along with this program; if not, write to the Free Software */
Wanlong Gao4548c6c2012-10-19 18:03:36 +080019/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
subrata_modakbeedd5d2009-05-29 12:09:53 +000020/* */
21/******************************************************************************/
22/******************************************************************************/
23/* */
24/* File: ppoll01.c */
25/* */
26/* Description: This tests the ppoll01() syscall */
27/* */
28/* */
29/* */
30/* */
31/* */
32/* */
33/* Usage: <for command-line> */
34/* ppoll01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
35/* where, -c n : Run n copies concurrently. */
36/* -e : Turn on errno logging. */
37/* -i n : Execute test n times. */
38/* -I x : Execute test for x seconds. */
39/* -P x : Pause for x seconds between iterations. */
40/* -t : Turn on syscall timing. */
41/* */
42/* Total Tests: 1 */
43/* */
44/* Test Name: ppoll01 */
45/* History: Porting from Crackerjack to LTP is done by */
46/* Manas Kumar Nayak maknayak@in.ibm.com> */
47/******************************************************************************/
yaberauneya2f765062009-11-26 12:12:32 +000048#ifndef _GNU_SOURCE
49#define _GNU_SOURCE
50#endif
51
subrata_modakbeedd5d2009-05-29 12:09:53 +000052#include <sys/syscall.h>
53#include <sys/types.h>
54#include <sys/select.h>
55#include <sys/wait.h>
56#include <getopt.h>
57#include <string.h>
58#include <stdlib.h>
59#include <errno.h>
60#include <stdio.h>
61#include <unistd.h>
62#include <fcntl.h>
63#include <libgen.h>
64#include <limits.h>
65#include <signal.h>
yaberauneya2f765062009-11-26 12:12:32 +000066#include <poll.h>
subrata_modakbeedd5d2009-05-29 12:09:53 +000067
subrata_modakbeedd5d2009-05-29 12:09:53 +000068#include "../utils/include_j_h.h"
69#include "../utils/common_j_h.c"
70
yaberauneya2f765062009-11-26 12:12:32 +000071#include "ltp_signal.h"
subrata_modakbeedd5d2009-05-29 12:09:53 +000072#include "test.h"
subrata_modakbeedd5d2009-05-29 12:09:53 +000073#include "linux_syscall_numbers.h"
74
yaberauneyafc7a2a52009-12-06 12:45:15 +000075/* Older versions of glibc don't publish this constant's value. */
76#ifndef POLLRDHUP
77#define POLLRDHUP 0x2000
78#endif
79
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020080char *TCID = "ppoll01";
yaberauneyaea695e42009-11-15 01:17:43 +000081int testno;
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020082int TST_TOTAL = 1;
subrata_modakbeedd5d2009-05-29 12:09:53 +000083
Wanlong Gao354ebb42012-12-07 10:10:04 +080084void sighandler(int sig)
Garrett Cooper75b5a4b2010-12-20 15:56:11 -080085{
86 if (sig == SIGINT)
87 return;
88 else
89 tst_brkm(TBROK, NULL, "received unexpected signal %d", sig);
90}
91
Mike Frysingerc57fba52014-04-09 18:56:30 -040092void cleanup(void)
Wanlong Gao354ebb42012-12-07 10:10:04 +080093{
Garrett Cooper2c282152010-12-16 00:55:50 -080094
yaberauneyaea695e42009-11-15 01:17:43 +000095 tst_rmdir();
subrata_modakbeedd5d2009-05-29 12:09:53 +000096}
97
Mike Frysingerc57fba52014-04-09 18:56:30 -040098void setup(void)
Wanlong Gao354ebb42012-12-07 10:10:04 +080099{
Garrett Cooper75b5a4b2010-12-20 15:56:11 -0800100 tst_sig(FORK, sighandler, cleanup);
subrata_modakd07b5952009-10-14 20:22:42 +0000101
yaberauneyaea695e42009-11-15 01:17:43 +0000102 TEST_PAUSE;
103 tst_tmpdir();
subrata_modakbeedd5d2009-05-29 12:09:53 +0000104}
105
subrata_modakbeedd5d2009-05-29 12:09:53 +0000106/*
107 * Macros
108 */
109#define SYSCALL_NAME "ppoll"
110
subrata_modakbeedd5d2009-05-29 12:09:53 +0000111/*
112 * Global variables
113 */
subrata_modakbeedd5d2009-05-29 12:09:53 +0000114
115enum test_type {
116 NORMAL,
yaberauneyaea695e42009-11-15 01:17:43 +0000117 MASK_SIGNAL,
118 TIMEOUT,
119 FD_ALREADY_CLOSED,
120 SEND_SIGINT,
121 SEND_SIGINT_RACE_TEST,
122 INVALID_NFDS,
123 INVALID_FDS,
124 MINUS_NSEC,
125 TOO_LARGE_NSEC,
subrata_modakbeedd5d2009-05-29 12:09:53 +0000126};
127
subrata_modakbeedd5d2009-05-29 12:09:53 +0000128/*
129 * Data Structure
130 */
131struct test_case {
132 short expect_revents;
yaberauneyaea695e42009-11-15 01:17:43 +0000133 int ttype;
134 int ret;
135 int err;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000136};
137
subrata_modakbeedd5d2009-05-29 12:09:53 +0000138/* Test cases
139 *
140 * test status of errors on man page
141 *
142 * EBADF can't check because EBADF never happen even though
143 * fd was invalid. In this case, information of invalid
144 * fd is set in revents
145 * EFAULT v ('fds' array in the invalid address space)
146 * EINTR v (a non blocked signal was caught)
147 * EINVAL v ('nfds' is over the 'RLIMIT_NOFILE' value)
148 * ENOMEM can't check because it's difficult to create no-memory
149 */
150
subrata_modakbeedd5d2009-05-29 12:09:53 +0000151static struct test_case tcase[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800152 { // case00
153 .ttype = NORMAL,
154 .expect_revents = POLLIN | POLLOUT,
155 .ret = 0,
156 .err = 0,
157 },
158 { // case01
159 .ttype = MASK_SIGNAL,
160 .expect_revents = 0, // don't care
161 .ret = 0,
162 .err = 0,
163 },
164 { // case02
165 .ttype = TIMEOUT,
166 .expect_revents = 0, // don't care
167 .ret = 0,
168 .err = 0,
169 },
170 { // case03
171 .ttype = FD_ALREADY_CLOSED,
172 .expect_revents = POLLNVAL,
173 .ret = 0,.err = 0,
174 },
175 { // case04
176 .ttype = SEND_SIGINT,
177 .ret = -1,
178 .err = EINTR,
179 },
180 { // case05
181 .ttype = SEND_SIGINT_RACE_TEST,
182 .ret = -1,
183 .err = EINTR,
184 },
185 { // case06
186 .ttype = INVALID_NFDS,
187 .ret = -1,
188 .err = EINVAL,
189 },
190 { // case07
191 .ttype = INVALID_FDS,
192 .ret = -1,
193 .err = EFAULT,},
subrata_modakbeedd5d2009-05-29 12:09:53 +0000194#if 0
Wanlong Gao354ebb42012-12-07 10:10:04 +0800195 { // case08
196 .ttype = MINUS_NSEC,
197 .ret = -1,
198 .err = EINVAL, // RHEL4U1 + 2.6.18 returns SUCCESS
199 },
200 { // case09
201 .ttype = TOO_LARGE_NSEC,
202 .ret = -1,
203 .err = EINVAL, // RHEL4U1 + 2.6.18 returns SUCCESS
204 },
subrata_modakbeedd5d2009-05-29 12:09:53 +0000205#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800206};
subrata_modakbeedd5d2009-05-29 12:09:53 +0000207
208#define NUM_TEST_FDS 1
209
210/*
211 * do_test()
212 *
213 * Input : TestCase Data
214 * Return : RESULT_OK(0), RESULT_NG(1)
215 *
216 */
217
Wanlong Gao354ebb42012-12-07 10:10:04 +0800218static int do_test(struct test_case *tc)
219{
yaberauneyaea695e42009-11-15 01:17:43 +0000220 int sys_ret, sys_errno;
221 int result = RESULT_OK;
222 int fd = -1, cmp_ok = 1;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000223 char fpath[PATH_MAX];
224 struct pollfd *p_fds, fds[NUM_TEST_FDS];
yaberauneyaea695e42009-11-15 01:17:43 +0000225 unsigned int nfds = NUM_TEST_FDS;
226 struct timespec *p_ts, ts;
227 sigset_t *p_sigmask, sigmask;
228 pid_t pid = 0;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000229
yaberauneyaea695e42009-11-15 01:17:43 +0000230 TEST(fd = setup_file(".", "test.file", fpath));
231 if (fd < 0)
232 return 1;
233 fds[0].fd = fd;
234 fds[0].events = POLLIN | POLLPRI | POLLOUT | POLLRDHUP;
235 fds[0].revents = 0;
236 p_fds = fds;
237 p_ts = NULL;
238 p_sigmask = NULL;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000239
240 switch (tc->ttype) {
yaberauneyaea695e42009-11-15 01:17:43 +0000241 case TIMEOUT:
242 nfds = 0;
243 ts.tv_sec = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800244 ts.tv_nsec = 50000000; // 50msec
yaberauneyaea695e42009-11-15 01:17:43 +0000245 p_ts = &ts;
246 break;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000247 case FD_ALREADY_CLOSED:
yaberauneyaea695e42009-11-15 01:17:43 +0000248 TEST(close(fd));
249 fd = -1;
250 TEST(cleanup_file(fpath));
251 break;
252 case MASK_SIGNAL:
253 TEST(sigemptyset(&sigmask));
254 TEST(sigaddset(&sigmask, SIGINT));
255 p_sigmask = &sigmask;
256 nfds = 0;
257 ts.tv_sec = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800258 ts.tv_nsec = 300000000; // 300msec => need to be enough for
yaberauneyaea695e42009-11-15 01:17:43 +0000259 // waiting the signal
260 p_ts = &ts;
261 // fallthrough
subrata_modakbeedd5d2009-05-29 12:09:53 +0000262 case SEND_SIGINT:
yaberauneyaea695e42009-11-15 01:17:43 +0000263 nfds = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800264 pid = create_sig_proc(100000, SIGINT, UINT_MAX); // 100msec
yaberauneyaea695e42009-11-15 01:17:43 +0000265 if (pid < 0)
266 return 1;
267 break;
268 case SEND_SIGINT_RACE_TEST:
269 /* block the INT signal */
270 sigemptyset(&sigmask);
271 sigaddset(&sigmask, SIGINT);
272 sigprocmask(SIG_SETMASK, &sigmask, NULL);
subrata_modak447cb962009-09-27 17:38:06 +0000273
yaberauneyaea695e42009-11-15 01:17:43 +0000274 /* and let it be unblocked when the syscall runs */
275 sigemptyset(&sigmask);
276 p_sigmask = &sigmask;
277 nfds = 0;
278 ts.tv_sec = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800279 ts.tv_nsec = 300000000; // 300msec => need to be enough for
yaberauneyaea695e42009-11-15 01:17:43 +0000280 // waiting the signal
281 p_ts = &ts;
282 nfds = 0;
283 pid = create_sig_proc(0, SIGINT, 1);
284 if (pid < 0) {
285 result = 1;
286 goto cleanup;
287 }
288 break;
289 case INVALID_NFDS:
290 //nfds = RLIMIT_NOFILE + 1; //==> RHEL4U1 + 2.6.18 returns SUCCESS
291 nfds = -1;
292 break;
293 case INVALID_FDS:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800294 p_fds = (void *)0xc0000000;
yaberauneyaea695e42009-11-15 01:17:43 +0000295 break;
296 case MINUS_NSEC:
297 ts.tv_sec = 0;
298 ts.tv_nsec = -1;
299 p_ts = &ts;
300 break;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000301 case TOO_LARGE_NSEC:
yaberauneyaea695e42009-11-15 01:17:43 +0000302 ts.tv_sec = 0;
303 ts.tv_nsec = 1000000000;
304 p_ts = &ts;
305 break;
306 }
subrata_modakbeedd5d2009-05-29 12:09:53 +0000307
308 /*
yaberauneyaea695e42009-11-15 01:17:43 +0000309 * Execute system call
310 */
311 errno = 0;
Jan Stancek359980f2013-02-15 10:16:05 +0100312 sys_ret = ltp_syscall(__NR_ppoll, p_fds, nfds, p_ts, p_sigmask,
313 SIGSETSIZE);
Garrett Cooper53740502010-12-16 00:04:01 -0800314 sys_errno = errno;
yaberauneyaea695e42009-11-15 01:17:43 +0000315 if (sys_ret <= 0 || tc->ret < 0)
316 goto TEST_END;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000317
yaberauneyaea695e42009-11-15 01:17:43 +0000318 cmp_ok = fds[0].revents == tc->expect_revents;
319 tst_resm(TINFO, "EXPECT: revents=0x%04x", tc->expect_revents);
320 tst_resm(TINFO, "RESULT: revents=0x%04x", fds[0].revents);
subrata_modakbeedd5d2009-05-29 12:09:53 +0000321
Garrett Cooper53740502010-12-16 00:04:01 -0800322TEST_END:
yaberauneyaea695e42009-11-15 01:17:43 +0000323 /*
324 * Check results
325 */
326 if (tc->ttype == SEND_SIGINT_RACE_TEST) {
327 int sig;
328 sigprocmask(SIG_SETMASK, NULL, &sigmask);
329 for (sig = 1; sig < SIGRTMAX; sig++) {
330 TEST(sigismember(&sigmask, sig));
Wanlong Gao354ebb42012-12-07 10:10:04 +0800331 if (TEST_RETURN < 0 && TEST_ERRNO == EINVAL
332 && sig != SIGINT)
333 continue; /* let's ignore errors if they are for other signal than SIGINT that we set */
yaberauneyaea695e42009-11-15 01:17:43 +0000334 if ((sig == SIGINT) != (TEST_RETURN != 0)) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800335 tst_resm(TFAIL,
336 "Bad value of signal mask, signal %d is %s",
337 sig, TEST_RETURN ? "on" : "off");
yaberauneyaea695e42009-11-15 01:17:43 +0000338 cmp_ok |= 1;
339 }
340 }
341 }
342 result |= (sys_errno != tc->err) || !cmp_ok;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800343 PRINT_RESULT_CMP(sys_ret >= 0, tc->ret, tc->err, sys_ret, sys_errno,
344 cmp_ok);
Garrett Cooper53740502010-12-16 00:04:01 -0800345cleanup:
346 if (fd >= 0) {
Subrata Modak76a720a2010-07-03 21:08:18 +0530347 close(fd);
yaberauneyaea695e42009-11-15 01:17:43 +0000348 cleanup_file(fpath);
Subrata Modak76a720a2010-07-03 21:08:18 +0530349 }
subrata_modak447cb962009-09-27 17:38:06 +0000350
yaberauneyaea695e42009-11-15 01:17:43 +0000351 sigemptyset(&sigmask);
352 sigprocmask(SIG_SETMASK, &sigmask, NULL);
353 if (pid > 0) {
354 int st;
355 kill(pid, SIGTERM);
356 wait(&st);
357 }
subrata_modakbeedd5d2009-05-29 12:09:53 +0000358 return result;
359}
360
subrata_modakbeedd5d2009-05-29 12:09:53 +0000361/*
subrata_modakbeedd5d2009-05-29 12:09:53 +0000362 * main()
363 */
364
Wanlong Gao354ebb42012-12-07 10:10:04 +0800365int main(int ac, char **av)
366{
yaberauneyaea695e42009-11-15 01:17:43 +0000367 int i;
Garrett Cooper53740502010-12-16 00:04:01 -0800368 int ret;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000369
yaberauneyaea695e42009-11-15 01:17:43 +0000370 setup();
subrata_modakbeedd5d2009-05-29 12:09:53 +0000371
Garrett Cooper53740502010-12-16 00:04:01 -0800372 ret = 0;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000373
Wanlong Gao354ebb42012-12-07 10:10:04 +0800374 for (i = 0; ret == 0 && i < (sizeof(tcase) / sizeof(tcase[0])); i++) {
Garrett Cooper53740502010-12-16 00:04:01 -0800375 tst_resm(TINFO, "(case%02d) START", i);
376 ret = do_test(&tcase[i]);
377 tst_resm(TINFO, "(case%02d) END => %s", i, (ret == 0) ? "OK"
Wanlong Gao354ebb42012-12-07 10:10:04 +0800378 : "NG");
yaberauneyaea695e42009-11-15 01:17:43 +0000379 }
380 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800381 tst_exit();
Garrett Cooper52626672010-12-20 15:03:21 -0800382}