[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
new module stat-time, to ease access to sub-second file time stamps
From: |
Paul Eggert |
Subject: |
new module stat-time, to ease access to sub-second file time stamps |
Date: |
Thu, 15 Sep 2005 23:56:45 -0700 |
User-agent: |
Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux) |
I installed the following patch to clean up the timespec module, which
had some stat-related stuff in it that (1) really belonged in a
separate module, and (2) did not support sub-second file time stamp
resolution on several operating systems, e.g., OpenBSD.
Much of the new code is stolen from GNU tar. I have tested these
changes with (modified) GNU tar and coreutils, and will update tar and
coreutils soon to incorporate these changes.
2005-09-15 Paul Eggert <address@hidden>
* MODULES.html.sh (File system functions): Add stat-time.
* lib/stat-time.h: New file.
* lib/timespec.h (ST_TIME_CMP_NS, ST_TIME_CMP, ATIME_CMP, CTIME_CMP):
(MTIME_CMP, TIMESPEC_NS): Remove. Now done by stat-time.h,
in a different way.
(timespec_cmp): New function.
* m4/st_mtim.m4: Remove. Superseded by...
* m4/stat-time.m4: New file.
* m4/timespec.m4 (gl_TIMESPEC): Require AC_C_INLINE.
Do not invoke AC_STRUCT_ST_MTIM_NSEC; no longer needed.
* modules/stat-time: New file.
* modules/timespec (Files): Remove m4/st_mtim.m4; this
is now done in a different way, by the stat-time module.
Index: MODULES.html.sh
===================================================================
RCS file: /cvsroot/gnulib/gnulib/MODULES.html.sh,v
retrieving revision 1.106
diff -p -u -r1.106 MODULES.html.sh
--- MODULES.html.sh 25 Aug 2005 12:36:01 -0000 1.106
+++ MODULES.html.sh 16 Sep 2005 06:48:17 -0000
@@ -1849,6 +1849,7 @@ func_all_modules ()
func_module same
func_module save-cwd
func_module savedir
+ func_module stat-time
func_module unlinkdir
func_module utimecmp
func_module utimens
Index: lib/timespec.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/timespec.h,v
retrieving revision 1.5
diff -p -u -r1.5 timespec.h
--- lib/timespec.h 14 May 2005 06:03:58 -0000 1.5
+++ lib/timespec.h 16 Sep 2005 06:48:18 -0000
@@ -42,22 +42,15 @@ struct timespec
};
# endif
-# ifdef ST_MTIM_NSEC
-# define ST_TIME_CMP_NS(a, b, ns) ((a).ns < (b).ns ? -1 : (a).ns > (b).ns)
-# else
-# define ST_TIME_CMP_NS(a, b, ns) 0
-# endif
-# define ST_TIME_CMP(a, b, s, ns) \
- ((a).s < (b).s ? -1 : (a).s > (b).s ? 1 : ST_TIME_CMP_NS(a, b, ns))
-# define ATIME_CMP(a, b) ST_TIME_CMP (a, b, st_atime, st_atim.ST_MTIM_NSEC)
-# define CTIME_CMP(a, b) ST_TIME_CMP (a, b, st_ctime, st_ctim.ST_MTIM_NSEC)
-# define MTIME_CMP(a, b) ST_TIME_CMP (a, b, st_mtime, st_mtim.ST_MTIM_NSEC)
-
-# ifdef ST_MTIM_NSEC
-# define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC)
-# else
-# define TIMESPEC_NS(timespec) 0
-# endif
+/* Return negative, zero, positive if A < B, A == B, A > B, respectively.
+ Assume the nanosecond components are in range, or close to it. */
+static inline int
+timespec_cmp (struct timespec a, struct timespec b)
+{
+ return (a.tv_sec < b.tv_sec ? -1
+ : a.tv_sec > b.tv_sec ? 1
+ : a.tv_nsec - b.tv_nsec);
+}
# if ! HAVE_DECL_NANOSLEEP
/* Don't specify a prototype here. Some systems (e.g., OSF) declare
Index: m4/timespec.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/timespec.m4,v
retrieving revision 1.10
diff -p -u -r1.10 timespec.m4
--- m4/timespec.m4 21 Mar 2005 22:06:27 -0000 1.10
+++ m4/timespec.m4 16 Sep 2005 06:48:18 -0000
@@ -1,4 +1,4 @@
-#serial 10
+#serial 11
# Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
@@ -12,10 +12,10 @@ AC_DEFUN([gl_TIMESPEC],
AC_LIBSOURCES([timespec.h])
dnl Prerequisites of lib/timespec.h.
+ AC_REQUIRE([AC_C_INLINE])
AC_REQUIRE([AC_HEADER_TIME])
AC_CHECK_HEADERS_ONCE(sys/time.h)
gl_CHECK_TYPE_STRUCT_TIMESPEC
- AC_STRUCT_ST_MTIM_NSEC
dnl Persuade glibc <time.h> to declare nanosleep().
AC_REQUIRE([AC_GNU_SOURCE])
Index: modules/timespec
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/timespec,v
retrieving revision 1.6
diff -p -u -r1.6 timespec
--- modules/timespec 21 Mar 2005 22:07:25 -0000 1.6
+++ modules/timespec 16 Sep 2005 06:48:18 -0000
@@ -3,7 +3,6 @@ struct timespec.
Files:
lib/timespec.h
-m4/st_mtim.m4
m4/timespec.m4
Depends-on:
--- /dev/null 2005-06-27 15:40:05.000000000 -0700
+++ modules/stat-time 2005-09-15 22:45:47.000000000 -0700
@@ -0,0 +1,23 @@
+Description:
+stat-related time functions
+
+Files:
+lib/stat-time.h
+m4/stat-time.m4
+
+Depends-on:
+timespec
+
+configure.ac:
+gl_STAT_TIME
+
+Makefile.am:
+
+Include:
+"stat-time.h"
+
+License:
+GPL
+
+Maintainer:
+Paul Eggert and Jim Meyering
--- /dev/null 2005-06-27 15:40:05.000000000 -0700
+++ m4/stat-time.m4 2005-09-15 22:39:57.000000000 -0700
@@ -0,0 +1,39 @@
+# Checks for stat-related time functions.
+
+# Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# st_atim.tv_nsec - Linux, Solaris
+# st_atimespec.tv_nsec - FreeBSD, if ! defined _POSIX_SOURCE
+# st_atimensec - FreeBSD, if defined _POSIX_SOURCE
+# st_atim.st__tim.tv_nsec - UnixWare (at least 2.1.2 through 7.1)
+# st_spare1 - Cygwin?
+
+AC_DEFUN([gl_STAT_TIME],
+[
+ AC_LIBSOURCES([stat-time.h])
+
+ AC_REQUIRE([AC_C_INLINE])
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+
+ AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec], [],
+ [AC_CHECK_MEMBERS([struct stat.st_atimespec.tv_nsec], [],
+ [AC_CHECK_MEMBERS([struct stat.st_atimensec], [],
+ [AC_CHECK_MEMBERS([struct stat.st_atim.st__tim.tv_nsec], [],
+ [AC_CHECK_MEMBERS([struct stat.st_spare1], [],
+ [],
+ [#include <sys/types.h>
+ #include <sys/stat.h>])],
+ [#include <sys/types.h>
+ #include <sys/stat.h>])],
+ [#include <sys/types.h>
+ #include <sys/stat.h>])],
+ [#include <sys/types.h>
+ #include <sys/stat.h>])],
+ [#include <sys/types.h>
+ #include <sys/stat.h>])
+])
--- /dev/null 2005-06-27 15:40:05.000000000 -0700
+++ lib/stat-time.h 2005-09-15 23:21:44.000000000 -0700
@@ -0,0 +1,178 @@
+/* stat-related time functions.
+
+ Copyright (C) 2005 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 2, 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, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert. */
+
+#ifndef STAT_TIME_H
+#define STAT_TIME_H 1
+
+#include "timespec.h"
+
+/* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type
+ struct timespec, if available. If not, then STAT_TIMESPEC_NS (ST,
+ ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST,
+ if available. ST_XTIM can be st_atim, st_ctim, or st_mtim for
+ access, status change, or data modification time, respectively.
+
+ These macros are private to stat-time.h. */
+#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim)
+#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec)
+#elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC
+# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec)
+#elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC
+# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec)
+#endif
+
+/* Return the nanosecond component of *ST's access time. */
+static inline long int
+get_stat_atime_ns (struct stat const *st)
+{
+# if defined STAT_TIMESPEC
+ return STAT_TIMESPEC (st, st_atim).tv_nsec;
+# elif defined STAT_TIMESPEC_NS
+ return STAT_TIMESPEC_NS (st, st_atim);
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ return st->st_spare1 * 1000;
+# else
+ return 0;
+# endif
+}
+
+/* Return the nanosecond component of *ST's status change time. */
+static inline long int
+get_stat_ctime_ns (struct stat const *st)
+{
+# if defined STAT_TIMESPEC
+ return STAT_TIMESPEC (st, st_ctim).tv_nsec;
+# elif defined STAT_TIMESPEC_NS
+ return STAT_TIMESPEC_NS (st, st_ctim);
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ return st->st_spare3 * 1000;
+# else
+ return 0;
+# endif
+}
+
+/* Return the nanosecond component of *ST's data modification time. */
+static inline long int
+get_stat_mtime_ns (struct stat const *st)
+{
+# if defined STAT_TIMESPEC
+ return STAT_TIMESPEC (st, st_mtim).tv_nsec;
+# elif defined STAT_TIMESPEC_NS
+ return STAT_TIMESPEC_NS (st, st_mtim);
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ return st->st_spare2 * 1000;
+# else
+ return 0;
+# endif
+}
+
+/* Return *ST's access time. */
+static inline struct timespec
+get_stat_atime (struct stat const *st)
+{
+#ifdef STAT_TIMESPEC
+ return STAT_TIMESPEC (st, st_atim);
+#else
+ struct timespec t;
+ t.tv_sec = st->st_atime;
+ t.tv_nsec = get_stat_atime_ns (st);
+ return t;
+#endif
+}
+
+/* Return *ST's status change time. */
+static inline struct timespec
+get_stat_ctime (struct stat const *st)
+{
+#ifdef STAT_TIMESPEC
+ return STAT_TIMESPEC (st, st_ctim);
+#else
+ struct timespec t;
+ t.tv_sec = st->st_ctime;
+ t.tv_nsec = get_stat_ctime_ns (st);
+ return t;
+#endif
+}
+
+/* Return *ST's data modification time. */
+static inline struct timespec
+get_stat_mtime (struct stat const *st)
+{
+#ifdef STAT_TIMESPEC
+ return STAT_TIMESPEC (st, st_mtim);
+#else
+ struct timespec t;
+ t.tv_sec = st->st_mtime;
+ t.tv_nsec = get_stat_mtime_ns (st);
+ return t;
+#endif
+}
+
+/* Set *ST's access time. */
+static inline void
+set_stat_atime (struct stat *st, struct timespec t)
+{
+#ifdef STAT_TIMESPEC
+ STAT_TIMESPEC (st, st_atim) = t;
+#else
+ st->st_atime = t.tv_sec;
+# if defined STAT_TIMESPEC_NS
+ STAT_TIMESPEC_NS (st, st_atim) = t.tv_nsec;
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ st->st_spare1 = t.tv_nsec / 1000;
+# endif
+#endif
+}
+
+/* Set *ST's status change time. */
+static inline void
+set_stat_ctime (struct stat *st, struct timespec t)
+{
+#ifdef STAT_TIMESPEC
+ STAT_TIMESPEC (st, st_ctim) = t;
+#else
+ st->st_ctime = t.tv_sec;
+# if defined STAT_TIMESPEC_NS
+ STAT_TIMESPEC_NS (st, st_ctim) = t.tv_nsec;
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ st->st_spare1 = t.tv_nsec / 1000;
+# endif
+#endif
+}
+
+/* Set *ST's data modification time. */
+static inline void
+set_stat_mtime (struct stat *st, struct timespec t)
+{
+#ifdef STAT_TIMESPEC
+ STAT_TIMESPEC (st, st_mtim) = t;
+#else
+ st->st_mtime = t.tv_sec;
+# if defined STAT_TIMESPEC_NS
+ STAT_TIMESPEC_NS (st, st_mtim) = t.tv_nsec;
+# elif defined HAVE_STRUCT_STAT_ST_SPARE1
+ st->st_spare1 = t.tv_nsec / 1000;
+# endif
+#endif
+}
+
+#endif
- new module stat-time, to ease access to sub-second file time stamps,
Paul Eggert <=