blob: 0bf50d74928ea012c4d4539a36386ae5115d13a5 [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
71/* Harness Specific Include Files. */
yaberauneya2f765062009-11-26 12:12:32 +000072#include "ltp_signal.h"
subrata_modakbeedd5d2009-05-29 12:09:53 +000073#include "test.h"
74#include "usctest.h"
75#include "linux_syscall_numbers.h"
76
yaberauneyafc7a2a52009-12-06 12:45:15 +000077/* Older versions of glibc don't publish this constant's value. */
78#ifndef POLLRDHUP
79#define POLLRDHUP 0x2000
80#endif
81
Wanlong Gao354ebb42012-12-07 10:10:04 +080082char *TCID = "ppoll01"; /* Test program identifier. */
yaberauneyaea695e42009-11-15 01:17:43 +000083int testno;
Wanlong Gao354ebb42012-12-07 10:10:04 +080084int TST_TOTAL = 1; /* total number of tests in this file. */
subrata_modakbeedd5d2009-05-29 12:09:53 +000085
Wanlong Gao354ebb42012-12-07 10:10:04 +080086void sighandler(int sig)
Garrett Cooper75b5a4b2010-12-20 15:56:11 -080087{
88 if (sig == SIGINT)
89 return;
90 else
91 tst_brkm(TBROK, NULL, "received unexpected signal %d", sig);
92}
93
Wanlong Gao354ebb42012-12-07 10:10:04 +080094void cleanup()
95{
Garrett Cooper2c282152010-12-16 00:55:50 -080096
yaberauneyaea695e42009-11-15 01:17:43 +000097 TEST_CLEANUP;
98 tst_rmdir();
subrata_modakbeedd5d2009-05-29 12:09:53 +000099}
100
Wanlong Gao354ebb42012-12-07 10:10:04 +0800101void setup()
102{
Garrett Cooper75b5a4b2010-12-20 15:56:11 -0800103 tst_sig(FORK, sighandler, cleanup);
subrata_modakd07b5952009-10-14 20:22:42 +0000104
yaberauneyaea695e42009-11-15 01:17:43 +0000105 TEST_PAUSE;
106 tst_tmpdir();
subrata_modakbeedd5d2009-05-29 12:09:53 +0000107}
108
subrata_modakbeedd5d2009-05-29 12:09:53 +0000109/*
110 * Macros
111 */
112#define SYSCALL_NAME "ppoll"
113
subrata_modakbeedd5d2009-05-29 12:09:53 +0000114/*
115 * Global variables
116 */
subrata_modakbeedd5d2009-05-29 12:09:53 +0000117
118enum test_type {
119 NORMAL,
yaberauneyaea695e42009-11-15 01:17:43 +0000120 MASK_SIGNAL,
121 TIMEOUT,
122 FD_ALREADY_CLOSED,
123 SEND_SIGINT,
124 SEND_SIGINT_RACE_TEST,
125 INVALID_NFDS,
126 INVALID_FDS,
127 MINUS_NSEC,
128 TOO_LARGE_NSEC,
subrata_modakbeedd5d2009-05-29 12:09:53 +0000129};
130
subrata_modakbeedd5d2009-05-29 12:09:53 +0000131/*
132 * Data Structure
133 */
134struct test_case {
135 short expect_revents;
yaberauneyaea695e42009-11-15 01:17:43 +0000136 int ttype;
137 int ret;
138 int err;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000139};
140
subrata_modakbeedd5d2009-05-29 12:09:53 +0000141/* Test cases
142 *
143 * test status of errors on man page
144 *
145 * EBADF can't check because EBADF never happen even though
146 * fd was invalid. In this case, information of invalid
147 * fd is set in revents
148 * EFAULT v ('fds' array in the invalid address space)
149 * EINTR v (a non blocked signal was caught)
150 * EINVAL v ('nfds' is over the 'RLIMIT_NOFILE' value)
151 * ENOMEM can't check because it's difficult to create no-memory
152 */
153
subrata_modakbeedd5d2009-05-29 12:09:53 +0000154static struct test_case tcase[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800155 { // case00
156 .ttype = NORMAL,
157 .expect_revents = POLLIN | POLLOUT,
158 .ret = 0,
159 .err = 0,
160 },
161 { // case01
162 .ttype = MASK_SIGNAL,
163 .expect_revents = 0, // don't care
164 .ret = 0,
165 .err = 0,
166 },
167 { // case02
168 .ttype = TIMEOUT,
169 .expect_revents = 0, // don't care
170 .ret = 0,
171 .err = 0,
172 },
173 { // case03
174 .ttype = FD_ALREADY_CLOSED,
175 .expect_revents = POLLNVAL,
176 .ret = 0,.err = 0,
177 },
178 { // case04
179 .ttype = SEND_SIGINT,
180 .ret = -1,
181 .err = EINTR,
182 },
183 { // case05
184 .ttype = SEND_SIGINT_RACE_TEST,
185 .ret = -1,
186 .err = EINTR,
187 },
188 { // case06
189 .ttype = INVALID_NFDS,
190 .ret = -1,
191 .err = EINVAL,
192 },
193 { // case07
194 .ttype = INVALID_FDS,
195 .ret = -1,
196 .err = EFAULT,},
subrata_modakbeedd5d2009-05-29 12:09:53 +0000197#if 0
Wanlong Gao354ebb42012-12-07 10:10:04 +0800198 { // case08
199 .ttype = MINUS_NSEC,
200 .ret = -1,
201 .err = EINVAL, // RHEL4U1 + 2.6.18 returns SUCCESS
202 },
203 { // case09
204 .ttype = TOO_LARGE_NSEC,
205 .ret = -1,
206 .err = EINVAL, // RHEL4U1 + 2.6.18 returns SUCCESS
207 },
subrata_modakbeedd5d2009-05-29 12:09:53 +0000208#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800209};
subrata_modakbeedd5d2009-05-29 12:09:53 +0000210
211#define NUM_TEST_FDS 1
212
213/*
214 * do_test()
215 *
216 * Input : TestCase Data
217 * Return : RESULT_OK(0), RESULT_NG(1)
218 *
219 */
220
Wanlong Gao354ebb42012-12-07 10:10:04 +0800221static int do_test(struct test_case *tc)
222{
yaberauneyaea695e42009-11-15 01:17:43 +0000223 int sys_ret, sys_errno;
224 int result = RESULT_OK;
225 int fd = -1, cmp_ok = 1;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000226 char fpath[PATH_MAX];
227 struct pollfd *p_fds, fds[NUM_TEST_FDS];
yaberauneyaea695e42009-11-15 01:17:43 +0000228 unsigned int nfds = NUM_TEST_FDS;
229 struct timespec *p_ts, ts;
230 sigset_t *p_sigmask, sigmask;
231 pid_t pid = 0;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000232
yaberauneyaea695e42009-11-15 01:17:43 +0000233 TEST(fd = setup_file(".", "test.file", fpath));
234 if (fd < 0)
235 return 1;
236 fds[0].fd = fd;
237 fds[0].events = POLLIN | POLLPRI | POLLOUT | POLLRDHUP;
238 fds[0].revents = 0;
239 p_fds = fds;
240 p_ts = NULL;
241 p_sigmask = NULL;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000242
243 switch (tc->ttype) {
yaberauneyaea695e42009-11-15 01:17:43 +0000244 case TIMEOUT:
245 nfds = 0;
246 ts.tv_sec = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800247 ts.tv_nsec = 50000000; // 50msec
yaberauneyaea695e42009-11-15 01:17:43 +0000248 p_ts = &ts;
249 break;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000250 case FD_ALREADY_CLOSED:
yaberauneyaea695e42009-11-15 01:17:43 +0000251 TEST(close(fd));
252 fd = -1;
253 TEST(cleanup_file(fpath));
254 break;
255 case MASK_SIGNAL:
256 TEST(sigemptyset(&sigmask));
257 TEST(sigaddset(&sigmask, SIGINT));
258 p_sigmask = &sigmask;
259 nfds = 0;
260 ts.tv_sec = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800261 ts.tv_nsec = 300000000; // 300msec => need to be enough for
yaberauneyaea695e42009-11-15 01:17:43 +0000262 // waiting the signal
263 p_ts = &ts;
264 // fallthrough
subrata_modakbeedd5d2009-05-29 12:09:53 +0000265 case SEND_SIGINT:
yaberauneyaea695e42009-11-15 01:17:43 +0000266 nfds = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800267 pid = create_sig_proc(100000, SIGINT, UINT_MAX); // 100msec
yaberauneyaea695e42009-11-15 01:17:43 +0000268 if (pid < 0)
269 return 1;
270 break;
271 case SEND_SIGINT_RACE_TEST:
272 /* block the INT signal */
273 sigemptyset(&sigmask);
274 sigaddset(&sigmask, SIGINT);
275 sigprocmask(SIG_SETMASK, &sigmask, NULL);
subrata_modak447cb962009-09-27 17:38:06 +0000276
yaberauneyaea695e42009-11-15 01:17:43 +0000277 /* and let it be unblocked when the syscall runs */
278 sigemptyset(&sigmask);
279 p_sigmask = &sigmask;
280 nfds = 0;
281 ts.tv_sec = 0;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800282 ts.tv_nsec = 300000000; // 300msec => need to be enough for
yaberauneyaea695e42009-11-15 01:17:43 +0000283 // waiting the signal
284 p_ts = &ts;
285 nfds = 0;
286 pid = create_sig_proc(0, SIGINT, 1);
287 if (pid < 0) {
288 result = 1;
289 goto cleanup;
290 }
291 break;
292 case INVALID_NFDS:
293 //nfds = RLIMIT_NOFILE + 1; //==> RHEL4U1 + 2.6.18 returns SUCCESS
294 nfds = -1;
295 break;
296 case INVALID_FDS:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800297 p_fds = (void *)0xc0000000;
yaberauneyaea695e42009-11-15 01:17:43 +0000298 break;
299 case MINUS_NSEC:
300 ts.tv_sec = 0;
301 ts.tv_nsec = -1;
302 p_ts = &ts;
303 break;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000304 case TOO_LARGE_NSEC:
yaberauneyaea695e42009-11-15 01:17:43 +0000305 ts.tv_sec = 0;
306 ts.tv_nsec = 1000000000;
307 p_ts = &ts;
308 break;
309 }
subrata_modakbeedd5d2009-05-29 12:09:53 +0000310
311 /*
yaberauneyaea695e42009-11-15 01:17:43 +0000312 * Execute system call
313 */
314 errno = 0;
Jan Stancek359980f2013-02-15 10:16:05 +0100315 sys_ret = ltp_syscall(__NR_ppoll, p_fds, nfds, p_ts, p_sigmask,
316 SIGSETSIZE);
Garrett Cooper53740502010-12-16 00:04:01 -0800317 sys_errno = errno;
yaberauneyaea695e42009-11-15 01:17:43 +0000318 if (sys_ret <= 0 || tc->ret < 0)
319 goto TEST_END;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000320
yaberauneyaea695e42009-11-15 01:17:43 +0000321 cmp_ok = fds[0].revents == tc->expect_revents;
322 tst_resm(TINFO, "EXPECT: revents=0x%04x", tc->expect_revents);
323 tst_resm(TINFO, "RESULT: revents=0x%04x", fds[0].revents);
subrata_modakbeedd5d2009-05-29 12:09:53 +0000324
Garrett Cooper53740502010-12-16 00:04:01 -0800325TEST_END:
yaberauneyaea695e42009-11-15 01:17:43 +0000326 /*
327 * Check results
328 */
329 if (tc->ttype == SEND_SIGINT_RACE_TEST) {
330 int sig;
331 sigprocmask(SIG_SETMASK, NULL, &sigmask);
332 for (sig = 1; sig < SIGRTMAX; sig++) {
333 TEST(sigismember(&sigmask, sig));
Wanlong Gao354ebb42012-12-07 10:10:04 +0800334 if (TEST_RETURN < 0 && TEST_ERRNO == EINVAL
335 && sig != SIGINT)
336 continue; /* let's ignore errors if they are for other signal than SIGINT that we set */
yaberauneyaea695e42009-11-15 01:17:43 +0000337 if ((sig == SIGINT) != (TEST_RETURN != 0)) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800338 tst_resm(TFAIL,
339 "Bad value of signal mask, signal %d is %s",
340 sig, TEST_RETURN ? "on" : "off");
yaberauneyaea695e42009-11-15 01:17:43 +0000341 cmp_ok |= 1;
342 }
343 }
344 }
345 result |= (sys_errno != tc->err) || !cmp_ok;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800346 PRINT_RESULT_CMP(sys_ret >= 0, tc->ret, tc->err, sys_ret, sys_errno,
347 cmp_ok);
Garrett Cooper53740502010-12-16 00:04:01 -0800348cleanup:
349 if (fd >= 0) {
Subrata Modak76a720a2010-07-03 21:08:18 +0530350 close(fd);
yaberauneyaea695e42009-11-15 01:17:43 +0000351 cleanup_file(fpath);
Subrata Modak76a720a2010-07-03 21:08:18 +0530352 }
subrata_modak447cb962009-09-27 17:38:06 +0000353
yaberauneyaea695e42009-11-15 01:17:43 +0000354 sigemptyset(&sigmask);
355 sigprocmask(SIG_SETMASK, &sigmask, NULL);
356 if (pid > 0) {
357 int st;
358 kill(pid, SIGTERM);
359 wait(&st);
360 }
subrata_modakbeedd5d2009-05-29 12:09:53 +0000361 return result;
362}
363
subrata_modakbeedd5d2009-05-29 12:09:53 +0000364/*
subrata_modakbeedd5d2009-05-29 12:09:53 +0000365 * main()
366 */
367
Wanlong Gao354ebb42012-12-07 10:10:04 +0800368int main(int ac, char **av)
369{
yaberauneyaea695e42009-11-15 01:17:43 +0000370 int i;
Garrett Cooper53740502010-12-16 00:04:01 -0800371 int ret;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000372
yaberauneyaea695e42009-11-15 01:17:43 +0000373 setup();
subrata_modakbeedd5d2009-05-29 12:09:53 +0000374
Garrett Cooper53740502010-12-16 00:04:01 -0800375 ret = 0;
subrata_modakbeedd5d2009-05-29 12:09:53 +0000376
Wanlong Gao354ebb42012-12-07 10:10:04 +0800377 for (i = 0; ret == 0 && i < (sizeof(tcase) / sizeof(tcase[0])); i++) {
Garrett Cooper53740502010-12-16 00:04:01 -0800378 tst_resm(TINFO, "(case%02d) START", i);
379 ret = do_test(&tcase[i]);
380 tst_resm(TINFO, "(case%02d) END => %s", i, (ret == 0) ? "OK"
Wanlong Gao354ebb42012-12-07 10:10:04 +0800381 : "NG");
yaberauneyaea695e42009-11-15 01:17:43 +0000382 }
383 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800384 tst_exit();
Garrett Cooper52626672010-12-20 15:03:21 -0800385}