diff options
Diffstat (limited to 'sntp/timing.c')
-rw-r--r-- | sntp/timing.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/sntp/timing.c b/sntp/timing.c new file mode 100644 index 0000000..30a9159 --- /dev/null +++ b/sntp/timing.c @@ -0,0 +1,110 @@ +/* Copyright (C) 1996 N.M. Maclaren + Copyright (C) 1996 The University of Cambridge + +This includes all of the code needed to handle the time. It assumes rather +more than is defined by POSIX, unfortunately. Systems that do not have the +'X/Open' extensions may need changes. */ + + + +#include "header.h" + +#include <sys/types.h> +#include <sys/time.h> + +#define TIMING +#include "kludges.h" +#undef TIMING + + + +#define MILLION_L 1000000l /* For conversion to/from timeval */ +#define MILLION_D 1.0e6 /* Must be equal to MILLION_L */ + + + +double current_time (double offset) { + +/* Get the current UTC time in seconds since the Epoch plus an offset (usually +the time from the beginning of the century to the Epoch!) */ + + struct timeval current; + + errno = 0; + if (gettimeofday(¤t,NULL)) + fatal(1,"unable to read current machine/system time",NULL); + return offset+current.tv_sec+1.0e-6*current.tv_usec; +} + + + +time_t convert_time (double value, int *millisecs) { + +/* Convert the time to the ANSI C form. */ + + time_t result = (time_t)value; + + if ((*millisecs = (int)(1000.0*(value-result))) >= 1000) { + *millisecs = 0; + ++result; + } + return result; +} + + + +void adjust_time (double difference, int immediate, double ignore) { + +/* Adjust the current UTC time. This is portable, even if struct timeval uses +an unsigned long for tv_sec. */ + + struct timeval old, new, adjust, previous; + char text[40]; + long n; + +/* Start by converting to timeval format. Note that we have to cater for +negative, unsigned values. */ + + if ((n = (long)difference) > difference) --n; + adjust.tv_sec = n; + adjust.tv_usec = (long)(MILLION_D*(difference-n)); + errno = 0; + if (gettimeofday(&old,NULL)) + fatal(1,"unable to read machine/system time",NULL); + new.tv_sec = old.tv_sec+adjust.tv_sec; + new.tv_usec = (n = (long)old.tv_usec+(long)adjust.tv_usec); + if (n < 0) { + new.tv_usec += MILLION_L; + --new.tv_sec; + } else if (n >= MILLION_L) { + new.tv_usec -= MILLION_L; + ++new.tv_sec; + } + +/* Now diagnose the situation if necessary, and perform the dirty deed. */ + + if (verbose > 2) + fprintf(stderr, + "Times: old=(%ld,%.6ld) new=(%ld,%.6ld) adjust=(%ld,%.6ld)\n", + (long)old.tv_sec,(long)old.tv_usec, + (long)new.tv_sec,(long)new.tv_usec, + (long)adjust.tv_sec,(long)adjust.tv_usec); + if (immediate) { + errno = 0; + /* if (settimeofday(&new,NULL)) + fatal(1,"unable to reset current system time",NULL);*/ + } else { + errno = 0; + /* if (adjtime(&adjust,&previous)) + fatal(1,"unable to adjust current system time",NULL);*/ + if (previous.tv_sec != 0 || previous.tv_usec != 0) { + sprintf(text,"(%ld,%.6ld)", + (long)previous.tv_sec,(long)previous.tv_usec); + if (previous.tv_sec+1.0e-6*previous.tv_usec > ignore) + fatal(0,"outstanding time adjustment %s",text); + else if (verbose) + fprintf(stderr,"%s: outstanding time adjustment %s\n", + argv0,text); + } + } +} |