diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | Src/cond.c | 20 | ||||
-rw-r--r-- | Src/glob.c | 54 | ||||
-rw-r--r-- | Src/system.h | 21 | ||||
-rw-r--r-- | configure.ac | 11 |
5 files changed, 109 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog index 5334df940..572b2a745 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2007-11-01 Oliver Kiddle <opk@zsh.org> + * 24050: configure.ac, Src/cond.c, Src/glob.c, Src/system.h: + handle nanosecond timestamps on systems that support them + * 24048: Src/hashtable.c: fix home directory expansion with NIS on Solaris diff --git a/Src/cond.c b/Src/cond.c index a38df6fb7..cabe64446 100644 --- a/Src/cond.c +++ b/Src/cond.c @@ -344,19 +344,39 @@ evalcond(Estate state, char *fromtest) case 'G': return !((st = getstat(left)) && st->st_gid == getegid()); case 'N': +#if defined(GET_ST_MTIME_NSEC) && defined(GET_ST_ATIME_NSEC) + if (!(st = getstat(left))) + return 1; + return (st->st_atime == st->st_mtime) ? + GET_ST_ATIME_NSEC(*st) > GET_ST_MTIME_NSEC(*st) : + st->st_atime > st->st_mtime; +#else return !((st = getstat(left)) && st->st_atime <= st->st_mtime); +#endif case 't': return !isatty(mathevali(left)); case COND_NT: case COND_OT: { time_t a; +#ifdef GET_ST_MTIME_NSEC + long nsecs; +#endif if (!(st = getstat(left))) return 1; a = st->st_mtime; +#ifdef GET_ST_MTIME_NSEC + nsecs = GET_ST_MTIME_NSEC(*st); +#endif if (!(st = getstat(right))) return 1; +#ifdef GET_ST_MTIME_NSEC + if (a == st->st_mtime) { + return !((ctype == COND_NT) ? nsecs > GET_ST_MTIME_NSEC(*st) : + nsecs < GET_ST_MTIME_NSEC(*st)); + } +#endif return !((ctype == COND_NT) ? a > st->st_mtime : a < st->st_mtime); } case COND_EF: diff --git a/Src/glob.c b/Src/glob.c index b703926a9..e81fd1e97 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -52,6 +52,18 @@ struct gmatch { long _mtime; long _ctime; long _links; +#ifdef GET_ST_ATIME_NSEC + long ansec; + long _ansec; +#endif +#ifdef GET_ST_MTIME_NSEC + long mnsec; + long _mnsec; +#endif +#ifdef GET_ST_CTIME_NSEC + long cnsec; + long _cnsec; +#endif }; #define GS_NAME 1 @@ -373,6 +385,15 @@ insert(char *s, int checked) matchptr->mtime = buf.st_mtime; matchptr->ctime = buf.st_ctime; matchptr->links = buf.st_nlink; +#ifdef GET_ST_ATIME_NSEC + matchptr->ansec = GET_ST_ATIME_NSEC(buf); +#endif +#ifdef GET_ST_MTIME_NSEC + matchptr->mnsec = GET_ST_MTIME_NSEC(buf); +#endif +#ifdef GET_ST_CTIME_NSEC + matchptr->cnsec = GET_ST_CTIME_NSEC(buf); +#endif } if (statted & 2) { matchptr->_size = buf2.st_size; @@ -380,6 +401,15 @@ insert(char *s, int checked) matchptr->_mtime = buf2.st_mtime; matchptr->_ctime = buf2.st_ctime; matchptr->_links = buf2.st_nlink; +#ifdef GET_ST_ATIME_NSEC + matchptr->_ansec = GET_ST_ATIME_NSEC(buf); +#endif +#ifdef GET_ST_MTIME_NSEC + matchptr->_mnsec = GET_ST_MTIME_NSEC(buf); +#endif +#ifdef GET_ST_CTIME_NSEC + matchptr->_cnsec = GET_ST_CTIME_NSEC(buf); +#endif } matchptr++; @@ -885,12 +915,24 @@ gmatchcmp(Gmatch a, Gmatch b) break; case GS_ATIME: r = a->atime - b->atime; +#ifdef GET_ST_ATIME_NSEC + if (!r) + r = a->ansec - b->ansec; +#endif break; case GS_MTIME: r = a->mtime - b->mtime; +#ifdef GET_ST_MTIME_NSEC + if (!r) + r = a->mnsec - b->mnsec; +#endif break; case GS_CTIME: r = a->ctime - b->ctime; +#ifdef GET_ST_CTIME_NSEC + if (!r) + r = a->cnsec - b->cnsec; +#endif break; case GS_LINKS: r = b->links - a->links; @@ -900,12 +942,24 @@ gmatchcmp(Gmatch a, Gmatch b) break; case GS__ATIME: r = a->_atime - b->_atime; +#ifdef GET_ST_ATIME_NSEC + if (!r) + r = a->_ansec - b->_ansec; +#endif break; case GS__MTIME: r = a->_mtime - b->_mtime; +#ifdef GET_ST_MTIME_NSEC + if (!r) + r = a->_mnsec - b->_mnsec; +#endif break; case GS__CTIME: r = a->_ctime - b->_ctime; +#ifdef GET_ST_CTIME_NSEC + if (!r) + r = a->_cnsec - b->_cnsec; +#endif break; case GS__LINKS: r = b->_links - a->_links; diff --git a/Src/system.h b/Src/system.h index 022ace250..2d89ac80e 100644 --- a/Src/system.h +++ b/Src/system.h @@ -805,3 +805,24 @@ extern short ospeed; # define USE_GETPWUID #endif +#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC +# define GET_ST_ATIME_NSEC(st) (st).st_atim.tv_nsec +#elif HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC +# define GET_ST_ATIME_NSEC(st) (st).st_atimespec.tv_nsec +#elif HAVE_STRUCT_STAT_ST_ATIMENSEC +# define GET_ST_ATIME_NSEC(st) (st).st_atimensec +#endif +#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC +# define GET_ST_MTIME_NSEC(st) (st).st_mtim.tv_nsec +#elif HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC +# define GET_ST_MTIME_NSEC(st) (st).st_mtimespec.tv_nsec +#elif HAVE_STRUCT_STAT_ST_MTIMENSEC +# define GET_ST_MTIME_NSEC(st) (st).st_mtimensec +#endif +#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC +# define GET_ST_CTIME_NSEC(st) (st).st_ctim.tv_nsec +#elif HAVE_STRUCT_STAT_ST_CTIMESPEC_TV_NSEC +# define GET_ST_CTIME_NSEC(st) (st).st_ctimespec.tv_nsec +#elif HAVE_STRUCT_STAT_ST_CTIMENSEC +# define GET_ST_CTIME_NSEC(st) (st).st_ctimensec +#endif diff --git a/configure.ac b/configure.ac index 83fda70b8..f42b90994 100644 --- a/configure.ac +++ b/configure.ac @@ -977,6 +977,17 @@ if test x$zsh_cv_type_sigset_t = xno; then AC_DEFINE(sigset_t, unsigned int) fi +dnl check structures for high resolution timestamps +AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec, + struct stat.st_atimespec.tv_nsec, + struct stat.st_atimensec, + struct stat.st_mtim.tv_nsec, + struct stat.st_mtimespec.tv_nsec, + struct stat.st_mtimensec, + struct stat.st_ctim.tv_nsec, + struct stat.st_ctimespec.tv_nsec, + struct stat.st_ctimensec]) + dnl Check for struct timezone since some old SCO versions do not define it zsh_TYPE_EXISTS([ #ifdef HAVE_SYS_TIME_H |