187 lines
7.5 KiB
C
187 lines
7.5 KiB
C
#ifndef VLIBC_SYS_TIME_H
|
|
#define VLIBC_SYS_TIME_H
|
|
|
|
/*
|
|
* vlibc — <sys/time.h>.
|
|
*
|
|
* 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 <sys/select.h> 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 <vlibc/features.h>
|
|
|
|
#include <sys/types.h> /* 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
|
|
* <sys/select.h>, 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 */
|