Package: coreutils;
Reported by: Jim Meyering <jim <at> meyering.net>
Date: Wed, 3 Nov 2010 18:56:02 UTC
Severity: normal
Done: Pádraig Brady <P <at> draigBrady.com>
Bug is archived. No further changes may be made.
Message #134 received at 7325 <at> debbugs.gnu.org (full text, mbox):
From: Jim Meyering <jim <at> meyering.net> To: Paul Eggert <eggert <at> cs.ucla.edu> Cc: Eric Blake <eblake <at> redhat.com>, 7325 <at> debbugs.gnu.org, Pádraig Brady <P <at> draigBrady.com> Subject: Re: bug#7325: new test failure due to non-portability of printf formats like %05.3s Date: Sat, 13 Nov 2010 11:45:09 +0100
Paul Eggert wrote: > On 11/12/2010 06:12 AM, Jim Meyering wrote: >> I'd like to defer the addition of this feature, >> at least until it's more predictable. >> >> Is that ok with you, Paul? > > Doesn't bother me. We can revisit this again in twenty years. > Perhaps by then, pathconf will support interrogation of > file systems for their time stamp resolutions, as POSIX requires. > > In the meantime we can add it to 'diff' instead, where it > wouldn't be as problematic. Here's what I'm planning. With this, I'm ready for coreutils-8.7. Debating whether to make another snapshot first. We'll see... From 4a8e9bf14c33b356680298d29f7321d82d4fde5d Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering <at> redhat.com> Date: Sat, 13 Nov 2010 08:02:02 +0100 Subject: [PATCH 1/3] stat: do not provide variable precision time stamps * src/stat.c: Don't include fstimeprec.c. (out_epoch_sec): Don't call fstimeprec. * NEWS: Update description. * doc/coreutils.texi: Likewise. --- NEWS | 5 +++-- doc/coreutils.texi | 10 +++++----- gnulib | 2 +- src/stat.c | 6 +----- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index e77768d..51e0650 100644 --- a/NEWS +++ b/NEWS @@ -24,8 +24,9 @@ GNU coreutils NEWS -*- outline -*- stat's %X, %Y, and %Z directives once again print only the integer part of seconds since the epoch. This reverts a change from coreutils-8.6, that was deemed unnecessarily disruptive. To obtain - a full resolution time stamp for %X, use %.X; if you want (say) just - 3 fractional digits, use %.3X. Likewise for %Y and %Z. + a nanosecond-precision floating point time stamp for %X use %.X; + if you want (say) just 3 fractional digits, use %.3X. Likewise + for %Y and %Z. stat's new %W format directive would print floating point seconds. However, with the above change to %X, %Y and %Z, we've made %W work diff --git a/doc/coreutils.texi b/doc/coreutils.texi index ce56b0e..6a4257f 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -10718,10 +10718,10 @@ stat invocation The @samp{%W}, @samp{%X}, @samp{%Y}, and @samp{%Z} formats accept a precision preceded by a period to specify the number of digits to -print after the decimal point. For example, @samp{%.9X} outputs the -last access time to nanosecond precision. If a period is given but no -precision, @command{stat} uses the estimated precision of the file -system. When discarding excess precision, time stamps are truncated +print after the decimal point. For example, @samp{%.3X} outputs the +last access time to millisecond precision. If a period is given but no +precision, @command{stat} uses 9 digits, so @samp{%.X} is equivalent to +@samp{%.9X} When discarding excess precision, time stamps are truncated toward minus infinity. @example @@ -10737,7 +10737,7 @@ stat invocation $ stat -c '[%.3Y]' /usr [1288929712.114] $ stat -c '[%.Y]' /usr - [1288929712.114951] + [1288929712.114951834] @end example The mount point printed by @samp{%m} is similar to that output diff --git a/gnulib b/gnulib index 4baf5c1..6383a3b 160000 --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 4baf5c1e594a65a315fbd5094eaeeb11f4630d18 +Subproject commit 6383a3bbe16d3615791568c030fed5bfe86a4381 diff --git a/src/stat.c b/src/stat.c index ae7ce02..b419f19 100644 --- a/src/stat.c +++ b/src/stat.c @@ -63,7 +63,6 @@ #include "file-type.h" #include "filemode.h" #include "fs.h" -#include "fstimeprec.h" #include "getopt.h" #include "mountlist.h" #include "quote.h" @@ -557,10 +556,7 @@ out_epoch_sec (char *pformat, size_t prefix_len, struct stat const *statbuf, } else { - static struct fstimeprec *tab; - if (! tab) - tab = fstimeprec_alloc (); - precision = fstimeprec (tab, statbuf); + precision = 9; } if (precision && ISDIGIT (dot[-1])) -- 1.7.3.2.4.g60aa9 From ff5fc553f974513e27015faa414fca3603e928e7 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering <at> redhat.com> Date: Sat, 13 Nov 2010 08:04:13 +0100 Subject: [PATCH 2/3] maint: remove fstimeprec (variable precision time stamp) support The implementation of variable-precision time stamps relied on heuristics that made the output subtly nondeterministic, or at least hard to reproduce: http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/21531/focus=21538 So, for now at least, we're removing that feature. * bootstrap.conf (gnulib_modules): Remove fstimeprec. * gl/lib/fstimeprec.c, gl/lib/fstimeprec.h: Remove files. * gl/modules/fstimeprec, gl/modules/fstimeprec-tests: Likewise. * gl/tests/test-fstimeprec.c: Remove file. --- bootstrap.conf | 1 - gl/lib/fstimeprec.c | 178 ------------------------------------------- gl/lib/fstimeprec.h | 22 ----- gl/modules/fstimeprec | 24 ------ gl/modules/fstimeprec-tests | 10 --- gl/tests/test-fstimeprec.c | 74 ------------------ 6 files changed, 0 insertions(+), 309 deletions(-) delete mode 100644 gl/lib/fstimeprec.c delete mode 100644 gl/lib/fstimeprec.h delete mode 100644 gl/modules/fstimeprec delete mode 100644 gl/modules/fstimeprec-tests delete mode 100644 gl/tests/test-fstimeprec.c diff --git a/bootstrap.conf b/bootstrap.conf index 5a6ebae..18ef914 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -85,7 +85,6 @@ gnulib_modules=" freopen freopen-safer fseeko - fstimeprec fsusage fsync ftello diff --git a/gl/lib/fstimeprec.c b/gl/lib/fstimeprec.c deleted file mode 100644 index fd63054..0000000 --- a/gl/lib/fstimeprec.c +++ /dev/null @@ -1,178 +0,0 @@ -/* Determine a file system's time stamp precision. - - Copyright 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 <http://www.gnu.org/licenses/>. */ - -/* written by Paul Eggert */ - -#include <config.h> -#include "fstimeprec.h" - -#include "hash.h" -#include "stat-time.h" -#include <limits.h> -#include <stdlib.h> - -/* A hash table that maps device numbers to precisions. */ -struct fstimeprec -{ - /* Map device numbers to precisions. */ - struct hash_table *map; - - /* Cache of the most recently allocated and otherwise-unused storage - for probing this table. */ - struct ent *probe; -}; - -/* A pair that maps a device number to a precision. */ -struct ent -{ - dev_t dev; - int prec; -}; - -/* Hash an entry. */ -static size_t -ent_hash (void const *x, size_t table_size) -{ - struct ent const *p = x; - dev_t dev = p->dev; - - /* FIXME: This code is duplicated from di-set.c. */ - /* When DEV is wider than size_t, exclusive-OR the words of DEV into H. - This avoids loss of info, without applying % to the wider type, - which could be quite slow on some systems. */ - size_t h = dev; - unsigned int i; - unsigned int n_words = sizeof dev / sizeof h + (sizeof dev % sizeof h != 0); - for (i = 1; i < n_words; i++) - h ^= dev >> CHAR_BIT * sizeof h * i; - - return h % table_size; -} - -/* Return true if two entries are the same. */ -static bool -ent_compare (void const *x, void const *y) -{ - struct ent const *a = x; - struct ent const *b = y; - return a->dev == b->dev; -} - -/* Using the SET table, map a device to an entry that represents - the file system precision. Return NULL on error. */ -static struct ent * -map_device (struct fstimeprec *tab, dev_t dev) -{ - /* Find space for the probe, reusing the cache if available. */ - struct ent *ent; - struct ent *probe = tab->probe; - if (probe) - { - /* If repeating a recent query, return the cached result. */ - if (probe->dev == dev) - return probe; - } - else - { - tab->probe = probe = malloc (sizeof *probe); - if (! probe) - return NULL; - probe->prec = 0; - } - - /* Probe for the device. */ - probe->dev = dev; - ent = hash_insert (tab->map, probe); - if (ent == probe) - tab->probe = NULL; - return ent; -} - -/* Return a newly allocated table of file system time stamp - resolutions, or NULL if out of memory. */ -struct fstimeprec * -fstimeprec_alloc (void) -{ - struct fstimeprec *tab = malloc (sizeof *tab); - if (tab) - { - enum { INITIAL_DEV_MAP_SIZE = 11 }; - tab->map = hash_initialize (INITIAL_DEV_MAP_SIZE, NULL, - ent_hash, ent_compare, free); - if (! tab->map) - { - free (tab); - return NULL; - } - tab->probe = NULL; - } - return tab; -} - -/* Free TAB. */ -void -fstimeprec_free (struct fstimeprec *tab) -{ - hash_free (tab->map); - free (tab->probe); - free (tab); -} - -/* Using the cached information in TAB, return the estimated precision - of time stamps for the file system containing the file whose status - info is in ST. The returned value counts the number of decimal - fraction digits. Return 0 on failure. - - If TAB is null, the guess is based purely on ST. */ -int -fstimeprec (struct fstimeprec *tab, struct stat const *st) -{ - /* Map the device number to an entry. */ - struct ent *ent = (tab ? map_device (tab, st->st_dev) : NULL); - - /* Guess the precision based on what has been seen so far. */ - int prec = (ent ? ent->prec : 0); - - /* If the current file's timestamp resolution is higher than the - guess, increase the guess. */ - if (prec < 9) - { - struct timespec ats = get_stat_atime (st); - struct timespec mts = get_stat_mtime (st); - struct timespec cts = get_stat_ctime (st); - struct timespec bts = get_stat_birthtime (st); - unsigned int ans = ats.tv_nsec; - unsigned int mns = mts.tv_nsec; - unsigned int cns = cts.tv_nsec; - unsigned int bns = bts.tv_nsec < 0 ? 0 : bts.tv_nsec; - unsigned int power = 10; - int p; - for (p = prec + 1; p < 9; p++) - power *= 10; - - while (ans % power | mns % power | cns % power | bns % power) - { - power /= 10; - prec++; - } - - if (ent) - ent->prec = prec; - } - - return prec; -} diff --git a/gl/lib/fstimeprec.h b/gl/lib/fstimeprec.h deleted file mode 100644 index 8ec24df..0000000 --- a/gl/lib/fstimeprec.h +++ /dev/null @@ -1,22 +0,0 @@ -#include <sys/stat.h> - -#ifndef ATTRIBUTE_MALLOC -# if __GNUC__ >= 3 -# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) -# else -# define ATTRIBUTE_MALLOC -# endif -#endif - -#ifndef _GL_ARG_NONNULL -# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 -# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) -# else -# define _GL_ARG_NONNULL(params) -# endif -#endif - -struct fstimeprec *fstimeprec_alloc (void) ATTRIBUTE_MALLOC; -void fstimeprec_free (struct fstimeprec *) _GL_ARG_NONNULL ((1)); -int fstimeprec (struct fstimeprec *, struct stat const *) - _GL_ARG_NONNULL ((2)); diff --git a/gl/modules/fstimeprec b/gl/modules/fstimeprec deleted file mode 100644 index 787c2e7..0000000 --- a/gl/modules/fstimeprec +++ /dev/null @@ -1,24 +0,0 @@ -Description: -estimate precision of time stamps in file systems - -Files: -lib/fstimeprec.c -lib/fstimeprec.h - -Depends-on: -hash -stat-time - -configure.ac: - -Makefile.am: -lib_SOURCES += fstimeprec.c fstimeprec.h - -Include: -"fstimeprec.h" - -License -GPL - -Maintainer: -Paul Eggert and Jim Meyering diff --git a/gl/modules/fstimeprec-tests b/gl/modules/fstimeprec-tests deleted file mode 100644 index bf6b49e..0000000 --- a/gl/modules/fstimeprec-tests +++ /dev/null @@ -1,10 +0,0 @@ -Files: -tests/test-fstimeprec.c - -Depends-on: - -configure.ac: - -Makefile.am: -TESTS += test-fstimeprec -check_PROGRAMS += test-fstimeprec diff --git a/gl/tests/test-fstimeprec.c b/gl/tests/test-fstimeprec.c deleted file mode 100644 index f699139..0000000 --- a/gl/tests/test-fstimeprec.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Test the fstimeprec module. - 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 <http://www.gnu.org/licenses/>. */ - -/* written by Paul Eggert */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/stat.h> - -#define ASSERT(expr) \ - do \ - { \ - if (!(expr)) \ - { \ - fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ - fflush (stderr); \ - abort (); \ - } \ - } \ - while (0) - -#include "fstimeprec.h" - -static int -fstimeprec_file (struct fstimeprec *tab, char const *file) -{ - struct stat st; - if (stat (file, &st) != 0) - return 0; - return fstimeprec (tab, &st); -} - -int -main (void) -{ - struct fstimeprec *tab = fstimeprec_alloc (); - ASSERT (tab); - - int m1 = fstimeprec_file (tab, "/"); - int m2 = fstimeprec_file (tab, "."); - int m3 = fstimeprec_file (tab, ".."); - ASSERT (0 <= m1 && m1 <= 9); - ASSERT (0 <= m2 && m2 <= 9); - ASSERT (0 <= m3 && m3 <= 9); - - int n1 = fstimeprec_file (tab, "/"); - int n2 = fstimeprec_file (tab, "."); - int n3 = fstimeprec_file (tab, ".."); - ASSERT (0 <= n1 && n1 <= 9); - ASSERT (0 <= n2 && n2 <= 9); - ASSERT (0 <= n3 && n3 <= 9); - - ASSERT (m1 <= n1); - ASSERT (m2 <= n2); - ASSERT (m3 <= n3); - - fstimeprec_free (tab); - - return 0; -} -- 1.7.3.2.4.g60aa9 From 2d5b3329a2c97a2fee4851d9551ee3d080106765 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering <at> redhat.com> Date: Sat, 13 Nov 2010 10:12:49 +0100 Subject: [PATCH 3/3] build: update gnulib for linux 2.6.9 nanosleep workaround Also, do the following to avoid "make syntax-check" failure induced by new rules. * .x-sc_bindtextdomain: Exempt files with an #ifdef'd "main". * Makefile.am: Add this file. --- .x-sc_bindtextdomain | 7 +++++++ Makefile.am | 1 + 2 files changed, 8 insertions(+), 0 deletions(-) create mode 100644 .x-sc_bindtextdomain diff --git a/.x-sc_bindtextdomain b/.x-sc_bindtextdomain new file mode 100644 index 0000000..2a568be --- /dev/null +++ b/.x-sc_bindtextdomain @@ -0,0 +1,7 @@ +^gl/lib/randint\.c$ +^gl/tests/test-di-set\.c$ +^gl/tests/test-fadvise\.c$ +^gl/tests/test-ino-map\.c$ +^gl/tests/test-mbsalign\.c$ +^gl/tests/test-rand-isaac\.c$ +^lib/euidaccess-stat\.c$ diff --git a/Makefile.am b/Makefile.am index 9fd5361..b61229d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,6 +41,7 @@ changelog_etc = \ syntax_check_exceptions = \ .x-sc_GPL_version \ + .x-sc_bindtextdomain \ .x-sc_error_message_uppercase \ .x-sc_file_system \ .x-sc_obsolete_symbols \ -- 1.7.3.2.4.g60aa9
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.