Add functions for converting to/from a struct timespec, and for setting

the system clock
This commit is contained in:
Laurence Withers 2007-09-13 11:05:51 +00:00
parent 2a51412ade
commit c47e0e241f
3 changed files with 67 additions and 0 deletions

View File

@ -11,6 +11,7 @@
/* standard includes, or includes needed for type declarations */
#include <time.h>
#include <stdint.h>
#include <sys/time.h>
/* options for text editors
kate: replace-trailing-space-save true; space-indent true; tab-width 4;

View File

@ -44,6 +44,33 @@ void iso8601_now(struct iso8601_date* date, struct iso8601_details* details)
int iso8601_set_sysclock(const struct iso8601_date* date)
{
static int use_settimeofday = 0;
struct timeval tv;
struct timespec ts;
/* not all systems have clock_settime implemented */
if(use_settimeofday) goto try_settimeofday;
/* try setting clock */
iso8601_to_ts(&ts, date);
if(clock_settime(CLOCK_REALTIME, &ts)) {
if(errno == EPERM) return -1;
use_settimeofday = 1;
goto try_settimeofday;
}
return 0;
/* fallback using settimeofday() */
try_settimeofday:
iso8601_to_tv(&tv, date);
return settimeofday(&tv, 0);
}
void iso8601_from_ts(struct iso8601_date* date, const struct timespec* ts)
{
ldiv_t qr;
@ -64,6 +91,26 @@ void iso8601_to_ts(struct timespec* ts, const struct iso8601_date* date)
void iso8601_from_tv(struct iso8601_date* date, const struct timeval* tv)
{
ldiv_t qr;
qr = ldiv(tv->tv_sec, 86400);
date->day = EPOCH_GDAY + qr.quot;
date->sec = qr.rem;
date->nsec = tv->tv_usec * 1000;
}
void iso8601_to_tv(struct timeval* tv, const struct iso8601_date* date)
{
tv->tv_sec = 86400L * (date->day - EPOCH_GDAY) + date->sec;
tv->tv_usec = date->nsec / 1000;
}
void iso8601_from_time_t(struct iso8601_date* date, const time_t* t)
{
ldiv_t qr;

View File

@ -29,10 +29,29 @@ void iso8601_now(struct iso8601_date* date, struct iso8601_details* details);
/*! \brief Set the system clock.
\param date Date to set.
\retval 0 on success.
\retval -1 on error (and see \a errno).
Attempts to set the system clock using \c clock_settime(), falling back to \c settimeofday(). The
user will need the \c CAP_SYS_TIME capability to set the clock, otherwise \a errno will be set to
\c EPERM.
*/
int iso8601_set_sysclock(const struct iso8601_date* date);
/*! \brief Convert from a struct timespec. */
void iso8601_from_ts(struct iso8601_date* date, const struct timespec* ts);
/*! \brief Convert to a struct timespec. */
void iso8601_to_ts(struct timespec* ts, const struct iso8601_date* date);
/*! \brief Convert from a struct timeval. */
void iso8601_from_tv(struct iso8601_date* date, const struct timeval* tv);
/*! \brief Convert to a struct timeval. */
void iso8601_to_tv(struct timeval* tv, const struct iso8601_date* date);
/*! \brief Convert from a time_t. */
void iso8601_from_time_t(struct iso8601_date* date, const time_t* t);
/*! \brief Convert to a time_t. */