Commit cf0e1bcd authored by Paul Eggert's avatar 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.
parent 6f3c76e0
2013-09-19 Paul Eggert <eggert@cs.ucla.edu>
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:
......@@ -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;
}
......@@ -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);
}
......@@ -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);
}
......@@ -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:
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment