blob: b15da331e7fdf45a68b63943f700d63ceb9aece3 [file] [log] [blame]
subrata_modak705ba462009-05-29 12:21:34 +00001/******************************************************************************/
Garrett Cooper045b2222010-11-22 15:34:12 -08002/* Copyright (c) Crackerjack Project., 2007 ,Hitachi, Ltd */
3/* Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, */
4/* */
subrata_modak705ba462009-05-29 12:21:34 +00005/* 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 */
Garrett Cooper045b2222010-11-22 15:34:12 -08007/* 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 */
Garrett Cooper045b2222010-11-22 15:34:12 -080018/* */
subrata_modak705ba462009-05-29 12:21:34 +000019/******************************************************************************/
20/******************************************************************************/
Garrett Cooper045b2222010-11-22 15:34:12 -080021/* */
22/* File: utimes01.c */
23/* */
24/* Description: This tests the utimes() syscall */
subrata_modak705ba462009-05-29 12:21:34 +000025/* */
26/* */
27/* */
28/* */
29/* */
Garrett Cooper045b2222010-11-22 15:34:12 -080030/* */
31/* Usage: <for command-line> */
32/* utimes01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
33/* where, -c n : Run n copies concurrently. */
34/* -e : Turn on errno logging. */
35/* -i n : Execute test n times. */
36/* -I x : Execute test for x seconds. */
37/* -P x : Pause for x seconds between iterations. */
38/* -t : Turn on syscall timing. */
39/* */
40/* Total Tests: 1 */
41/* */
42/* Test Name: utimes01 */
43/* History: Porting from Crackerjack to LTP is done by */
44/* Manas Kumar Nayak maknayak@in.ibm.com> */
subrata_modak705ba462009-05-29 12:21:34 +000045/******************************************************************************/
46#include <sys/types.h>
47#include <sys/stat.h>
48#include <sys/time.h>
49#include <dirent.h>
50#include <unistd.h>
51#include <getopt.h>
52#include <string.h>
53#include <stdlib.h>
54#include <errno.h>
55#include <stdio.h>
subrata_modak705ba462009-05-29 12:21:34 +000056
57#include "../utils/include_j_h.h"
58#include "../utils/common_j_h.c"
59
subrata_modak705ba462009-05-29 12:21:34 +000060#include "test.h"
61#include "usctest.h"
62#include "linux_syscall_numbers.h"
63
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020064char *TCID = "utimes01";
Wanlong Gao354ebb42012-12-07 10:10:04 +080065int testno;
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020066int TST_TOTAL = 1;
subrata_modak705ba462009-05-29 12:21:34 +000067
68/* Extern Global Functions */
69/******************************************************************************/
Garrett Cooper045b2222010-11-22 15:34:12 -080070/* */
71/* Function: cleanup */
72/* */
subrata_modak705ba462009-05-29 12:21:34 +000073/* Description: Performs all one time clean up for this test on successful */
Garrett Cooper045b2222010-11-22 15:34:12 -080074/* completion, premature exit or failure. Closes all temporary */
75/* files, removes all temporary directories exits the test with */
76/* appropriate return code by calling tst_exit() function. */
77/* */
78/* Input: None. */
79/* */
80/* Output: None. */
81/* */
subrata_modak705ba462009-05-29 12:21:34 +000082/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */
Garrett Cooper045b2222010-11-22 15:34:12 -080083/* On success - Exits calling tst_exit(). With '0' return code. */
84/* */
subrata_modak705ba462009-05-29 12:21:34 +000085/******************************************************************************/
Wanlong Gao354ebb42012-12-07 10:10:04 +080086extern void cleanup()
87{
Garrett Cooper2c282152010-12-16 00:55:50 -080088
Garrett Cooper045b2222010-11-22 15:34:12 -080089 TEST_CLEANUP;
90 tst_rmdir();
subrata_modak705ba462009-05-29 12:21:34 +000091
subrata_modak705ba462009-05-29 12:21:34 +000092}
93
94/* Local Functions */
95/******************************************************************************/
Garrett Cooper045b2222010-11-22 15:34:12 -080096/* */
97/* Function: setup */
98/* */
subrata_modak705ba462009-05-29 12:21:34 +000099/* Description: Performs all one time setup for this test. This function is */
Garrett Cooper045b2222010-11-22 15:34:12 -0800100/* typically used to capture signals, create temporary dirs */
101/* and temporary files that may be used in the course of this */
102/* test. */
103/* */
104/* Input: None. */
105/* */
106/* Output: None. */
107/* */
108/* Return: On failure - Exits by calling cleanup(). */
109/* On success - returns 0. */
110/* */
subrata_modak705ba462009-05-29 12:21:34 +0000111/******************************************************************************/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800112void setup()
113{
Garrett Cooperf7af1ec2010-12-18 09:04:37 -0800114 tst_require_root(NULL);
subrata_modakbc924982009-09-27 17:35:51 +0000115
Garrett Cooper045b2222010-11-22 15:34:12 -0800116 /* Capture signals if any */
117 /* Create temporary directories */
118 TEST_PAUSE;
119 tst_tmpdir();
subrata_modak705ba462009-05-29 12:21:34 +0000120}
121
subrata_modak705ba462009-05-29 12:21:34 +0000122/*
123 * Macros
124 */
125#define SYSCALL_NAME "utimes"
126
subrata_modak705ba462009-05-29 12:21:34 +0000127enum test_type {
Garrett Cooper045b2222010-11-22 15:34:12 -0800128 NORMAL,
129 FILE_NOT_EXIST,
130 NO_FNAME,
subrata_modak705ba462009-05-29 12:21:34 +0000131};
132
subrata_modak705ba462009-05-29 12:21:34 +0000133/*
134 * Data Structure
135 */
136struct test_case {
137 int ttype;
Garrett Cooper045b2222010-11-22 15:34:12 -0800138 long a_sec;
139 long m_sec;
140 char *user;
141 int ret;
142 int err;
subrata_modak705ba462009-05-29 12:21:34 +0000143
144};
145
subrata_modak705ba462009-05-29 12:21:34 +0000146/* Test cases
147 *
148 * test status of errors on man page
149 *
Garrett Cooper045b2222010-11-22 15:34:12 -0800150 * EACCES v (permission denied)
151 * ENOENT v (file does not exist)
subrata_modak705ba462009-05-29 12:21:34 +0000152 *
153 * test status of errors on man page
154 *
Garrett Cooper045b2222010-11-22 15:34:12 -0800155 * EFAULT v (points to not process address space)
subrata_modak705ba462009-05-29 12:21:34 +0000156 */
157
158static struct test_case tcase[] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800159 { // case00
160 .ttype = NORMAL,
161 .a_sec = 0,
162 .m_sec = 1000,
163 .ret = 0,
164 .err = 0,
165 },
166 { // case01
167 .ttype = NORMAL,
168 .a_sec = 1000,
169 .m_sec = 0,
170 .ret = 0,
171 .err = 0,
172 },
173 { // case02
174 .ttype = NORMAL,
175 .user = "nobody",
176 .ret = -1,
177 .err = EACCES, // RHEL4U1 + 2.6.18 returns EPERM
178 },
179 { // case03
180 .ttype = FILE_NOT_EXIST,
181 .a_sec = 1000,
182 .m_sec = 2000,
183 .ret = -1,
184 .err = ENOENT,
185 },
subrata_modak705ba462009-05-29 12:21:34 +0000186
Wanlong Gao354ebb42012-12-07 10:10:04 +0800187 { // case04
188 .ttype = NO_FNAME,
189 .a_sec = 1000,
190 .m_sec = 2000,
191 .ret = -1,
192 .err = EFAULT,
193 },
subrata_modak705ba462009-05-29 12:21:34 +0000194};
195
196/*
197 * do_test()
198 *
199 * Input : TestCase Data
200 * Return : RESULT_OK(0), RESULT_NG(1)
201 *
202 */
203
204static int do_test(struct test_case *tc)
205{
Garrett Cooper045b2222010-11-22 15:34:12 -0800206 int sys_ret;
207 int sys_errno;
208 int result = RESULT_OK;
subrata_modak705ba462009-05-29 12:21:34 +0000209 struct timeval tv[2];
Garrett Cooper045b2222010-11-22 15:34:12 -0800210 char fpath[PATH_MAX], c = '\0';
211 int rc, len, cmp_ok = 1;
212 struct stat st;
213 uid_t old_uid;
subrata_modak705ba462009-05-29 12:21:34 +0000214
Garrett Cooperf7af1ec2010-12-18 09:04:37 -0800215 /* XXX (garrcoop): memory leak with get_tst_tmpdir. */
216 TEST(rc = setup_file(get_tst_tmpdir(), "test.file", fpath));
Garrett Cooper045b2222010-11-22 15:34:12 -0800217 if (rc < 0)
218 return 1;
Subrata Modak76a720a2010-07-03 21:08:18 +0530219 /* The test just needs the file, so no need to keep it open. */
220 close(rc);
subrata_modak705ba462009-05-29 12:21:34 +0000221
222 /*
Garrett Cooper045b2222010-11-22 15:34:12 -0800223 * Change effective user id
224 */
225 if (tc->user != NULL) {
226 TEST(rc = setup_euid(tc->user, &old_uid));
227 if (rc < 0)
228 goto EXIT2;
229 }
subrata_modak705ba462009-05-29 12:21:34 +0000230
231 /*
Garrett Cooper045b2222010-11-22 15:34:12 -0800232 * Execute system call
233 */
234 memset(tv, 0, 2 * sizeof(struct timeval));
235 tv[0].tv_sec = tc->a_sec;
236 tv[1].tv_sec = tc->m_sec;
237 TEST(len = strlen(fpath));
238 if (tc->ttype == FILE_NOT_EXIST) {
239 c = fpath[len - 1];
240 fpath[len - 1] = '\0';
241 }
242 errno = 0;
243 if (tc->ttype == NO_FNAME) {
244 /**
245 * Note (garrcoop):
246 *
247 * If you do NULL directly, then gcc [4.3] will complain when
248 * one specifies -Wnonnull in CPPFLAGS. This is a negative
249 * test, but let's not allow the compiler to complain about
250 * something trivial like this.
251 **/
252 const char *dummy = NULL;
253 TEST(sys_ret = utimes(dummy, tv));
Wanlong Gao354ebb42012-12-07 10:10:04 +0800254 } else {
Garrett Cooper045b2222010-11-22 15:34:12 -0800255 if (tc->user == NULL)
256 TEST(sys_ret = utimes(fpath, tv));
257 else
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800258 TEST(sys_ret = utimes(fpath, NULL));
Garrett Cooper045b2222010-11-22 15:34:12 -0800259 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800260 tv[0].tv_sec = tc->a_sec;
261 tv[1].tv_sec = tc->m_sec;
262 TEST(len = strlen(fpath));
263 if (tc->ttype == FILE_NOT_EXIST) {
264 c = fpath[len - 1];
265 fpath[len - 1] = '\0';
266 }
267 errno = 0;
268 if (tc->ttype == NO_FNAME) {
269 /**
subrata_modak705ba462009-05-29 12:21:34 +0000270 * Note (garrcoop):
271 *
272 * If you do NULL directly, then gcc [4.3] will complain when
273 * one specifies -Wnonnull in CPPFLAGS. This is a negative
274 * test, but let's not allow the compiler to complain about
275 * something trivial like this.
276 **/
Wanlong Gao354ebb42012-12-07 10:10:04 +0800277 const char *dummy = NULL;
278 TEST(sys_ret = utimes(dummy, tv));
279 } else {
280 if (tc->user == NULL)
281 TEST(sys_ret = utimes(fpath, tv));
282 else
283 TEST(sys_ret = utimes(fpath, NULL));
284 }
Garrett Cooper045b2222010-11-22 15:34:12 -0800285 sys_errno = errno;
286 if (tc->ttype == FILE_NOT_EXIST)
287 fpath[len - 1] = c;
288 if (sys_ret < 0)
289 goto TEST_END;
subrata_modak705ba462009-05-29 12:21:34 +0000290
Garrett Cooper045b2222010-11-22 15:34:12 -0800291 /*
292 * Check test file's time stamp
293 */
294 rc = stat(fpath, &st);
295 if (rc < 0) {
296 EPRINTF("stat failed.\n");
297 result = 1;
298 goto EXIT1;
299 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800300 tst_resm(TINFO, "E:%ld,%ld <=> R:%ld,%ld", tv[0].tv_sec, tv[1].tv_sec,
301 st.st_atime, st.st_mtime);
Garrett Cooper045b2222010-11-22 15:34:12 -0800302 cmp_ok = st.st_atime == tv[0].tv_sec && st.st_mtime == tv[1].tv_sec;
303
304 /*
305 * Check results
306 */
subrata_modak705ba462009-05-29 12:21:34 +0000307TEST_END:
Garrett Cooper045b2222010-11-22 15:34:12 -0800308 result |= (sys_errno != tc->err) || !cmp_ok;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800309 PRINT_RESULT_CMP(sys_ret >= 0, tc->ret, tc->err, sys_ret, sys_errno,
310 cmp_ok);
subrata_modak705ba462009-05-29 12:21:34 +0000311
Garrett Cooper045b2222010-11-22 15:34:12 -0800312 /*
313 * Restore effective user id
314 */
subrata_modak705ba462009-05-29 12:21:34 +0000315EXIT1:
Garrett Cooper045b2222010-11-22 15:34:12 -0800316 if (tc->user != NULL) {
317 TEST(rc = cleanup_euid(old_uid));
318 if (rc < 0)
319 return 1;
320 }
subrata_modak705ba462009-05-29 12:21:34 +0000321EXIT2:
Garrett Cooper045b2222010-11-22 15:34:12 -0800322 TEST(cleanup_file(fpath));
subrata_modak705ba462009-05-29 12:21:34 +0000323
Garrett Cooper045b2222010-11-22 15:34:12 -0800324 return result;
subrata_modak705ba462009-05-29 12:21:34 +0000325}
326
327/*
subrata_modak705ba462009-05-29 12:21:34 +0000328 * main()
329 */
330
Wanlong Gao354ebb42012-12-07 10:10:04 +0800331int main(int ac, char **av)
332{
subrata_modak705ba462009-05-29 12:21:34 +0000333 int result = RESULT_OK;
Garrett Cooper045b2222010-11-22 15:34:12 -0800334 int i;
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200335 int lc;
336 char *msg;
subrata_modak705ba462009-05-29 12:21:34 +0000337
Garrett Cooper045b2222010-11-22 15:34:12 -0800338 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800339 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modak705ba462009-05-29 12:21:34 +0000340
Garrett Cooper045b2222010-11-22 15:34:12 -0800341 setup();
subrata_modak705ba462009-05-29 12:21:34 +0000342
Garrett Cooper045b2222010-11-22 15:34:12 -0800343 for (lc = 0; TEST_LOOPING(lc); ++lc) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800344 tst_count = 0;
Garrett Cooper045b2222010-11-22 15:34:12 -0800345 for (testno = 0; testno < TST_TOTAL; ++testno) {
subrata_modak705ba462009-05-29 12:21:34 +0000346
Wanlong Gao354ebb42012-12-07 10:10:04 +0800347 for (i = 0; i < (int)(sizeof(tcase) / sizeof(tcase[0]));
348 i++) {
Garrett Cooper045b2222010-11-22 15:34:12 -0800349 int ret;
350 tst_resm(TINFO, "(case%02d) START", i);
351 ret = do_test(&tcase[i]);
352 tst_resm(TINFO, "(case%02d) END => %s",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800353 i, (ret == 0) ? "OK" : "NG");
Garrett Cooper045b2222010-11-22 15:34:12 -0800354 result |= ret;
355 }
subrata_modak705ba462009-05-29 12:21:34 +0000356
Wanlong Gao354ebb42012-12-07 10:10:04 +0800357 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800358 }
Garrett Cooper045b2222010-11-22 15:34:12 -0800359 cleanup();
subrata_modak705ba462009-05-29 12:21:34 +0000360 tst_exit();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700361}