summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure23
-rw-r--r--share/txr/stdlib/path-test.tl8
-rw-r--r--sysif.c22
-rw-r--r--sysif.h4
-rw-r--r--txr.136
5 files changed, 86 insertions, 7 deletions
diff --git a/configure b/configure
index ba3c6f4d..5d31d359 100755
--- a/configure
+++ b/configure
@@ -127,6 +127,7 @@ debug_support=y
gen_gc=y
have_dbl_decimal_dig=
have_unistd=
+have_sys_stat=
have_sys_types=
have_sys_time=
have_makedev=
@@ -1609,10 +1610,32 @@ int main(void)
if conftest ; then
printf "yes\n"
printf "#define HAVE_SYS_STAT 1\n" >> config.h
+ have_sys_stat=y
else
printf "no\n"
fi
+if [ "$have_sys_stat" ] ; then
+ printf "Checking for sub-second resolution time in struct stat ... "
+
+ cat > conftest.c <<!
+
+#include <sys/stat.h>
+
+struct stat s;
+
+int main(void)
+{
+ return s.st_mtim.tv_nsec != 0;
+}
+!
+ if conftest ; then
+ printf "yes\n"
+ printf "#define HAVE_STAT_NSEC 1\n" >> config.h
+ else
+ printf "no\n"
+ fi
+fi
#
# environ
diff --git a/share/txr/stdlib/path-test.tl b/share/txr/stdlib/path-test.tl
index 59b24b13..4e26f1f8 100644
--- a/share/txr/stdlib/path-test.tl
+++ b/share/txr/stdlib/path-test.tl
@@ -153,7 +153,13 @@
(defun path-newer (path-0 path-1)
(sys:path-examine (s0 stat path-0)
(sys:path-examine (s1 stat path-1)
- (and s0 (or (not s1) (> s0.mtime s1.mtime))))))
+ (if s0
+ (or (null s1)
+ (let ((mt0 s0.mtime)
+ (mt1 s1.mtime))
+ (or (> mt0 mt1)
+ (and (= mt0 mt1)
+ (> s0.mtime-nsec s1.mtime-nsec)))))))))
(defun path-older (path-0 path-1)
(path-newer path-1 path-0))
diff --git a/sysif.c b/sysif.c
index f1eb5fa4..667e3ad9 100644
--- a/sysif.c
+++ b/sysif.c
@@ -101,7 +101,9 @@ val gid_k, rdev_k, size_k, blksize_k, blocks_k;
val atime_k, mtime_k, ctime_k;
val dev_s, ino_s, mode_s, nlink_s, uid_s;
val gid_s, rdev_s, size_s, blksize_s, blocks_s;
-val atime_s, mtime_s, ctime_s, path_s;
+val atime_s, mtime_s, ctime_s;
+val atime_nsec_s, mtime_nsec_s, ctime_nsec_s;
+val path_s;
#if HAVE_PWUID
val passwd_s, gecos_s, dir_s, shell_s;
@@ -822,6 +824,15 @@ val stat_to_struct(struct stat st, val path)
slotset(strct, atime_s, num(st.st_atime));
slotset(strct, mtime_s, num(st.st_mtime));
slotset(strct, ctime_s, num(st.st_ctime));
+#if HAVE_STAT_NSEC
+ slotset(strct, atime_nsec_s, num(st.st_atim.tv_nsec));
+ slotset(strct, mtime_nsec_s, num(st.st_mtim.tv_nsec));
+ slotset(strct, ctime_nsec_s, num(st.st_ctim.tv_nsec));
+#else
+ slotset(strct, atime_nsec_s, zero);
+ slotset(strct, mtime_nsec_s, zero);
+ slotset(strct, ctime_nsec_s, zero);
+#endif
if (path)
slotset(strct, path_s, path);
@@ -1719,6 +1730,9 @@ void sysif_init(void)
atime_s = intern(lit("atime"), user_package);
mtime_s = intern(lit("mtime"), user_package);
ctime_s = intern(lit("ctime"), user_package);
+ atime_nsec_s = intern(lit("atime-nsec"), user_package);
+ mtime_nsec_s = intern(lit("mtime-nsec"), user_package);
+ ctime_nsec_s = intern(lit("ctime-nsec"), user_package);
path_s = intern(lit("path"), user_package);
#if HAVE_PWUID
passwd_s = intern(lit("passwd"), user_package);
@@ -1750,8 +1764,10 @@ void sysif_init(void)
make_struct_type(stat_s, nil, nil,
list(dev_s, ino_s, mode_s, nlink_s, uid_s, gid_s,
- rdev_s, size_s, blksize_s, blocks_s, atime_s,
- mtime_s, ctime_s, path_s, nao), nil, nil, nil, nil);
+ rdev_s, size_s, blksize_s, blocks_s,
+ atime_s, atime_nsec_s, mtime_s, mtime_nsec_s,
+ ctime_s, ctime_nsec_s, path_s, nao),
+ nil, nil, nil, nil);
#if HAVE_PWUID
make_struct_type(passwd_s, nil, nil,
list(name_s, passwd_s, uid_s, gid_s,
diff --git a/sysif.h b/sysif.h
index 15625b24..cc817402 100644
--- a/sysif.h
+++ b/sysif.h
@@ -31,7 +31,9 @@ extern val gid_k, rdev_k, size_k, blksize_k, blocks_k;
extern val atime_k, mtime_k, ctime_k;
extern val dev_s, ino_s, mode_s, nlink_s, uid_s;
extern val gid_s, rdev_s, size_s, blksize_s, blocks_s;
-extern val atime_s, mtime_s, ctime_s, path_s;
+extern val atime_s, mtime_s, ctime_s;
+extern val atime_nsec_s, mtime_nsec_s, ctime_nsec_s;
+extern val path_s;
#if !HAVE_FTRUNCATE
typedef long off_t;
diff --git a/txr.1 b/txr.1
index 18e8cf73..851cfedf 100644
--- a/txr.1
+++ b/txr.1
@@ -56889,8 +56889,9 @@ as a way of specifying a command to execute.
.synb
.mets (defstruct stat nil
.mets \ \ dev ino mod nlink uid gid
-.mets \ \ rdev size blksize blocks atime
-.mets \ \ mtime ctime path)
+.mets \ \ rdev size blksize blocks
+.mets \ \ atime atime-nsec mtime mtime-nsec
+.mets \ \ ctime ctime-nsec path)
.syne
.desc
The
@@ -56903,6 +56904,10 @@ and
.code fstat
functions. Except for
.codn path ,
+.codn atime-nsec ,
+.code ctime-nsec
+and
+.codn mtime-nsec ,
the slots are the direct counterparts of the
members of POSIX C structure
.codn "struct stat" .
@@ -56910,6 +56915,7 @@ For instance the slot
.code dev
corresponds to
.codn st_dev .
+
The
.code path
slot is set by the functions
@@ -56920,6 +56926,22 @@ Its value is
.code nil
when the path is not available.
+The
+.codn atime-nsec ,
+.code ctime-nsec
+and
+.code mtime-nsec
+fields give the fractional parts of
+.codn atime ,
+.code ctime
+and
+.codn mtime ,
+respectively. They are derived from the newer style information
+in which the POSIX function provides the timestamps in
+.code "struct timespec"
+format. If that is not available from the platform, these
+fields take on values of zero.
+
.coNP Functions @, stat @ lstat and @ fstat
.synb
.mets (stat << path )
@@ -57580,6 +57602,16 @@ function is equivalent to
.code path-newer
with the arguments reversed.
+Note:
+.code path-newer
+takes advantage of sub-second timestamp resolution information,
+if available. The implementation is based on using the
+.code mtime-nsec
+field of the
+.code stat
+structure, if it isn't
+.codn nil .
+
.coNP Function @ path-same-object
.synb
.mets (path-same-object < left-path << right-path )