test_option_a.c revision 348608
11590Srgrimes/*-
21590Srgrimes * Copyright (c) 2003-2008 Tim Kientzle
31590Srgrimes * All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes *
141590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
151590Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
161590Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
171590Srgrimes * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
181590Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
191590Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
201590Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
211590Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
221590Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
231590Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
241590Srgrimes */
251590Srgrimes#include "test.h"
261590Srgrimes#if defined(HAVE_UTIME_H)
271590Srgrimes#include <utime.h>
281590Srgrimes#elif defined(HAVE_SYS_UTIME_H)
291590Srgrimes#include <sys/utime.h>
301590Srgrimes#endif
3113236Sgraichen__FBSDID("$FreeBSD: stable/10/contrib/libarchive/cpio/test/test_option_a.c 348608 2019-06-04 10:36:26Z mm $");
3250477Speter
331590Srgrimesstatic struct {
34166651Smpp	const char *name;
351590Srgrimes	time_t atime_sec;
3679535Sru} files[] = {
371590Srgrimes	{ "f0", 0 },
381590Srgrimes	{ "f1", 0 },
391590Srgrimes	{ "f2", 0 },
401590Srgrimes	{ "f3", 0 },
4168963Sru	{ "f4", 0 },
42163599Sru	{ "f5", 0 }
43166646Smpp};
44166651Smpp
4568963Sru/*
46163599Sru * Create a bunch of test files and record their atimes.
47166646Smpp * For the atime preserve/change tests, the files must have
48166651Smpp * atimes in the past.  We can accomplish this by explicitly invoking
49101544Siedowse * utime() on platforms that support it or by simply sleeping
5068963Sru * for a second after creating the files.  (Creating all of the files
51101544Siedowse * at once means we only need to sleep once.)
52163599Sru */
53166646Smppstatic void
54166651Smpptest_create(void)
55101544Siedowse{
561590Srgrimes	struct stat st;
5795124Scharnier	struct utimbuf times;
5895124Scharnier	static const int numfiles = sizeof(files) / sizeof(files[0]);
5995124Scharnier	int i;
601590Srgrimes
61163599Sru	for (i = 0; i < numfiles; ++i) {
621590Srgrimes		/*
6358618Scharnier		 * Note: Have to write at least one byte to the file.
6458618Scharnier		 * cpio doesn't bother reading the file if it's zero length,
65166646Smpp		 * so the atime never gets changed in that case, which
66166646Smpp		 * makes the tests below rather pointless.
67166646Smpp		 */
68166646Smpp		assertMakeFile(files[i].name, 0644, "a");
691590Srgrimes
7079755Sdd		/* If utime() isn't supported on your platform, just
711590Srgrimes		 * #ifdef this section out.  Most of the test below is
72163599Sru		 * still valid. */
73163599Sru		memset(&times, 0, sizeof(times));
74163599Sru#if defined(_WIN32) && !defined(CYGWIN)
75101545Siedowse		times.actime = 86400;
76101545Siedowse		times.modtime = 86400;
77101545Siedowse#else
78107788Sru		times.actime = 1;
791590Srgrimes		times.modtime = 3;
801590Srgrimes#endif
811590Srgrimes		assertEqualInt(0, utime(files[i].name, &times));
82107788Sru
83166646Smpp		/* Record whatever atime the file ended up with. */
84166646Smpp		/* If utime() is available, this should be 1, but there's
85166646Smpp		 * no harm in being careful. */
86166646Smpp		assertEqualInt(0, stat(files[i].name, &st));
87166646Smpp		files[i].atime_sec = st.st_atime;
88166646Smpp	}
89166646Smpp
90166651Smpp	/* Wait until the atime on the last file is actually in the past. */
91166646Smpp	sleepUntilAfter(files[numfiles - 1].atime_sec);
92166646Smpp}
93166646Smpp
94166646SmppDEFINE_TEST(test_option_a)
95166646Smpp{
96166646Smpp	struct stat st;
97166646Smpp	int r;
98101544Siedowse	char *p;
99101544Siedowse
100101544Siedowse	/* Create all of the test files. */
101101544Siedowse	test_create();
102101544Siedowse
103101544Siedowse	/* Sanity check; verify that atimes really do get modified. */
104107788Sru	p = slurpfile(NULL, "f0");
105101544Siedowse	assert(p != NULL);
1061590Srgrimes	free(p);
1071590Srgrimes	assertEqualInt(0, stat("f0", &st));
1081590Srgrimes	if (st.st_atime == files[0].atime_sec) {
1091590Srgrimes		skipping("Cannot verify -a option\n"
1101590Srgrimes		    "      Your system appears to not support atime.");
1111590Srgrimes	}
1121590Srgrimes	else
1131590Srgrimes	{
1141590Srgrimes		/*
1151590Srgrimes		 * If this disk is mounted noatime, then we can't
1161590Srgrimes		 * verify correct operation without -a.
1171590Srgrimes		 */
1181590Srgrimes
1191590Srgrimes		/* Copy the file without -a; should change the atime. */
12018718Swosch		r = systemf("echo %s | %s -pd copy-no-a > copy-no-a.out 2>copy-no-a.err", files[1].name, testprog);
1211590Srgrimes		assertEqualInt(r, 0);
1221590Srgrimes		assertTextFileContents("1 block\n", "copy-no-a.err");
1231590Srgrimes		assertEmptyFile("copy-no-a.out");
1241590Srgrimes		assertEqualInt(0, stat(files[1].name, &st));
1251590Srgrimes		failure("Copying file without -a should have changed atime.");
1261590Srgrimes		assert(st.st_atime != files[1].atime_sec);
12795124Scharnier
128107788Sru		/* Archive the file without -a; should change the atime. */
129107788Sru		r = systemf("echo %s | %s -o > archive-no-a.out 2>archive-no-a.err", files[2].name, testprog);
13058618Scharnier		assertEqualInt(r, 0);
13113236Sgraichen		assertTextFileContents("1 block\n", "copy-no-a.err");
13213236Sgraichen		assertEqualInt(0, stat(files[2].name, &st));
13313236Sgraichen		failure("Archiving file without -a should have changed atime.");
13458618Scharnier		assert(st.st_atime != files[2].atime_sec);
13513236Sgraichen	}
13613236Sgraichen
13758618Scharnier	/*
138107788Sru	 * We can, of course, still verify that the atime is unchanged
1391590Srgrimes	 * when using the -a option.
1401590Srgrimes	 */
14127888Scharnier
142107788Sru	/* Copy the file with -a; should not change the atime. */
143166646Smpp	r = systemf("echo %s | %s -pad copy-a > copy-a.out 2>copy-a.err",
144166646Smpp	    files[3].name, testprog);
145166646Smpp	assertEqualInt(r, 0);
146101545Siedowse	assertTextFileContents("1 block\n", "copy-a.err");
147101545Siedowse	assertEmptyFile("copy-a.out");
148101545Siedowse	assertEqualInt(0, stat(files[3].name, &st));
149101545Siedowse	failure("Copying file with -a should not have changed atime.");
150101545Siedowse	assertEqualInt(st.st_atime, files[3].atime_sec);
151101545Siedowse
152101545Siedowse	/* Archive the file with -a; should not change the atime. */
153107788Sru	r = systemf("echo %s | %s -oa > archive-a.out 2>archive-a.err",
1541590Srgrimes	    files[4].name, testprog);
1551590Srgrimes	assertEqualInt(r, 0);
1561590Srgrimes	assertTextFileContents("1 block\n", "copy-a.err");
157107788Sru	assertEqualInt(0, stat(files[4].name, &st));
1581590Srgrimes	failure("Archiving file with -a should not have changed atime.");
159107788Sru	assertEqualInt(st.st_atime, files[4].atime_sec);
1601590Srgrimes}
161107788Sru