From 89f6af42ba33ce2c43f891d7da229725a66cc4e6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Aug 2006 01:31:00 +0000 Subject: r17766: Getting ready to properly expose 100ns times on the wire. Move the internals of nt_time functions to use struct timespecs. Jeremy. (This used to be commit 4ece92f7ef070c86ee7c6f523a207cfaccf84478) --- source3/lib/time.c | 97 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 29 deletions(-) (limited to 'source3/lib/time.c') diff --git a/source3/lib/time.c b/source3/lib/time.c index 0bfdfac856..9c5f412a9d 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -178,22 +178,28 @@ int TimeDiff(time_t t) Interpret an 8 byte "filetime" structure to a time_t It's originally in "100ns units since jan 1st 1601" - An 8 byte value of 0xffffffffffffffff will be returned as (time_t)0. + An 8 byte value of 0xffffffffffffffff will be returned as a timespec of + + tv_sec = 0 + tv_nsec = 0; Returns GMT. ****************************************************************************/ -time_t nt_time_to_unix(NTTIME *nt) +struct timespec nt_time_to_unix_timespec(NTTIME *nt) { double d; - time_t ret; + struct timespec ret; /* The next two lines are a fix needed for the broken SCO compiler. JRA. */ time_t l_time_min = TIME_T_MIN; time_t l_time_max = TIME_T_MAX; - if (nt->high == 0 || (nt->high == 0xffffffff && nt->low == 0xffffffff)) { - return(0); + if ((nt->high == 0 && nt->low == 0 )|| + (nt->high == 0xffffffff && nt->low == 0xffffffff)) { + ret.tv_sec = 0; + ret.tv_nsec = 0; + return ret; } d = ((double)nt->high)*4.0*(double)(1<<30); @@ -204,15 +210,26 @@ time_t nt_time_to_unix(NTTIME *nt) d -= TIME_FIXUP_CONSTANT; if (d <= l_time_min) { - return (l_time_min); + ret.tv_sec = l_time_min; + ret.tv_nsec = 0; + return ret; } if (d >= l_time_max) { - return (l_time_max); + ret.tv_sec = l_time_max; + ret.tv_nsec = 0; + return ret; } - ret = (time_t)(d+0.5); - return(ret); + ret.tv_sec = (time_t)d; + ret.tv_nsec = (long) ((d*1.0e9) - ((double)ret.tv_sec)*1.0e9); + return ret; +} + +time_t nt_time_to_unix(NTTIME *nt) +{ + struct timespec ts = nt_time_to_unix_timespec(nt); + return ts.tv_sec; } /**************************************************************************** @@ -224,10 +241,10 @@ time_t nt_time_to_unix(NTTIME *nt) if the NTTIME was 5 seconds, the time_t is 5 seconds. JFM ****************************************************************************/ -time_t nt_time_to_unix_abs(const NTTIME *nt) +struct timespec nt_time_to_unix_abs(const NTTIME *nt) { double d; - time_t ret; + struct timespec ret; /* The next two lines are a fix needed for the broken SCO compiler. JRA. */ time_t l_time_min = TIME_T_MIN; @@ -235,11 +252,15 @@ time_t nt_time_to_unix_abs(const NTTIME *nt) NTTIME neg_nt; if (nt->high == 0) { - return(0); + ret.tv_sec = 0; + ret.tv_nsec = 0; + return ret; } if (nt->high==0x80000000 && nt->low==0) { - return (time_t)-1; + ret.tv_sec = (time_t)-1; + ret.tv_nsec = 0; + return ret; } /* reverse the time */ @@ -252,63 +273,81 @@ time_t nt_time_to_unix_abs(const NTTIME *nt) d *= 1.0e-7; if (!(l_time_min <= d && d <= l_time_max)) { - return(0); + ret.tv_sec = 0; + ret.tv_nsec = 0; + return ret; } - ret = (time_t)(d+0.5); - - return(ret); + ret.tv_sec = (time_t)d; + ret.tv_nsec = (long) ((d*1.0e9) - ((double)ret.tv_sec)*1.0e9); + return ret; } /**************************************************************************** - Interprets an nt time into a unix time_t. + Interprets an nt time into a unix struct timespec. Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff will be returned as (time_t)-1, whereas nt_time_to_unix returns 0 in this case. ****************************************************************************/ -time_t interpret_long_date(char *p) +struct timespec interpret_long_date(char *p) { NTTIME nt; nt.low = IVAL(p,0); nt.high = IVAL(p,4); if (nt.low == 0xFFFFFFFF && nt.high == 0xFFFFFFFF) { - return (time_t)-1; + struct timespec ret; + ret.tv_sec = (time_t)-1; + ret.tv_nsec = 0; + return ret; } - return nt_time_to_unix(&nt); + return nt_time_to_unix_timespec(&nt); } /**************************************************************************** - Put a 8 byte filetime from a time_t. Uses GMT. + Put a 8 byte filetime from a struct timespec. Uses GMT. ****************************************************************************/ -void unix_to_nt_time(NTTIME *nt, time_t t) +void unix_timespec_to_nt_time(NTTIME *nt, struct timespec ts) { double d; - if (t==0) { + if (ts.tv_sec ==0 && ts.tv_nsec == 0) { nt->low = 0; nt->high = 0; return; } - if (t == TIME_T_MAX) { + if (ts.tv_sec == TIME_T_MAX) { nt->low = 0xffffffff; nt->high = 0x7fffffff; return; } - if (t == (time_t)-1) { + if (ts.tv_sec == (time_t)-1) { nt->low = 0xffffffff; nt->high = 0xffffffff; return; } - d = (double)(t); + d = (double)(ts.tv_sec); d += TIME_FIXUP_CONSTANT; d *= 1.0e7; + d += ((double)ts.tv_nsec / 100.0); nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30)))); nt->low = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30)); } +/**************************************************************************** + Put a 8 byte filetime from a time_t. Uses GMT. +****************************************************************************/ + +void unix_to_nt_time(NTTIME *nt, time_t t) +{ + struct timespec ts; + ts.tv_sec = t; + ts.tv_nsec = 0; + unix_timespec_to_nt_time(nt, ts); +} + /**************************************************************************** Convert a time_t to a NTTIME structure @@ -356,10 +395,10 @@ void unix_to_nt_time_abs(NTTIME *nt, time_t t) pointed to by p. ****************************************************************************/ -void put_long_date(char *p, time_t t) +void put_long_date(char *p, struct timespec ts) { NTTIME nt; - unix_to_nt_time(&nt, t); + unix_timespec_to_nt_time(&nt, ts); SIVAL(p, 0, nt.low); SIVAL(p, 4, nt.high); } -- cgit