1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
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
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * Test Name: utime01
22 *
23 * Test Description:
24 * Verify that the system call utime() successfully sets the modification
25 * and access times of a file to the current time, if the times argument
26 * is null, and the user ID of the process is "root".
27 *
28 * Expected Result:
29 * utime succeeds returning zero and sets the access and modification
30 * times of the file to the current time.
31 *
32 * Algorithm:
33 * Setup:
34 * Setup signal handling.
35 * Create temporary directory.
36 * Pause for SIGUSR1 if option specified.
37 *
38 * Test:
39 * Loop if the proper options are given.
40 * Execute system call
41 * Check return code, if system call failed (return=-1)
42 * Log the errno and Issue a FAIL message.
43 * Otherwise,
44 * Verify the Functionality of system call
45 * if successful,
46 * Issue Functionality-Pass message.
47 * Otherwise,
48 * Issue Functionality-Fail message.
49 * Cleanup:
50 * Print errno log and/or timing stats if options given
51 * Delete the temporary directory created.
52 *
53 * Usage: <for command-line>
54 * utime01 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
55 * where, -c n : Run n copies concurrently.
56 * -e : Turn on errno logging.
57 * -f : Turn off functionality Testing.
58 * -i n : Execute test n times.
59 * -I x : Execute test for x seconds.
60 * -P x : Pause for x seconds between iterations.
61 * -t : Turn on syscall timing.
62 *
63 * History
64 * 07/2001 John George
65 * -Ported
66 *
67 * Restrictions:
68 * This test should be run by 'super-user' (root) only.
69 *
70 */
71
72 #include <stdio.h>
73 #include <unistd.h>
74 #include <sys/types.h>
75 #include <errno.h>
76 #include <fcntl.h>
77 #include <utime.h>
78 #include <string.h>
79 #include <sys/stat.h>
80 #include <signal.h>
81 #include <time.h>
82
83 #include "test.h"
84 #include "safe_macros.h"
85
86 #define TEMP_FILE "tmp_file"
87 #define FILE_MODE S_IRUSR | S_IRGRP | S_IROTH
88
89 char *TCID = "utime01";
90 int TST_TOTAL = 1;
91 time_t curr_time; /* current time in seconds */
92
93 void setup(); /* Main setup function of test */
94 void cleanup(); /* cleanup function for the test */
95
main(int ac,char ** av)96 int main(int ac, char **av)
97 {
98 struct stat stat_buf; /* struct buffer to hold file info. */
99 int lc;
100 long type;
101 time_t modf_time, access_time;
102 time_t pres_time; /* file modification/access/present time */
103
104 tst_parse_opts(ac, av, NULL, NULL);
105
106 setup();
107
108 switch ((type = tst_fs_type(cleanup, "."))) {
109 case TST_NFS_MAGIC:
110 if (tst_kvercmp(2, 6, 18) < 0)
111 tst_brkm(TCONF, cleanup, "Cannot do utime on a file"
112 " on %s filesystem before 2.6.18",
113 tst_fs_type_name(type));
114 break;
115 case TST_V9FS_MAGIC:
116 tst_brkm(TCONF, cleanup,
117 "Cannot do utime on a file on %s filesystem",
118 tst_fs_type_name(type));
119 break;
120 }
121
122 for (lc = 0; TEST_LOOPING(lc); lc++) {
123
124 tst_count = 0;
125
126 /*
127 * Invoke utime(2) to set TEMP_FILE access and
128 * modification times to the current time.
129 */
130 TEST(utime(TEMP_FILE, NULL));
131
132 if (TEST_RETURN == -1) {
133 tst_resm(TFAIL|TTERRNO, "utime(%s) failed", TEMP_FILE);
134 } else {
135 /*
136 * Sleep for a second so that mod time and
137 * access times will be different from the
138 * current time
139 */
140 sleep(2);
141
142 /*
143 * Get the current time now, after calling
144 * utime(2)
145 */
146 pres_time = time(NULL);
147
148 /*
149 * Get the modification and access times of
150 * temporary file using stat(2).
151 */
152 SAFE_STAT(cleanup, TEMP_FILE, &stat_buf);
153 modf_time = stat_buf.st_mtime;
154 access_time = stat_buf.st_atime;
155
156 /* Now do the actual verification */
157 if (modf_time <= curr_time ||
158 modf_time >= pres_time ||
159 access_time <= curr_time ||
160 access_time >= pres_time) {
161 tst_resm(TFAIL, "%s access and "
162 "modification times not set",
163 TEMP_FILE);
164 } else {
165 tst_resm(TPASS, "Functionality of "
166 "utime(%s, NULL) successful",
167 TEMP_FILE);
168 }
169 }
170 tst_count++;
171 }
172
173 cleanup();
174 tst_exit();
175 }
176
177 /*
178 * void
179 * setup() - performs all ONE TIME setup for this test.
180 * Create a temporary directory and change directory to it.
181 * Create a test file under temporary directory and close it
182 */
setup(void)183 void setup(void)
184 {
185 int fildes; /* file handle for temp file */
186
187 tst_require_root();
188
189 tst_sig(FORK, DEF_HANDLER, cleanup);
190
191 TEST_PAUSE;
192
193 tst_tmpdir();
194
195 /* Creat a temporary file under above directory */
196 fildes = SAFE_CREAT(cleanup, TEMP_FILE, FILE_MODE);
197
198 /* Close the temporary file created */
199 SAFE_CLOSE(cleanup, fildes);
200
201 /* Get the current time */
202 curr_time = time(NULL);
203
204 /*
205 * Sleep for a second so that mod time and access times will be
206 * different from the current time
207 */
208 sleep(2); /* sleep(1) on IA64 sometimes sleeps < 1 sec!! */
209
210 }
211
212 /*
213 * void
214 * cleanup() - performs all ONE TIME cleanup for this test at
215 * completion or premature exit.
216 * Remove the test directory and testfile created in the setup.
217 */
cleanup(void)218 void cleanup(void)
219 {
220
221 tst_rmdir();
222
223 }
224