1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <utime.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <fcntl.h>
37
38 #define ST_ATIME 0
39 #define ST_CTIME 1
40 #define ST_MTIME 2
41
42 #define ALL_MODE (mode_t)(S_IRWXU|S_IRWXG|S_IRWXO)
43
44 typedef struct timetest {
45 int type;
46 char *name;
47 int (*func)(const char *pfile);
48 } timetest_t;
49
50 #ifdef __stc_assertion__
51
52 /*
53 * ID: ctime_001_pos
54 *
55 * DESCRIPTION:
56 * Verify time will be changed correctly according to relevant operating.
57 *
58 * STRATEGY:
59 * 1. Define time test array.
60 * 2. loop each item in this array.
61 * 3. Verify the time will be changed after relevant operating.
62 *
63 * TESTABILITY: explicit
64 *
65 * TEST_AUTOMATION_LEVEL: automated
66 *
67 * CODING_STATUS: COMPLETED (2007-01-30)
68 *
69 */
70
71 #endif /* __stc_assertion__ */
72
73 /*
74 * Get file specific time information.
75 */
76 int get_file_time(char *pfile, int what, time_t *ptr);
77
78 int do_read(const char *pfile);
79 int do_write(const char *pfile);
80 int do_link(const char *pfile);
81 int do_creat(const char *pfile);
82 int do_utime(const char *pfile);
83 int do_chmod(const char *pfile);
84 int do_chown(const char *pfile);
85
86 static char tfile[BUFSIZ] = { 0 };
87 static char msg[BUFSIZ] = { 0 };
88
89 static timetest_t timetest_table[] = {
90 { ST_ATIME, "st_atime", do_read },
91 { ST_ATIME, "st_atime", do_utime },
92 { ST_MTIME, "st_mtime", do_creat },
93 { ST_MTIME, "st_mtime", do_write },
94 { ST_MTIME, "st_mtime", do_utime },
95 { ST_CTIME, "st_ctime", do_creat },
96 { ST_CTIME, "st_ctime", do_write },
97 { ST_CTIME, "st_ctime", do_chmod },
98 { ST_CTIME, "st_ctime", do_chown },
99 { ST_CTIME, "st_ctime", do_link },
100 { ST_CTIME, "st_ctime", do_utime },
101 };
102
103 #define NCOMMAND (sizeof (timetest_table) / sizeof (timetest_table[0]))
104
105 int
main(int argc,char * argv[])106 main(int argc, char *argv[])
107 {
108 int i, ret, fd;
109 const char *env_names[2] = {"TESTDIR", "TESTFILE"};
110 char *env_vals[2];
111
112 /*
113 * Get envirnment variable value
114 */
115 for (i = 0; i < sizeof (env_names) / sizeof (char *); i++) {
116 if ((env_vals[i] = getenv(env_names[i])) == NULL) {
117 fprintf(stderr, "getenv(%s) returned NULL\n",
118 env_names[i]);
119 exit(1);
120 }
121 }
122 (void) snprintf(tfile, sizeof (tfile), "%s/%s", env_vals[0],
123 env_vals[1]);
124
125 /*
126 * If the test file is existing, remove it firstly
127 */
128 if (access(tfile, F_OK) == 0) {
129 unlink(tfile);
130 }
131 fd = open(tfile, O_WRONLY | O_CREAT | O_TRUNC, ALL_MODE);
132 if (fd < 0) {
133 perror("open");
134 exit(1);
135 }
136 (void) close(fd);
137
138 for (i = 0; i < NCOMMAND; i++) {
139 time_t t1, t2;
140
141 /*
142 * Get original time before operating.
143 */
144 ret = get_file_time(tfile, timetest_table[i].type, &t1);
145 if (ret != 0) {
146 fprintf(stderr,
147 "ERROR: get_file_time(%s, %d, &t1) returned %d\n",
148 tfile, timetest_table[i].type, ret);
149 exit(1);
150 }
151
152 /*
153 * Sleep 2 seconds to be sure that the timeofday has changed,
154 * then invoke command on given file
155 */
156 sleep(2);
157 timetest_table[i].func(tfile);
158
159 /*
160 * Get time after operating.
161 */
162 ret = get_file_time(tfile, timetest_table[i].type, &t2);
163 if (ret != 0) {
164 fprintf(stderr, "get_file_time(%s, %d, &t2)\n",
165 tfile, timetest_table[i].type);
166 exit(1);
167 }
168
169 if (t1 == t2) {
170 fprintf(stderr, "%s: t1(%ld) == t2(%ld)\n",
171 timetest_table[i].name, (long)t1, (long)t2);
172 exit(1);
173 }
174 }
175
176 (void) unlink(tfile);
177
178 return (0);
179 }
180
181 int
get_file_time(char * pfile,int what,time_t * ptr)182 get_file_time(char *pfile, int what, time_t *ptr)
183 {
184 struct stat stat_buf;
185
186 if (pfile == NULL || ptr == NULL) {
187 return (-1);
188 }
189
190 if (stat(pfile, &stat_buf) == -1) {
191 return (-1);
192 }
193
194 switch (what) {
195 case ST_ATIME:
196 *ptr = stat_buf.st_atime;
197 return (0);
198 case ST_CTIME:
199 *ptr = stat_buf.st_ctime;
200 return (0);
201 case ST_MTIME:
202 *ptr = stat_buf.st_mtime;
203 return (0);
204 default:
205 return (-1);
206 }
207 }
208
209 int
do_read(const char * pfile)210 do_read(const char *pfile)
211 {
212 int fd, ret = 0;
213 char buf[BUFSIZ] = { 0 };
214
215 if (pfile == NULL) {
216 return (-1);
217 }
218
219 if ((fd = open(pfile, O_RDONLY, ALL_MODE)) == -1) {
220 return (-1);
221 }
222 if (read(fd, buf, sizeof (buf)) == -1) {
223 ret = errno;
224 }
225 (void) close(fd);
226
227 if (ret != 0) {
228 fprintf(stderr, "read(%d, buf, %zu)\n", fd, sizeof (buf));
229 exit(1);
230 }
231
232 return (ret);
233 }
234
235 int
do_write(const char * pfile)236 do_write(const char *pfile)
237 {
238 int fd, ret = 0;
239 char buf[BUFSIZ] = "call function do_write()";
240
241 if (pfile == NULL) {
242 return (-1);
243 }
244
245 if ((fd = open(pfile, O_WRONLY, ALL_MODE)) == -1) {
246 return (-1);
247 }
248 if (write(fd, buf, strlen(buf)) == -1) {
249 ret = errno;
250 }
251 (void) close(fd);
252
253 if (ret != 0) {
254 fprintf(stderr, "write(%d, buf, %zu)\n", fd, strlen(buf));
255 exit(1);
256 }
257
258 return (ret);
259 }
260
261 int
do_link(const char * pfile)262 do_link(const char *pfile)
263 {
264 int ret = 0;
265 char link_file[BUFSIZ] = { 0 };
266 char *ptr = link_file;
267
268 if (pfile == NULL) {
269 return (-1);
270 }
271
272 /*
273 * Figure out source file directory name, and create
274 * the link file in the same directory.
275 */
276 snprintf(link_file, sizeof (link_file), "%s", pfile);
277 ptr = strrchr(link_file, '/');
278 snprintf(ptr + 1,
279 sizeof (link_file) - (ptr + 1 - link_file), "link_file");
280
281 if (link(pfile, link_file) == -1) {
282 ret = errno;
283 }
284 if (ret != 0) {
285 fprintf(stderr, "link(%s, %s)\n", pfile, link_file);
286 exit(1);
287 }
288
289 unlink(link_file);
290 return (ret);
291 }
292
293 int
do_creat(const char * pfile)294 do_creat(const char *pfile)
295 {
296 int fd, ret = 0;
297
298 if (pfile == NULL) {
299 return (-1);
300 }
301
302 if ((fd = creat(pfile, ALL_MODE)) == -1) {
303 ret = errno;
304 }
305 if (fd != -1) {
306 (void) close(fd);
307 }
308
309 if (ret != 0) {
310 fprintf(stderr, "creat(%s, ALL_MODE)\n", pfile);
311 exit(1);
312 }
313
314 return (ret);
315 }
316
317 int
do_utime(const char * pfile)318 do_utime(const char *pfile)
319 {
320 int ret = 0;
321
322 if (pfile == NULL) {
323 return (-1);
324 }
325
326 /*
327 * Times of the file are set to the current time
328 */
329 if (utime(pfile, NULL) == -1) {
330 ret = errno;
331 }
332 if (ret != 0) {
333 fprintf(stderr, "utime(%s, NULL)\n", pfile);
334 exit(1);
335 }
336
337 return (ret);
338 }
339
340 int
do_chmod(const char * pfile)341 do_chmod(const char *pfile)
342 {
343 int ret = 0;
344
345 if (pfile == NULL) {
346 return (-1);
347 }
348
349 if (chmod(pfile, ALL_MODE) == -1) {
350 ret = errno;
351 }
352 if (ret != 0) {
353 fprintf(stderr, "chmod(%s, ALL_MODE)\n", pfile);
354 exit(1);
355 }
356
357 return (ret);
358 }
359
360 int
do_chown(const char * pfile)361 do_chown(const char *pfile)
362 {
363 int ret = 0;
364
365 if (pfile == NULL) {
366 return (-1);
367 }
368
369 if (chown(pfile, getuid(), getgid()) == -1) {
370 ret = errno;
371 }
372 if (ret != 0) {
373 fprintf(stderr, "chown(%s, %d, %d)\n", pfile, (int)getuid(),
374 (int)getgid());
375 exit(1);
376 }
377
378 return (ret);
379 }
380