mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-02-16 20:33:18 +02:00
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.
This commit is contained in:
@@ -85,7 +85,6 @@ gnulib_modules="
|
||||
freopen
|
||||
freopen-safer
|
||||
fseeko
|
||||
fstimeprec
|
||||
fsusage
|
||||
fsync
|
||||
ftello
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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));
|
||||
@@ -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
|
||||
@@ -1,10 +0,0 @@
|
||||
Files:
|
||||
tests/test-fstimeprec.c
|
||||
|
||||
Depends-on:
|
||||
|
||||
configure.ac:
|
||||
|
||||
Makefile.am:
|
||||
TESTS += test-fstimeprec
|
||||
check_PROGRAMS += test-fstimeprec
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user