dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / test / zfs-tests / tests / functional / ctime / ctime_001_pos.c
bloba6e02fbea3537a9805ae4f59486c443ea4fb2db4
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 2013 by Delphix. All rights reserved.
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <utime.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <strings.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <libgen.h>
43 #define ST_ATIME 0
44 #define ST_CTIME 1
45 #define ST_MTIME 2
47 #define ALL_MODE (mode_t)(S_IRWXU|S_IRWXG|S_IRWXO)
49 typedef struct timetest {
50 int type;
51 char *name;
52 int (*func)(const char *pfile);
53 } timetest_t;
55 static char tfile[BUFSIZ] = { 0 };
57 extern int errno;
60 * DESCRIPTION:
61 * Verify time will be changed correctly after each operation.
63 * STRATEGY:
64 * 1. Define time test array.
65 * 2. Loop through each item in this array.
66 * 3. Verify the time is changed after each operation.
70 static int
71 get_file_time(const char *pfile, int what, time_t *ptr)
73 struct stat stat_buf;
75 if (pfile == NULL || ptr == NULL) {
76 return (-1);
79 if (stat(pfile, &stat_buf) == -1) {
80 return (-1);
83 switch (what) {
84 case ST_ATIME:
85 *ptr = stat_buf.st_atime;
86 return (0);
87 case ST_CTIME:
88 *ptr = stat_buf.st_ctime;
89 return (0);
90 case ST_MTIME:
91 *ptr = stat_buf.st_mtime;
92 return (0);
93 default:
94 return (-1);
98 static int
99 do_read(const char *pfile)
101 int fd, ret = 0;
102 char buf[BUFSIZ] = { 0 };
104 if (pfile == NULL) {
105 return (-1);
108 if ((fd = open(pfile, O_RDONLY, ALL_MODE)) == -1) {
109 return (-1);
111 if (read(fd, buf, sizeof (buf)) == -1) {
112 (void) fprintf(stderr, "read(%d, buf, %d) failed with errno "
113 "%d\n", fd, sizeof (buf), errno);
114 return (1);
116 (void) close(fd);
118 return (ret);
121 static int
122 do_write(const char *pfile)
124 int fd, ret = 0;
125 char buf[BUFSIZ] = "call function do_write()";
127 if (pfile == NULL) {
128 return (-1);
131 if ((fd = open(pfile, O_WRONLY, ALL_MODE)) == -1) {
132 return (-1);
134 if (write(fd, buf, strlen(buf)) == -1) {
135 (void) fprintf(stderr, "write(%d, buf, %d) failed with errno "
136 "%d\n", fd, strlen(buf), errno);
137 return (1);
139 (void) close(fd);
141 return (ret);
144 static int
145 do_link(const char *pfile)
147 int ret = 0;
148 char link_file[BUFSIZ] = { 0 };
149 char *dname;
151 if (pfile == NULL) {
152 return (-1);
156 * Figure out source file directory name, and create
157 * the link file in the same directory.
159 dname = dirname(strdup(pfile));
160 (void) snprintf(link_file, BUFSIZ, "%s/%s", dname, "link_file");
162 if (link(pfile, link_file) == -1) {
163 (void) fprintf(stderr, "link(%s, %s) failed with errno %d\n",
164 pfile, link_file, errno);
165 free((void *)dirname);
166 return (1);
169 (void) unlink(link_file);
170 free((void *)dirname);
171 return (ret);
174 static int
175 do_creat(const char *pfile)
177 int fd, ret = 0;
179 if (pfile == NULL) {
180 return (-1);
183 if ((fd = creat(pfile, ALL_MODE)) == -1) {
184 (void) fprintf(stderr, "creat(%s, ALL_MODE) failed with errno "
185 "%d\n", pfile, errno);
186 return (1);
188 (void) close(fd);
190 return (ret);
193 static int
194 do_utime(const char *pfile)
196 int ret = 0;
198 if (pfile == NULL) {
199 return (-1);
203 * Times of the file are set to the current time
205 if (utime(pfile, NULL) == -1) {
206 (void) fprintf(stderr, "utime(%s, NULL) failed with errno "
207 "%d\n", pfile, errno);
208 return (1);
211 return (ret);
214 static int
215 do_chmod(const char *pfile)
217 int ret = 0;
219 if (pfile == NULL) {
220 return (-1);
223 if (chmod(pfile, ALL_MODE) == -1) {
224 (void) fprintf(stderr, "chmod(%s, ALL_MODE) failed with "
225 "errno %d\n", pfile, errno);
226 return (1);
229 return (ret);
232 static int
233 do_chown(const char *pfile)
235 int ret = 0;
237 if (pfile == NULL) {
238 return (-1);
241 if (chown(pfile, getuid(), getgid()) == -1) {
242 (void) fprintf(stderr, "chown(%s, %d, %d) failed with errno "
243 "%d\n", pfile, (int)getuid(), (int)getgid(), errno);
244 return (1);
247 return (ret);
250 static void
251 cleanup(void)
253 if ((strlen(tfile) != 0) && (access(tfile, F_OK) == 0)) {
254 (void) unlink(tfile);
258 static timetest_t timetest_table[] = {
259 { ST_ATIME, "st_atime", do_read },
260 { ST_ATIME, "st_atime", do_utime },
261 { ST_MTIME, "st_mtime", do_creat },
262 { ST_MTIME, "st_mtime", do_write },
263 { ST_MTIME, "st_mtime", do_utime },
264 { ST_CTIME, "st_ctime", do_creat },
265 { ST_CTIME, "st_ctime", do_write },
266 { ST_CTIME, "st_ctime", do_chmod },
267 { ST_CTIME, "st_ctime", do_chown },
268 { ST_CTIME, "st_ctime", do_link },
269 { ST_CTIME, "st_ctime", do_utime },
272 #define NCOMMAND (sizeof (timetest_table) / sizeof (timetest_table[0]))
274 /* ARGSUSED */
276 main(int argc, char *argv[])
278 int i, ret, fd;
279 char *penv[] = {"TESTDIR", "TESTFILE0"};
281 (void) fprintf(stdout, "Verify [acm]time is modified appropriately.\n");
282 (void) atexit(cleanup);
285 * Get the environment variable values.
287 for (i = 0; i < sizeof (penv) / sizeof (char *); i++) {
288 if ((penv[i] = getenv(penv[i])) == NULL) {
289 (void) fprintf(stderr, "getenv(penv[%d])\n", i);
290 return (1);
293 (void) snprintf(tfile, sizeof (tfile), "%s/%s", penv[0], penv[1]);
296 * If the test file is exists, remove it first.
298 if (access(tfile, F_OK) == 0) {
299 (void) unlink(tfile);
301 ret = 0;
302 if ((fd = open(tfile, O_WRONLY | O_CREAT | O_TRUNC, ALL_MODE)) == -1) {
303 (void) fprintf(stderr, "open(%s) failed: %d\n", tfile, errno);
304 return (1);
306 (void) close(fd);
308 for (i = 0; i < NCOMMAND; i++) {
309 time_t t1, t2;
312 * Get original time before operating.
314 ret = get_file_time(tfile, timetest_table[i].type, &t1);
315 if (ret != 0) {
316 (void) fprintf(stderr, "get_file_time(%s %d) = %d\n",
317 tfile, timetest_table[i].type, ret);
318 return (1);
322 * Sleep 2 seconds, then invoke command on given file
324 (void) sleep(2);
325 timetest_table[i].func(tfile);
328 * Get time after operating.
330 ret = get_file_time(tfile, timetest_table[i].type, &t2);
331 if (ret != 0) {
332 (void) fprintf(stderr, "get_file_time(%s %d) = %d\n",
333 tfile, timetest_table[i].type, ret);
334 return (1);
337 if (t1 == t2) {
338 (void) fprintf(stderr, "%s: t1(%ld) == t2(%ld)\n",
339 timetest_table[i].name, (long)t1, (long)t2);
340 return (1);
341 } else {
342 (void) fprintf(stderr, "%s: t1(%ld) != t2(%ld)\n",
343 timetest_table[i].name, (long)t1, (long)t2);
347 (void) fprintf(stdout, "PASS\n");
348 return (0);