blob: 45dee62830a481143cf3a7fca43a77a4ba5b2bb6 [file] [log] [blame]
subrata_modak2f3f9562009-05-29 10:35:39 +00001/******************************************************************************/
Garrett Cooperd74fde62010-11-22 15:21:28 -08002/* Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd */
3/* Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, */
subrata_modak2f3f9562009-05-29 10:35:39 +00004/* Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, */
5/* Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> */
Garrett Cooperd74fde62010-11-22 15:21:28 -08006/* */
subrata_modak2f3f9562009-05-29 10:35:39 +00007/* 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 */
Garrett Cooperd74fde62010-11-22 15:21:28 -08009/* 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 */
Garrett Cooperd74fde62010-11-22 15:21:28 -080020/* */
subrata_modak2f3f9562009-05-29 10:35:39 +000021/******************************************************************************/
22/******************************************************************************/
Garrett Cooperd74fde62010-11-22 15:21:28 -080023/* */
24/* File: clock_nanosleep01.c */
25/* */
26/* Description: This tests the clock_nanosleep() syscall */
subrata_modak2f3f9562009-05-29 10:35:39 +000027/* */
28/* */
29/* */
30/* */
31/* */
Garrett Cooperd74fde62010-11-22 15:21:28 -080032/* */
33/* Usage: <for command-line> */
34/* clock_nanosleep01 [-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: clock_nanosleep01 */
45/* History: Porting from Crackerjack to LTP is done by */
46/* Manas Kumar Nayak maknayak@in.ibm.com> */
subrata_modak2f3f9562009-05-29 10:35:39 +000047/******************************************************************************/
48#include <sys/syscall.h>
49#include <sys/types.h>
50#include <getopt.h>
51#include <string.h>
52#include <stdlib.h>
53#include <errno.h>
54#include <stdio.h>
55#include <time.h>
56#include <signal.h>
57#include "../utils/common_j_h.c"
58#include "../utils/include_j_h.h"
59
subrata_modak2f3f9562009-05-29 10:35:39 +000060#include "test.h"
subrata_modak2f3f9562009-05-29 10:35:39 +000061#include "linux_syscall_numbers.h"
62
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020063char *TCID = "clock_nanosleep01";
Wanlong Gao354ebb42012-12-07 10:10:04 +080064int testno;
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020065int TST_TOTAL = 1;
subrata_modak266ec972009-10-18 17:56:53 +000066struct sigaction act;
67
68/*
69 * sighandler()
70 */
71void sighandler(int sig)
72{
Garrett Cooperd74fde62010-11-22 15:21:28 -080073 if (sig == SIGINT)
74 return;
Garrett Cooper2c282152010-12-16 00:55:50 -080075
Garrett Cooperd74fde62010-11-22 15:21:28 -080076 return;
subrata_modak266ec972009-10-18 17:56:53 +000077}
subrata_modak2f3f9562009-05-29 10:35:39 +000078
79/* Extern Global Functions */
80/******************************************************************************/
Garrett Cooperd74fde62010-11-22 15:21:28 -080081/* */
82/* Function: cleanup */
83/* */
subrata_modak2f3f9562009-05-29 10:35:39 +000084/* Description: Performs all one time clean up for this test on successful */
Garrett Cooperd74fde62010-11-22 15:21:28 -080085/* completion, premature exit or failure. Closes all temporary */
86/* files, removes all temporary directories exits the test with */
87/* appropriate return code by calling tst_exit() function. */
88/* */
89/* Input: None. */
90/* */
91/* Output: None. */
92/* */
subrata_modak2f3f9562009-05-29 10:35:39 +000093/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */
Garrett Cooperd74fde62010-11-22 15:21:28 -080094/* On success - Exits calling tst_exit(). With '0' return code. */
95/* */
subrata_modak2f3f9562009-05-29 10:35:39 +000096/******************************************************************************/
Mike Frysingerc57fba52014-04-09 18:56:30 -040097void cleanup(void)
Wanlong Gao354ebb42012-12-07 10:10:04 +080098{
Garrett Cooper2c282152010-12-16 00:55:50 -080099
Garrett Cooperd74fde62010-11-22 15:21:28 -0800100 tst_rmdir();
subrata_modak2f3f9562009-05-29 10:35:39 +0000101
subrata_modak2f3f9562009-05-29 10:35:39 +0000102}
103
104/* Local Functions */
105/******************************************************************************/
Garrett Cooperd74fde62010-11-22 15:21:28 -0800106/* */
107/* Function: setup */
108/* */
subrata_modak2f3f9562009-05-29 10:35:39 +0000109/* Description: Performs all one time setup for this test. This function is */
Garrett Cooperd74fde62010-11-22 15:21:28 -0800110/* typically used to capture signals, create temporary dirs */
111/* and temporary files that may be used in the course of this */
112/* test. */
113/* */
114/* Input: None. */
115/* */
116/* Output: None. */
117/* */
118/* Return: On failure - Exits by calling cleanup(). */
119/* On success - returns 0. */
120/* */
subrata_modak2f3f9562009-05-29 10:35:39 +0000121/******************************************************************************/
Mike Frysingerc57fba52014-04-09 18:56:30 -0400122void setup(void)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800123{
Garrett Cooperd74fde62010-11-22 15:21:28 -0800124 /* Capture signals if any */
subrata_modak266ec972009-10-18 17:56:53 +0000125 act.sa_handler = sighandler;
126 sigfillset(&act.sa_mask);
127 sigaction(SIGINT, &act, NULL);
128
Garrett Cooperd74fde62010-11-22 15:21:28 -0800129 /* Create temporary directories */
130 TEST_PAUSE;
131 tst_tmpdir();
subrata_modak2f3f9562009-05-29 10:35:39 +0000132}
133
subrata_modak2f3f9562009-05-29 10:35:39 +0000134/*
135 * Macros
136 */
137#define SYSCALL_NAME "clock_nanosleep"
138
subrata_modak2f3f9562009-05-29 10:35:39 +0000139enum test_type {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800140 NORMAL,
141 NULL_POINTER,
142 SEND_SIGINT,
subrata_modak2f3f9562009-05-29 10:35:39 +0000143};
144
subrata_modak2f3f9562009-05-29 10:35:39 +0000145/*
146 * Data Structure
147 */
148struct test_case {
149 clockid_t clk_id;
150 int ttype;
Garrett Cooperd74fde62010-11-22 15:21:28 -0800151 int flags;
152 time_t sec;
153 long nsec;
subrata_modak2f3f9562009-05-29 10:35:39 +0000154 int ret;
Garrett Cooperd74fde62010-11-22 15:21:28 -0800155 int err;
subrata_modak2f3f9562009-05-29 10:35:39 +0000156};
157
subrata_modak2f3f9562009-05-29 10:35:39 +0000158/* Test cases
159 *
160 * test status of errors on man page
161 *
Garrett Cooperd74fde62010-11-22 15:21:28 -0800162 * EINTR v (function was interrupted by a signal)
163 * EINVAL v (invalid tv_nsec, etc.)
164 * ENOTSUP can't check because not supported clk_id generates
165 * EINVAL
subrata_modak2f3f9562009-05-29 10:35:39 +0000166 */
167
subrata_modak2f3f9562009-05-29 10:35:39 +0000168static struct test_case tcase[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800169 { // case00
170 .clk_id = CLOCK_REALTIME,
171 .ttype = NORMAL,
172 .flags = 0,
173 .sec = 0,
174 .nsec = 500000000, // 500msec
175 .ret = 0,
176 .err = 0,
177 },
178 { // case01
179 .clk_id = CLOCK_MONOTONIC,
180 .ttype = NORMAL,
181 .flags = 0,
182 .sec = 0,
183 .nsec = 500000000, // 500msec
184 .ret = 0,
185 .err = 0,
186 },
187 { // case02
188 .ttype = NORMAL,
189 .clk_id = CLOCK_REALTIME,
190 .flags = 0,
191 .sec = 0,
192 .nsec = -1, // invalid
193 .ret = EINVAL,
194 .err = 0,
195 },
196 { // case03
197 .ttype = NORMAL,
198 .clk_id = CLOCK_REALTIME,
199 .flags = 0,
200 .sec = 0,
201 .nsec = 1000000000, // invalid
202 .ret = EINVAL,
203 .err = 0,
204 },
205 { // case04
206 .ttype = NORMAL,
207 .clk_id = CLOCK_THREAD_CPUTIME_ID, // not supported
208 .flags = 0,
209 .sec = 0,
210 .nsec = 500000000, // 500msec
211 .ret = EINVAL, // RHEL4U1 + 2.6.18 returns EINVAL
212 .err = 0,
213 },
214 { // case05
215 .ttype = SEND_SIGINT,
216 .clk_id = CLOCK_REALTIME,
217 .flags = 0,
218 .sec = 10,
219 .nsec = 0,
220 .ret = EINTR,
221 .err = 0,
222 },
223#if 0 // glibc generates SEGV error (RHEL4U1 + 2.6.18)
224 { // caseXX
225 .ttype = NULL_POINTER,
226 .clk_id = CLOCK_REALTIME,
227 .flags = 0,
228 .sec = 0,
229 .nsec = 500000000, // 500msec
230 .ret = EFAULT,
231 .err = 0,
232 },
subrata_modak2f3f9562009-05-29 10:35:39 +0000233#endif
234};
235
subrata_modak2f3f9562009-05-29 10:35:39 +0000236/*
237 * chk_difftime()
238 * Return : OK(0), NG(-1)
239 */
240#define MAX_MSEC_DIFF 20
241
242static int chk_difftime(struct timespec *bef, struct timespec *aft,
Garrett Cooperd74fde62010-11-22 15:21:28 -0800243 time_t sec, long nsec)
subrata_modak2f3f9562009-05-29 10:35:39 +0000244{
Garrett Cooperd74fde62010-11-22 15:21:28 -0800245 struct timespec t;
246 time_t expect;
247 time_t result;
subrata_modak2f3f9562009-05-29 10:35:39 +0000248
Garrett Cooperd74fde62010-11-22 15:21:28 -0800249 t.tv_sec = aft->tv_sec - bef->tv_sec;
250 t.tv_nsec = aft->tv_nsec - bef->tv_nsec;
251 if (t.tv_nsec < 0) {
252 t.tv_sec -= 1;
253 t.tv_nsec += 1000000000;
254 }
255 expect = (sec * 1000) + (nsec / 1000000);
256 result = (t.tv_sec * 1000) + (t.tv_nsec / 1000000);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800257 tst_resm(TINFO, "check sleep time: (min:%ld) < %ld < (max:%ld) (msec)",
258 expect - MAX_MSEC_DIFF, result, expect + MAX_MSEC_DIFF);
Garrett Cooperd74fde62010-11-22 15:21:28 -0800259 if (result < expect - MAX_MSEC_DIFF || result > expect + MAX_MSEC_DIFF)
260 return -1;
subrata_modak2f3f9562009-05-29 10:35:39 +0000261 return 0;
262}
263
subrata_modak2f3f9562009-05-29 10:35:39 +0000264/*
265 * do_test()
266 *
267 * Input : TestCase Data
268 * Return : RESULT_OK(0), RESULT_NG(1)
269 *
270 */
271static int do_test(struct test_case *tc)
272{
Garrett Cooperd74fde62010-11-22 15:21:28 -0800273 int sys_ret;
274 int sys_errno;
275 int result = RESULT_OK;
276 struct timespec beftp, afttp, rq, rm;
277 int rc, range_ok = 1, remain_ok = 1;
278 pid_t pid = 0;
subrata_modak2f3f9562009-05-29 10:35:39 +0000279
Wanlong Gao354ebb42012-12-07 10:10:04 +0800280 /*
Garrett Cooperd74fde62010-11-22 15:21:28 -0800281 * Check before sleep time
282 */
283 if (tc->ttype == SEND_SIGINT) {
284 pid = create_sig_proc(500000, SIGINT, UINT_MAX);
285 if (pid < 0)
286 return 1;
287 }
subrata_modak2f3f9562009-05-29 10:35:39 +0000288
Garrett Cooperd74fde62010-11-22 15:21:28 -0800289 /*
290 * Check before sleep time
291 */
292 TEST(rc = clock_gettime(tc->clk_id, &beftp));
293 if (rc < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800294 tst_resm(TFAIL | TTERRNO, "iclock_gettime failed");
Garrett Cooperd74fde62010-11-22 15:21:28 -0800295 result = 1;
296 goto EXIT;
297 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800298 /*
Garrett Cooperd74fde62010-11-22 15:21:28 -0800299 * Execute system call
300 */
301 rq.tv_sec = tc->sec;
302 rq.tv_nsec = tc->nsec;
303 // !!!CAUTION: 'clock_gettime' returns errno itself
304 errno = 0;
305 if (tc->ttype == NULL_POINTER)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800306 TEST(sys_ret =
307 clock_nanosleep(tc->clk_id, tc->flags, NULL, &rm));
Garrett Cooperd74fde62010-11-22 15:21:28 -0800308 else
Wanlong Gao354ebb42012-12-07 10:10:04 +0800309 TEST(sys_ret =
310 clock_nanosleep(tc->clk_id, tc->flags, &rq, &rm));
Garrett Cooperd74fde62010-11-22 15:21:28 -0800311 sys_errno = errno;
312 if (sys_ret != 0)
313 goto TEST_END;
Garrett Cooper2c282152010-12-16 00:55:50 -0800314
Wanlong Gao354ebb42012-12-07 10:10:04 +0800315 /*
Garrett Cooperd74fde62010-11-22 15:21:28 -0800316 * Check after sleep time
317 */
318 TEST(rc = clock_gettime(tc->clk_id, &afttp));
319 if (TEST_RETURN < 0) {
320 EPRINTF("clock_gettime failed.\n");
321 result = 1;
322 goto EXIT;
323 }
subrata_modak2f3f9562009-05-29 10:35:39 +0000324 range_ok = chk_difftime(&beftp, &afttp, tc->sec, tc->nsec) == 0;
325 /*
Garrett Cooperd74fde62010-11-22 15:21:28 -0800326 * Check remaining time
327 */
subrata_modak2f3f9562009-05-29 10:35:39 +0000328TEST_END:
Garrett Cooperd74fde62010-11-22 15:21:28 -0800329 if (tc->ttype == NORMAL || tc->ttype == SEND_SIGINT) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800330 tst_resm(TINFO, "remain time: %ld %ld", rm.tv_sec, rm.tv_nsec);
Garrett Cooperd74fde62010-11-22 15:21:28 -0800331 if (tc->ttype == NORMAL)
332 remain_ok = 1;
333 else
334 remain_ok = rm.tv_sec != 0 || rm.tv_nsec != 0;
335 }
subrata_modak2f3f9562009-05-29 10:35:39 +0000336
337 /*
Garrett Cooperd74fde62010-11-22 15:21:28 -0800338 * Check results
339 */
340 result |= (sys_ret != tc->ret) || !range_ok || !remain_ok;
341 if (!range_ok)
342 PRINT_RESULT_EXTRA(0, tc->ret, tc->err, sys_ret, sys_errno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800343 "time range check", range_ok);
Garrett Cooperd74fde62010-11-22 15:21:28 -0800344 else
345 PRINT_RESULT_EXTRA(0, tc->ret, tc->err, sys_ret, sys_errno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800346 "remain time check", remain_ok);
subrata_modak2f3f9562009-05-29 10:35:39 +0000347EXIT:
Garrett Cooperd74fde62010-11-22 15:21:28 -0800348 if (pid > 0) {
349 int st;
350 TEST(kill(pid, SIGTERM));
351 TEST(wait(&st));
352 }
353 return result;
subrata_modak2f3f9562009-05-29 10:35:39 +0000354}
355
subrata_modak2f3f9562009-05-29 10:35:39 +0000356/*
357 * main()
358 */
359
Wanlong Gao354ebb42012-12-07 10:10:04 +0800360int main(int ac, char **av)
361{
subrata_modak2f3f9562009-05-29 10:35:39 +0000362 int result = RESULT_OK;
Garrett Cooperd74fde62010-11-22 15:21:28 -0800363 int i;
Garrett Coopera9e49f12010-12-16 10:54:03 -0800364 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200365 const char *msg;
subrata_modak2f3f9562009-05-29 10:35:39 +0000366
Garrett Cooperd74fde62010-11-22 15:21:28 -0800367 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
368 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modak2f3f9562009-05-29 10:35:39 +0000369
Garrett Cooperd74fde62010-11-22 15:21:28 -0800370 setup();
subrata_modak2f3f9562009-05-29 10:35:39 +0000371
Garrett Cooperd74fde62010-11-22 15:21:28 -0800372 for (lc = 0; TEST_LOOPING(lc); ++lc) {
subrata_modak2f3f9562009-05-29 10:35:39 +0000373
Caspar Zhangd59a6592013-03-07 14:59:12 +0800374 tst_count = 0;
subrata_modak2f3f9562009-05-29 10:35:39 +0000375
Garrett Cooperd74fde62010-11-22 15:21:28 -0800376 for (testno = 0; testno < TST_TOTAL; ++testno) {
subrata_modak2f3f9562009-05-29 10:35:39 +0000377
Wanlong Gao354ebb42012-12-07 10:10:04 +0800378 for (i = 0; i < (int)(sizeof(tcase) / sizeof(tcase[0]));
379 i++) {
Garrett Cooperd74fde62010-11-22 15:21:28 -0800380 int ret;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800381 tst_resm(TINFO, "(case%02d) START", i);
Garrett Cooperd74fde62010-11-22 15:21:28 -0800382 ret = do_test(&tcase[i]);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800383 tst_resm(TINFO, "(case%02d) END => %s",
384 i, (ret == 0) ? "OK" : "NG");
Garrett Cooperd74fde62010-11-22 15:21:28 -0800385 result |= ret;
386 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800387
Garrett Cooperd74fde62010-11-22 15:21:28 -0800388 switch (result) {
389 case RESULT_OK:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800390 tst_resm(TPASS,
391 "clock_nanosleep call succeeded");
Garrett Cooperd74fde62010-11-22 15:21:28 -0800392 break;
subrata_modak2f3f9562009-05-29 10:35:39 +0000393
Garrett Cooperd74fde62010-11-22 15:21:28 -0800394 default:
Wanlong Gao354ebb42012-12-07 10:10:04 +0800395 tst_brkm(TFAIL | TERRNO, cleanup,
396 "clock_nanosleep failed");
Garrett Cooperd74fde62010-11-22 15:21:28 -0800397 break;
398 }
subrata_modak2f3f9562009-05-29 10:35:39 +0000399
Garrett Cooperd74fde62010-11-22 15:21:28 -0800400 }
401
402 }
403
404 cleanup();
subrata_modak2f3f9562009-05-29 10:35:39 +0000405 tst_exit();
subrata_modak2f3f9562009-05-29 10:35:39 +0000406
Chris Dearmanec6edca2012-10-17 19:54:01 -0700407}