From abe5c1f9bc09753fd79e7a121c8ecfa917dfaddb Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 30 Sep 2010 16:31:50 -0600 Subject: stat: support printing birthtime * src/stat.c (print_stat): New %w and %W formats. (do_stat): Include %w in default format. (usage): Document new specifiers. * doc/coreutils.texi (stat invocation): Likewise. * NEWS: Likewise. --- NEWS | 5 +++-- doc/coreutils.texi | 2 ++ src/stat.c | 28 +++++++++++++++++++++++++--- tests/Makefile.am | 1 + tests/misc/stat-birthtime | 41 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 5 deletions(-) create mode 100755 tests/misc/stat-birthtime diff --git a/NEWS b/NEWS index 11a8b74fd..0c7cc38d1 100644 --- a/NEWS +++ b/NEWS @@ -36,8 +36,9 @@ GNU coreutils NEWS -*- outline -*- sort now supports -d, -f, -i, -R, and -V in any combination. - stat now accepts the %m format directive to output - the mount point for a file. + stat now accepts the %m format directive to output the mount point + for a file. It also accepts the %w and %W format directives for + outputting the birth time of a file, if one is available. ** Changes in behavior diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 52f1b2000..12f103a12 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -10696,6 +10696,8 @@ The valid @var{format} directives for files with @option{--format} and @item %T - Minor device type in hex @item %u - User ID of owner @item %U - User name of owner +@item %w - Time of file birth, or @samp{-} if unknown +@item %W - Time of file birth as seconds since Epoch, or @samp{-} @item %x - Time of last access @item %X - Time of last access as seconds since Epoch @item %y - Time of last modification diff --git a/src/stat.c b/src/stat.c index f98597885..e1d68a556 100644 --- a/src/stat.c +++ b/src/stat.c @@ -788,6 +788,26 @@ print_stat (char *pformat, size_t prefix_len, char m, case 'o': out_uint (pformat, prefix_len, statbuf->st_blksize); break; + case 'w': + { + struct timespec t = get_stat_birthtime (statbuf); + if (t.tv_nsec < 0) + out_string (pformat, prefix_len, "-"); + else + out_string (pformat, prefix_len, human_time (t)); + } + break; + case 'W': + { + struct timespec t = get_stat_birthtime (statbuf); + if (t.tv_nsec < 0) + out_string (pformat, prefix_len, "-"); + else if (TYPE_SIGNED (time_t)) + out_int (pformat, prefix_len, t.tv_sec); + else + out_uint (pformat, prefix_len, t.tv_sec); + } + break; case 'x': out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); break; @@ -1042,7 +1062,7 @@ do_stat (char const *filename, bool terse, char const *format) { if (terse) { - format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; + format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %W %o\n"; } else { @@ -1056,7 +1076,7 @@ do_stat (char const *filename, bool terse, char const *format) "Device: %Dh/%dd\tInode: %-10i Links: %-5h" " Device type: %t,%T\n" "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" - "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + "Access: %x\n" "Modify: %y\n" "Change: %z\n" " Birth: %w\n"; } else { @@ -1065,7 +1085,7 @@ do_stat (char const *filename, bool terse, char const *format) " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" "Device: %Dh/%dd\tInode: %-10i Links: %h\n" "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" - "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + "Access: %x\n" "Modify: %y\n" "Change: %z\n" " Birth: %w\n"; } } } @@ -1130,6 +1150,8 @@ The valid format sequences for files (without --file-system):\n\ fputs (_("\ %u User ID of owner\n\ %U User name of owner\n\ + %w Time of file birth, or - if unknown\n\ + %W Time of file birth as seconds since Epoch, or - if unknown\n\ %x Time of last access\n\ %X Time of last access as seconds since Epoch\n\ %y Time of last modification\n\ diff --git a/tests/Makefile.am b/tests/Makefile.am index 3236637c6..a6a0594b8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -239,6 +239,7 @@ TESTS = \ misc/split-a \ misc/split-fail \ misc/split-l \ + misc/stat-birthtime \ misc/stat-fmt \ misc/stat-hyphen \ misc/stat-mount \ diff --git a/tests/misc/stat-birthtime b/tests/misc/stat-birthtime new file mode 100755 index 000000000..b54268c11 --- /dev/null +++ b/tests/misc/stat-birthtime @@ -0,0 +1,41 @@ +#!/bin/sh +# ensure that stat attempts birthtime access + +# Copyright (C) 2010 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=.}/init.sh"; path_prepend_ ../src + +# Whether birthtime is supported or not, it better not change even when +# [acm]time are modified. :) +touch a || fail=1 +btime=$(stat --format %W a) || fail=1 +atime=$(stat --format %X a) || fail=1 +mtime=$(stat --format %Y a) || fail=1 +ctime=$(stat --format %Z a) || fail=1 + +case $(stat --format %x a) in + *.000000000*) sleep 2;; # worst case file system is FAT + *) # FIXME: sleep .1 would be sufficient if %X is fixed to show nanoseconds + sleep 1;; +esac + +touch a || fail=1 +test "x$btime" = x$(stat --format %W a) || fail=1 +test "x$atime" != x$(stat --format %X a) || fail=1 +test "x$mtime" != x$(stat --format %Y a) || fail=1 +test "x$ctime" != x$(stat --format %Z a) || fail=1 + +Exit $fail -- cgit v1.2.3-54-g00ecf