From cf0e1bcdc666748ef2bcb38f806cac432936090d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 19 Sep 2013 14:12:29 -0700 Subject: [PATCH 1/1] timespec: new function make_timespec, and new constants * lib/timespec.h: Incorporate recent changes on the Emacs trunk. (TIMESPEC_RESOLUTION, LOG10_TIMESPEC_RESOLUTION): New constants. (make_timespec): New function. * lib/dtotimespec.c (dtotimespec): * lib/timespec-add.c (timespec_add): * lib/timespec-sub.c (timespec_sub): * lib/utimens.c (validate_timespec): * lib/utimensat.c (rpl_utimensat): Use these new constants and functions. --- ChangeLog | 11 +++++++++++ lib/dtotimespec.c | 30 ++++++++++-------------------- lib/timespec-add.c | 7 ++----- lib/timespec-sub.c | 7 ++----- lib/timespec.h | 17 +++++++++++++++++ lib/utimens.c | 6 ++++-- lib/utimensat.c | 8 ++++---- 7 files changed, 50 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0cd23677..5bf5dad7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2013-09-19 Paul Eggert + timespec: new function make_timespec, and new constants + * lib/timespec.h: Incorporate recent changes on the Emacs trunk. + (TIMESPEC_RESOLUTION, LOG10_TIMESPEC_RESOLUTION): New constants. + (make_timespec): New function. + * lib/dtotimespec.c (dtotimespec): + * lib/timespec-add.c (timespec_add): + * lib/timespec-sub.c (timespec_sub): + * lib/utimens.c (validate_timespec): + * lib/utimensat.c (rpl_utimensat): + Use these new constants and functions. + stdio: OS X port of putc_unlocked + extern inline * lib/stdio.in.h (putc_unlocked): #undef on problematic Apple platforms. * doc/posix-functions/putc_unlocked.texi: diff --git a/lib/dtotimespec.c b/lib/dtotimespec.c index ecce2e5bc..064f7d3a0 100644 --- a/lib/dtotimespec.c +++ b/lib/dtotimespec.c @@ -29,41 +29,31 @@ struct timespec dtotimespec (double sec) { - enum { BILLION = 1000 * 1000 * 1000 }; double min_representable = TYPE_MINIMUM (time_t); double max_representable = - ((TYPE_MAXIMUM (time_t) * (double) BILLION + (BILLION - 1)) - / BILLION); - struct timespec r; + ((TYPE_MAXIMUM (time_t) * (double) TIMESPEC_RESOLUTION + + (TIMESPEC_RESOLUTION - 1)) + / TIMESPEC_RESOLUTION); if (! (min_representable < sec)) - { - r.tv_sec = TYPE_MINIMUM (time_t); - r.tv_nsec = 0; - } + return make_timespec (TYPE_MINIMUM (time_t), 0); else if (! (sec < max_representable)) - { - r.tv_sec = TYPE_MAXIMUM (time_t); - r.tv_nsec = BILLION - 1; - } + return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_RESOLUTION - 1); else { time_t s = sec; - double frac = BILLION * (sec - s); + double frac = TIMESPEC_RESOLUTION * (sec - s); long ns = frac; ns += ns < frac; - s += ns / BILLION; - ns %= BILLION; + s += ns / TIMESPEC_RESOLUTION; + ns %= TIMESPEC_RESOLUTION; if (ns < 0) { s--; - ns += BILLION; + ns += TIMESPEC_RESOLUTION; } - r.tv_sec = s; - r.tv_nsec = ns; + return make_timespec (s, ns); } - - return r; } diff --git a/lib/timespec-add.c b/lib/timespec-add.c index 6ce2c7306..51323a632 100644 --- a/lib/timespec-add.c +++ b/lib/timespec-add.c @@ -28,11 +28,10 @@ struct timespec timespec_add (struct timespec a, struct timespec b) { - struct timespec r; time_t rs = a.tv_sec; time_t bs = b.tv_sec; int ns = a.tv_nsec + b.tv_nsec; - int nsd = ns - 1000000000; + int nsd = ns - TIMESPEC_RESOLUTION; int rns = ns; if (0 <= nsd) @@ -65,7 +64,5 @@ timespec_add (struct timespec a, struct timespec b) else rs += bs; - r.tv_sec = rs; - r.tv_nsec = rns; - return r; + return make_timespec (rs, rns); } diff --git a/lib/timespec-sub.c b/lib/timespec-sub.c index 97c9f9de8..b164a8380 100644 --- a/lib/timespec-sub.c +++ b/lib/timespec-sub.c @@ -29,7 +29,6 @@ struct timespec timespec_sub (struct timespec a, struct timespec b) { - struct timespec r; time_t rs = a.tv_sec; time_t bs = b.tv_sec; int ns = a.tv_nsec - b.tv_nsec; @@ -37,7 +36,7 @@ timespec_sub (struct timespec a, struct timespec b) if (ns < 0) { - rns = ns + 1000000000; + rns = ns + TIMESPEC_RESOLUTION; if (rs == TYPE_MINIMUM (time_t)) { if (bs <= 0) @@ -65,7 +64,5 @@ timespec_sub (struct timespec a, struct timespec b) else rs -= bs; - r.tv_sec = rs; - r.tv_nsec = rns; - return r; + return make_timespec (rs, rns); } diff --git a/lib/timespec.h b/lib/timespec.h index 5990d070e..d0c029b57 100644 --- a/lib/timespec.h +++ b/lib/timespec.h @@ -29,6 +29,23 @@ _GL_INLINE_HEADER_BEGIN # define _GL_TIMESPEC_INLINE _GL_INLINE #endif +/* Resolution of timespec time stamps (in units per second), and log + base 10 of the resolution. */ + +enum { TIMESPEC_RESOLUTION = 1000000000 }; +enum { LOG10_TIMESPEC_RESOLUTION = 9 }; + +/* Return a timespec with seconds S and nanoseconds NS. */ + +_GL_TIMESPEC_INLINE struct timespec +make_timespec (time_t s, long int ns) +{ + struct timespec r; + r.tv_sec = s; + r.tv_nsec = ns; + return r; +} + /* Return negative, zero, positive if A < B, A == B, A > B, respectively. For each time stamp T, this code assumes that either: diff --git a/lib/utimens.c b/lib/utimens.c index 013843d6d..44a33c1d7 100644 --- a/lib/utimens.c +++ b/lib/utimens.c @@ -90,10 +90,12 @@ validate_timespec (struct timespec timespec[2]) assert (timespec); if ((timespec[0].tv_nsec != UTIME_NOW && timespec[0].tv_nsec != UTIME_OMIT - && (timespec[0].tv_nsec < 0 || 1000000000 <= timespec[0].tv_nsec)) + && ! (0 <= timespec[0].tv_nsec + && timespec[0].tv_nsec < TIMESPEC_RESOLUTION)) || (timespec[1].tv_nsec != UTIME_NOW && timespec[1].tv_nsec != UTIME_OMIT - && (timespec[1].tv_nsec < 0 || 1000000000 <= timespec[1].tv_nsec))) + && ! (0 <= timespec[1].tv_nsec + && timespec[1].tv_nsec < TIMESPEC_RESOLUTION))) { errno = EINVAL; return -1; diff --git a/lib/utimensat.c b/lib/utimensat.c index 0c52b24e0..f3a665190 100644 --- a/lib/utimensat.c +++ b/lib/utimensat.c @@ -93,11 +93,11 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], values. */ else if (times && ((times[0].tv_nsec != UTIME_NOW - && (times[0].tv_nsec < 0 - || times[0].tv_nsec >= 1000000000)) + && ! (0 <= times[0].tv_nsec + && times[0].tv_nsec < TIMESPEC_RESOLUTION)) || (times[1].tv_nsec != UTIME_NOW - && (times[1].tv_nsec < 0 - || times[1].tv_nsec >= 1000000000)))) + && ! (0 <= times[1].tv_nsec + && times[1].tv_nsec < TIMESPEC_RESOLUTION)))) { errno = EINVAL; return -1; -- 2.11.0