#ifndef VLIBC_SYS_TIME_H #define VLIBC_SYS_TIME_H /* * vlibc — . * * Wall-clock access and per-process interval timers expressed in * microseconds. Everything here is XSI or BSD legacy — POSIX.1-2008 base * leaves only timerisset in this header — so the whole surface is gated at * level 2: * * Level 2 (muslmimic): gettimeofday, settimeofday, getitimer, * setitimer, utimes, futimes, lutimes, * struct timeval, struct itimerval, * struct timezone, the timer* macros. * * struct timeval is the same type uses for select()'s * timeout; that header defines it under the shared guard below so the two * headers agree and either may be included first. The layout is the kernel * ABI on x86_64 (two longs), which is why gettimeofday/setitimer pass it * through unmodified. * * ITIMER_REAL/ITIMER_VIRTUAL/ITIMER_PROF are kernel ABI values (the * getitimer/setitimer `which` argument). None of these declarations carries * an intent attribute: every function performs I/O with side effects and * reports failures through errno, so const/pure would be unsound. */ #include #include /* time_t, suseconds_t */ #ifdef __cplusplus extern "C" { #endif #if VLIBC_LEVEL_GE(2) /* Level 2 (muslmimic): XSI/BSD date-and-time interfaces. */ /* Interval-timer kinds (kernel ABI; the `which` argument). */ #define ITIMER_REAL 0 /* count down in real time */ #define ITIMER_VIRTUAL 1 /* count down in process virtual time */ #define ITIMER_PROF 2 /* count down in process virtual + system time */ /* * Elapsed time in seconds and microseconds. Shared guard with * , which needs struct timeval for select()'s timeout at * level 1 and defines it under the same macro; either header may therefore * be included first. tv_usec holds 0..999999. */ #ifndef VLIBC_TIMEVAL_DEFINED #define VLIBC_TIMEVAL_DEFINED struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ }; #endif /* * An interval timer setting: it_value is the time to the next expiry, * it_interval the period between expiries after the first (both zero for a * one-shot or a disarmed timer). Kernel ABI layout (x86_64): two timevals. */ struct itimerval { struct timeval it_interval; /* interval between periodic expiries */ struct timeval it_value; /* time to the next expiry */ }; /* * Historic timezone record for settimeofday(). POSIX.1-2008 removed struct * timezone; it is kept for the legacy gettimeofday/settimeofday signatures, * whose tz argument is ignored (see src/time/gettimeofday.c). */ struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of daylight-saving correction */ }; /* True when the timer described by tp is armed. */ #define timerisset(tp) ((tp)->tv_sec != 0 || (tp)->tv_usec != 0) /* Disarm the timer described by tp (zero both fields). */ #define timerclear(tp) ((tp)->tv_sec = (tp)->tv_usec = 0) /* * Set *result to *a plus *b, normalizing the carry into tv_sec. The * arguments may be evaluated more than once (classic BSD form). */ #define timeradd(a, b, result) \ do \ { \ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ if ((result)->tv_usec >= 1000000) \ { \ (result)->tv_sec++; \ (result)->tv_usec -= 1000000; \ } \ } while (0) /* * Set *result to *a minus *b, normalizing the borrow out of tv_sec. The * arguments may be evaluated more than once (classic BSD form). */ #define timersub(a, b, result) \ do \ { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) \ { \ (result)->tv_sec--; \ (result)->tv_usec += 1000000; \ } \ } while (0) /* * True when *a op *b, compared first by tv_sec and, on equality, by * tv_usec. op is a comparison operator (timercmp(x, y, <=)). The * arguments may be evaluated more than once (classic BSD form). */ /* clang-format off */ #define timercmp(a, b, op) \ (((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_usec op (b)->tv_usec) : ((a)->tv_sec op (b)->tv_sec)) /* clang-format on */ /* * Read the current wall-clock time into tv (seconds since the Epoch and * microseconds 0..999999). tz is ignored for compatibility with the * historic two-argument form and may be anything, including NULL; tv may * also be NULL, in which case nothing is written. Return 0, or -1 with * errno set when tv points outside the address space. */ int gettimeofday(struct timeval *restrict tv, void *restrict tz); /* * Set the kernel's idea of the current time from tv. tz, when not NULL, is * honored only together with tv; passing tz alone is unsupported (ENOTSUP). * Requires privilege. Return 0, or -1 with errno set. */ int settimeofday(const struct timeval *tv, const struct timezone *tz); /* * Store the current setting of interval timer which (ITIMER_REAL, * ITIMER_VIRTUAL or ITIMER_PROF) through value. Return 0, or -1 with errno * set for an unknown which or when value points outside the address space. */ int getitimer(int which, struct itimerval *value); /* * Arm interval timer which from value (when value is not NULL) and store * the previous setting through ovalue (when not NULL). A value whose * it_value is zero disarms the timer. Return 0, or -1 with errno set. */ int setitimer(int which, const struct itimerval *restrict value, struct itimerval *restrict ovalue); /* * Set the access (times[0]) and modification (times[1]) timestamps of path. * A NULL times array sets both to the current time. Return 0, or -1 with * errno set. */ int utimes(const char *path, const struct timeval times[2]); /* utimes() on the open file fd. */ int futimes(int fd, const struct timeval times[2]); /* utimes() on the symbolic link path itself, never following it. */ int lutimes(const char *path, const struct timeval times[2]); #endif /* VLIBC_LEVEL_GE(2) */ #ifdef __cplusplus } #endif #endif /* VLIBC_SYS_TIME_H */