/* greater than operation */ int gtTime(const TimeInternal *x, const TimeInternal *y) { TimeInternal r; subTime(&r, x, y); return !isTimeNegative(&r); }
static Boolean stepTime (ClockDriver *self, TimeInternal *delta, Boolean force) { GET_CONFIG_CLOCKDRIVER(self, myConfig, unix); if(isTimeZero(delta)) { return TRUE; } struct timespec nts; TimeInternal oldTime,newTime; getTime(self, &oldTime); addTime(&newTime, &oldTime, delta); if(self->config.readOnly) { return FALSE; } if(force) { self->lockedUp = FALSE; } if(!force && !self->config.negativeStep && isTimeNegative(delta)) { CRITICAL(THIS_COMPONENT"Cannot step Unix clock %s backwards\n", self->name); CRITICAL(THIS_COMPONENT"Manual intervention required or SIGUSR1 to force %s clock step\n", self->name); self->lockedUp = TRUE; self->setState(self, CS_NEGSTEP); return FALSE; } #ifdef ADJ_SETOFFSET struct timex tmx; memset(&tmx, 0, sizeof(tmx)); tmx.modes = ADJ_SETOFFSET | ADJ_NANO; tmx.time.tv_sec = delta->seconds; tmx.time.tv_usec = delta->nanoseconds; getTime(self, &newTime); addTime(&newTime, &newTime, delta); nts.tv_sec = newTime.seconds; if(nts.tv_sec == 0) { ERROR(THIS_COMPONENT"Unix clock %s: cannot step time to zero seconds\n", self->name); return FALSE; } if(nts.tv_sec < 0) { ERROR(THIS_COMPONENT"Unix clock %s: cannot step time to a negative value %d\n", self->name, nts.tv_sec); return FALSE; } if(adjtimex(&tmx) < 0) { DBG("Could not set clock offset of Unix clock %s\n", self->name); return setTime(self, &newTime, force); } NOTICE(THIS_COMPONENT"Unix clock %s: stepped clock by %s%d.%09d seconds\n", self->name, (delta->seconds <0 || delta->nanoseconds <0) ? "-":"", delta->seconds, delta->nanoseconds); addTime(&_stepAccumulator, &_stepAccumulator, delta); self->_stepped = TRUE; self->setState(self, CS_FREERUN); if(oldTime.seconds != newTime.seconds) { updateXtmp_unix(oldTime, newTime); if(myConfig->setRtc) { setRtc(self, &newTime); } } return TRUE; #else return setTime(self, &newTime, force); #endif }
static Boolean setTime (ClockDriver *self, TimeInternal *time, Boolean force) { GET_CONFIG_CLOCKDRIVER(self, myConfig, unix); TimeInternal oldTime, delta; getTime(self, &oldTime); subTime(&delta, &oldTime, time); if(self->config.readOnly) { return FALSE; } if(force) { self->lockedUp = FALSE; } if(!force && !self->config.negativeStep && isTimeNegative(&delta)) { CRITICAL(THIS_COMPONENT"Cannot step Unix clock %s backwards\n", self->name); CRITICAL(THIS_COMPONENT"Manual intervention required or SIGUSR1 to force %s clock step\n", self->name); self->lockedUp = TRUE; self->setState(self, CS_NEGSTEP); return FALSE; } #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) struct timespec tp; tp.tv_sec = time->seconds; tp.tv_nsec = time->nanoseconds; if(tp.tv_sec == 0) { ERROR(THIS_COMPONENT"Unix clock driver %s: cannot set time to zero seconds\n", self->name); return FALSE; } if(tp.tv_sec <= 0) { ERROR(THIS_COMPONENT"Unic clock driver %s: cannot set time to a negative value %d\n", self->name, tp.tv_sec); return FALSE; } #else struct timeval tv; tv.tv_sec = time->seconds; tv.tv_usec = time->nanoseconds / 1000; if(tv.tv_sec == 0) { ERROR(THIS_COMPONENT"Unix clock %s: cannot set time to zero seconds\n", self->name); return FALSE; } if(tv.tv_sec < 0) { ERROR(THIS_COMPONENT"Unic clock %s: cannot set time to a negative value %d\n", self->name, tv.tv_sec); return FALSE; } #endif /* _POSIX_TIMERS */ #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) if (clock_settime(CLOCK_REALTIME, &tp) < 0) { PERROR(THIS_COMPONENT"Could not set system time"); return FALSE; } addTime(&_stepAccumulator, &_stepAccumulator, &delta); #else settimeofday(&tv, 0); addTime(&_stepAccumulator, &_stepAccumulator, &delta); #endif /* _POSIX_TIMERS */ if(oldTime.seconds != time->seconds) { updateXtmp_unix(oldTime, *time); if(myConfig->setRtc) { setRtc(self, time); } } self->_stepped = TRUE; struct timespec tmpTs = { time->seconds,0 }; char timeStr[MAXTIMESTR]; strftime(timeStr, MAXTIMESTR, "%x %X", localtime(&tmpTs.tv_sec)); NOTICE(THIS_COMPONENT"Unix clock %s: stepped the system clock to: %s.%d\n", self->name, timeStr, time->nanoseconds); self->setState(self, CS_FREERUN); return TRUE; }