From ab7719540668240baf734b44a63bff270557c0a6 Mon Sep 17 00:00:00 2001 From: Bernhard Voelker Date: Mon, 22 Oct 2018 00:54:51 +0200 Subject: [PATCH 3/3] test: add -N unary operator Bash knows 'test -N FILE'. Add it to GNU 'test' as well. * src/test.c (unary_operator): Add a case for 'N'. (usage): Document it. * doc/coreutils.texi (node File characteristic tests): Likewise. * NEWS (New features): Likewise. * tests/misc/test-N.sh: Add a test. * tests/local.mk (all_tests): Reference it. --- NEWS | 3 +++ doc/coreutils.texi | 6 ++++++ src/test.c | 11 +++++++++++ tests/local.mk | 1 + tests/misc/test-N.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100755 tests/misc/test-N.sh diff --git a/NEWS b/NEWS index a2b733d38..a8fa5f2e4 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,9 @@ GNU coreutils NEWS -*- outline -*- id now supports specifying multiple users. + test now supports the '-N FILE' unary operator (like e.g. bash) to check + whether FILE exists and has been modified since it was last read. + * Noteworthy changes in release 8.30 (2018-07-01) [stable] diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 512443aa6..30155bb86 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -13099,6 +13099,12 @@ True if @var{file1} is older (according to modification date) than True if @var{file1} and @var{file2} have the same device and inode numbers, i.e., if they are hard links to each other. address@hidden -N @var{file} address@hidden -N address@hidden mtime-greater-atime file check +True if @var{file} exists and has been modified (mtime) since it was +last read (atime). + @end table diff --git a/src/test.c b/src/test.c index 9005b1962..7ed797f17 100644 --- a/src/test.c +++ b/src/test.c @@ -417,6 +417,16 @@ unary_operator (void) unary_advance (); return euidaccess (argv[pos - 1], X_OK) == 0; + case 'N': /* File exists and has been modified since it was last read? */ + { + unary_advance (); + if (stat (argv[pos - 1], &stat_buf) != 0) + return false; + struct timespec atime = get_stat_atime (&stat_buf); + struct timespec mtime = get_stat_mtime (&stat_buf); + return (timespec_cmp (mtime, atime) > 0); + } + case 'O': /* File is owned by you? */ { unary_advance (); @@ -741,6 +751,7 @@ EXPRESSION is true or false and sets exit status. It is one of:\n\ "), stdout); fputs (_("\ -L FILE FILE exists and is a symbolic link (same as -h)\n\ + -N FILE FILE exists and has been modified since it was last read\n\ -O FILE FILE exists and is owned by the effective user ID\n\ -p FILE FILE exists and is a named pipe\n\ -r FILE FILE exists and read permission is granted\n\ diff --git a/tests/local.mk b/tests/local.mk index 47c6b9537..84d346979 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -408,6 +408,7 @@ all_tests = \ tests/misc/tac-2-nonseekable.sh \ tests/misc/tail.pl \ tests/misc/tee.sh \ + tests/misc/test-N.sh \ tests/misc/test-diag.pl \ tests/misc/time-style.sh \ tests/misc/timeout.sh \ diff --git a/tests/misc/test-N.sh b/tests/misc/test-N.sh new file mode 100755 index 000000000..36eae8e8c --- /dev/null +++ b/tests/misc/test-N.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# Test 'test -N file'. + +# Copyright (C) 2018 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ test + +# For a freshly touched file, atime should equal mtime: 'test -N' returns 1. +touch file || framework_failure_ +stat file +returns_ 1 env test -N file || fail=1 + +# Set access time to yesterday at noon: 'test -N' returns 0. +touch -a -d "12:00 today -1 days" file || framework_failure_ +stat file +env test -N file || fail=1 + +# Set mtime to the day before yesterday: 'test -N' returns 1; +touch -m -d "12:00 today -2 days" file || framework_failure_ +stat file +returns_ 1 env test -N file || fail=1 + +# Now modify the file: 'test -N' returns 0. +> file || framework_failure_ +stat file +env test -N file || fail=1 + +Exit $fail -- 2.19.1