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