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(×, 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, ×)); 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