libc: add clock_settime() system call.
This also adds the sys_settime() kernel call which allows for the adjusting of the clock named realtime in the kernel. The existing sys_stime() function is still needed for a separate job (setting the boottime). The boottime is set in the readclock driver. The sys_settime() interface is meant to be flexible and will support both clock_settime() and adjtime() when adjtime() is implemented later. settimeofday() was adjusted to use the clock_settime() interface. One side note discovered during testing: uptime(1) (part of the last(1)), uses wtmp to determine boottime (not Minix's times(2)). This leads `uptime` to report odd results when you set the time to a time prior to boottime. This isn't a new bug introduced by my changes. It's been there for a while.
This commit is contained in:
parent
18ad4c0799
commit
516fec97d9
24 changed files with 179 additions and 11 deletions
|
@ -1,4 +1,4 @@
|
||||||
#define NCALLS 116 /* number of system calls allowed */
|
#define NCALLS 117 /* number of system calls allowed */
|
||||||
|
|
||||||
/* In case it isn't obvious enough: this list is sorted numerically. */
|
/* In case it isn't obvious enough: this list is sorted numerically. */
|
||||||
#define EXIT 1
|
#define EXIT 1
|
||||||
|
@ -104,6 +104,7 @@
|
||||||
#define PM_GETSID 113 /* PM getsid() */
|
#define PM_GETSID 113 /* PM getsid() */
|
||||||
#define CLOCK_GETRES 114 /* clock_getres() */
|
#define CLOCK_GETRES 114 /* clock_getres() */
|
||||||
#define CLOCK_GETTIME 115 /* clock_gettime() */
|
#define CLOCK_GETTIME 115 /* clock_gettime() */
|
||||||
|
#define CLOCK_SETTIME 116 /* clock_settime() */
|
||||||
|
|
||||||
#define TASK_REPLY 121 /* to VFS: reply code from drivers, not
|
#define TASK_REPLY 121 /* to VFS: reply code from drivers, not
|
||||||
* really a standalone call.
|
* really a standalone call.
|
||||||
|
|
|
@ -335,6 +335,7 @@
|
||||||
# define SYS_PROFBUF (KERNEL_CALL + 38) /* sys_profbuf() */
|
# define SYS_PROFBUF (KERNEL_CALL + 38) /* sys_profbuf() */
|
||||||
|
|
||||||
# define SYS_STIME (KERNEL_CALL + 39) /* sys_stime() */
|
# define SYS_STIME (KERNEL_CALL + 39) /* sys_stime() */
|
||||||
|
# define SYS_SETTIME (KERNEL_CALL + 40) /* sys_settime() */
|
||||||
|
|
||||||
# define SYS_VMCTL (KERNEL_CALL + 43) /* sys_vmctl() */
|
# define SYS_VMCTL (KERNEL_CALL + 43) /* sys_vmctl() */
|
||||||
# define SYS_SYSCTL (KERNEL_CALL + 44) /* sys_sysctl() */
|
# define SYS_SYSCTL (KERNEL_CALL + 44) /* sys_sysctl() */
|
||||||
|
@ -491,6 +492,12 @@
|
||||||
#define T_REAL_TICKS m4_l4 /* number of wall clock ticks since boottime */
|
#define T_REAL_TICKS m4_l4 /* number of wall clock ticks since boottime */
|
||||||
#define T_BOOT_TICKS m4_l5 /* number of hard clock ticks since boottime */
|
#define T_BOOT_TICKS m4_l5 /* number of hard clock ticks since boottime */
|
||||||
|
|
||||||
|
/* Field names for SYS_SETTIME. */
|
||||||
|
#define T_SETTIME_NOW m4_l2 /* non-zero for immediate, 0 for adjtime */
|
||||||
|
#define T_CLOCK_ID m4_l3 /* clock to adjust */
|
||||||
|
#define T_TIME_SEC m4_l4 /* time in seconds since 1970 */
|
||||||
|
#define T_TIME_NSEC m4_l5 /* number of nano seconds */
|
||||||
|
|
||||||
/* Field names for SYS_TRACE, SYS_PRIVCTL, SYS_STATECTL. */
|
/* Field names for SYS_TRACE, SYS_PRIVCTL, SYS_STATECTL. */
|
||||||
#define CTL_ENDPT m2_i1 /* process number of the caller */
|
#define CTL_ENDPT m2_i1 /* process number of the caller */
|
||||||
#define CTL_REQUEST m2_i2 /* server control request */
|
#define CTL_REQUEST m2_i2 /* server control request */
|
||||||
|
|
|
@ -65,6 +65,7 @@ int sys_vmctl_get_memreq(endpoint_t *who, vir_bytes *mem, vir_bytes
|
||||||
int sys_vmctl_enable_paging(void * data);
|
int sys_vmctl_enable_paging(void * data);
|
||||||
|
|
||||||
int sys_readbios(phys_bytes address, void *buf, size_t size);
|
int sys_readbios(phys_bytes address, void *buf, size_t size);
|
||||||
|
int sys_settime(int now, clockid_t clk_id, time_t sec, long nsec);
|
||||||
int sys_stime(time_t boottime);
|
int sys_stime(time_t boottime);
|
||||||
int sys_sysctl(int ctl, char *arg1, int arg2);
|
int sys_sysctl(int ctl, char *arg1, int arg2);
|
||||||
int sys_sysctl_stacktrace(endpoint_t who);
|
int sys_sysctl_stacktrace(endpoint_t who);
|
||||||
|
|
|
@ -162,10 +162,8 @@ int clock_getres(clockid_t, struct timespec *)
|
||||||
__RENAME(__clock_getres50);
|
__RENAME(__clock_getres50);
|
||||||
int clock_gettime(clockid_t, struct timespec *)
|
int clock_gettime(clockid_t, struct timespec *)
|
||||||
__RENAME(__clock_gettime50);
|
__RENAME(__clock_gettime50);
|
||||||
#ifndef __minix
|
|
||||||
int clock_settime(clockid_t, const struct timespec *)
|
int clock_settime(clockid_t, const struct timespec *)
|
||||||
__RENAME(__clock_settime50);
|
__RENAME(__clock_settime50);
|
||||||
#endif /* !__minix */
|
|
||||||
int nanosleep(const struct timespec *, struct timespec *)
|
int nanosleep(const struct timespec *, struct timespec *)
|
||||||
__RENAME(__nanosleep50);
|
__RENAME(__nanosleep50);
|
||||||
#ifndef __minix
|
#ifndef __minix
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
* loop, there are several other minor entry points:
|
* loop, there are several other minor entry points:
|
||||||
* clock_stop: called just before MINIX shutdown
|
* clock_stop: called just before MINIX shutdown
|
||||||
* get_realtime: get wall time since boot in clock ticks
|
* get_realtime: get wall time since boot in clock ticks
|
||||||
|
* set_realtime: set wall time since boot in clock ticks
|
||||||
* get_monotonic: get monotonic time since boot in clock ticks
|
* get_monotonic: get monotonic time since boot in clock ticks
|
||||||
* set_timer: set a watchdog timer (+)
|
* set_timer: set a watchdog timer (+)
|
||||||
* reset_timer: reset a watchdog timer (+)
|
* reset_timer: reset a watchdog timer (+)
|
||||||
|
@ -167,6 +168,13 @@ clock_t get_realtime(void)
|
||||||
return(realtime);
|
return(realtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* set_realtime *
|
||||||
|
*===========================================================================*/
|
||||||
|
void set_realtime(clock_t newrealtime)
|
||||||
|
{
|
||||||
|
realtime = newrealtime;
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* get_monotonic *
|
* get_monotonic *
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct timer;
|
||||||
|
|
||||||
/* clock.c */
|
/* clock.c */
|
||||||
clock_t get_realtime(void);
|
clock_t get_realtime(void);
|
||||||
|
void set_realtime(clock_t);
|
||||||
clock_t get_monotonic(void);
|
clock_t get_monotonic(void);
|
||||||
void set_timer(struct timer *tp, clock_t t, tmr_func_t f);
|
void set_timer(struct timer *tp, clock_t t, tmr_func_t f);
|
||||||
void reset_timer(struct timer *tp);
|
void reset_timer(struct timer *tp);
|
||||||
|
|
|
@ -235,6 +235,7 @@ void system_init(void)
|
||||||
map(SYS_TIMES, do_times); /* get uptime and process times */
|
map(SYS_TIMES, do_times); /* get uptime and process times */
|
||||||
map(SYS_SETALARM, do_setalarm); /* schedule a synchronous alarm */
|
map(SYS_SETALARM, do_setalarm); /* schedule a synchronous alarm */
|
||||||
map(SYS_STIME, do_stime); /* set the boottime */
|
map(SYS_STIME, do_stime); /* set the boottime */
|
||||||
|
map(SYS_SETTIME, do_settime); /* set the system time (realtime) */
|
||||||
map(SYS_VTIMER, do_vtimer); /* set or retrieve a virtual timer */
|
map(SYS_VTIMER, do_vtimer); /* set or retrieve a virtual timer */
|
||||||
|
|
||||||
/* System control. */
|
/* System control. */
|
||||||
|
|
|
@ -164,6 +164,7 @@ int do_setalarm(struct proc * caller, message *m_ptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int do_stime(struct proc * caller, message *m_ptr);
|
int do_stime(struct proc * caller, message *m_ptr);
|
||||||
|
int do_settime(struct proc * caller, message *m_ptr);
|
||||||
|
|
||||||
int do_vtimer(struct proc * caller, message *m_ptr);
|
int do_vtimer(struct proc * caller, message *m_ptr);
|
||||||
#if ! USE_VTIMER
|
#if ! USE_VTIMER
|
||||||
|
|
|
@ -13,6 +13,7 @@ SRCS+= \
|
||||||
do_times.c \
|
do_times.c \
|
||||||
do_setalarm.c \
|
do_setalarm.c \
|
||||||
do_stime.c \
|
do_stime.c \
|
||||||
|
do_settime.c \
|
||||||
do_vtimer.c \
|
do_vtimer.c \
|
||||||
do_irqctl.c \
|
do_irqctl.c \
|
||||||
do_copy.c \
|
do_copy.c \
|
||||||
|
|
43
kernel/system/do_settime.c
Normal file
43
kernel/system/do_settime.c
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* The kernel call implemented in this file:
|
||||||
|
* m_type: SYS_SETTIME
|
||||||
|
*
|
||||||
|
* The parameters for this kernel call are:
|
||||||
|
* m4_l2: T_SETTIME_NOW
|
||||||
|
* m4_l3: T_CLOCK_ID
|
||||||
|
* m4_l4: T_TIME_SEC
|
||||||
|
* m4_l5: T_TIME_NSEC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kernel/system.h"
|
||||||
|
#include <minix/endpoint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* do_settime *
|
||||||
|
*===========================================================================*/
|
||||||
|
int do_settime(struct proc * caller, message * m_ptr)
|
||||||
|
{
|
||||||
|
clock_t newclock;
|
||||||
|
time_t timediff;
|
||||||
|
|
||||||
|
if (m_ptr->T_CLOCK_ID != CLOCK_REALTIME) /* only realtime can change */
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
/* prevent a negative value for realtime */
|
||||||
|
if (m_ptr->T_TIME_SEC <= boottime) {
|
||||||
|
/* boottime was likely wrong, try to correct it. */
|
||||||
|
boottime = m_ptr->T_TIME_SEC;
|
||||||
|
set_realtime(1);
|
||||||
|
return(OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate the new value of realtime in ticks */
|
||||||
|
timediff = m_ptr->T_TIME_SEC - boottime;
|
||||||
|
newclock = (timediff*system_hz) + (m_ptr->T_TIME_NSEC/(1000000000/system_hz));
|
||||||
|
|
||||||
|
if (m_ptr->T_SETTIME_NOW) {
|
||||||
|
set_realtime(newclock);
|
||||||
|
} /* else used adjtime() method (to be implemented) */
|
||||||
|
|
||||||
|
return(OK);
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ adjtime
|
||||||
lchmod
|
lchmod
|
||||||
lchown
|
lchown
|
||||||
clone
|
clone
|
||||||
clock_settime
|
|
||||||
extattr_*
|
extattr_*
|
||||||
fhopen
|
fhopen
|
||||||
fhstat
|
fhstat
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
SRCS+= accept.c access.c bind.c brk.c sbrk.c m_closefrom.c getsid.c \
|
SRCS+= accept.c access.c bind.c brk.c sbrk.c m_closefrom.c getsid.c \
|
||||||
chdir.c chmod.c fchmod.c chown.c fchown.c chroot.c close.c \
|
chdir.c chmod.c fchmod.c chown.c fchown.c chroot.c close.c \
|
||||||
clock_getres.c clock_gettime.c \
|
clock_getres.c clock_gettime.c clock_settime.c \
|
||||||
connect.c dup.c dup2.c execve.c fcntl.c flock.c fpathconf.c fork.c \
|
connect.c dup.c dup2.c execve.c fcntl.c flock.c fpathconf.c fork.c \
|
||||||
fstatfs.c fstatvfs.c fsync.c ftruncate.c getdents.c getegid.c getgid.c \
|
fstatfs.c fstatvfs.c fsync.c ftruncate.c getdents.c getegid.c getgid.c \
|
||||||
getgroups.c getitimer.c setitimer.c __getlogin.c getpeername.c \
|
getgroups.c getitimer.c setitimer.c __getlogin.c getpeername.c \
|
||||||
|
|
|
@ -12,7 +12,7 @@ int clock_getres(clockid_t clock_id, struct timespec *res)
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
|
||||||
m.m2_l1 = (clockid_t) clock_id;
|
m.m2_i1 = (clockid_t) clock_id;
|
||||||
|
|
||||||
if (_syscall(PM_PROC_NR, CLOCK_GETRES, &m) < 0)
|
if (_syscall(PM_PROC_NR, CLOCK_GETRES, &m) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -12,7 +12,7 @@ int clock_gettime(clockid_t clock_id, struct timespec *res)
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
|
||||||
m.m2_l1 = (clockid_t) clock_id;
|
m.m2_i1 = (clockid_t) clock_id;
|
||||||
|
|
||||||
if (_syscall(PM_PROC_NR, CLOCK_GETTIME, &m) < 0)
|
if (_syscall(PM_PROC_NR, CLOCK_GETTIME, &m) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
24
lib/libc/sys-minix/clock_settime.c
Normal file
24
lib/libc/sys-minix/clock_settime.c
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include "namespace.h"
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifdef __weak_alias
|
||||||
|
__weak_alias(clock_settime, __clock_settime50);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int clock_settime(clockid_t clock_id, const struct timespec *ts)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
|
||||||
|
m.m2_i1 = (clockid_t) clock_id;
|
||||||
|
m.m2_l1 = (time_t) ts->tv_sec;
|
||||||
|
m.m2_l2 = (long) ts->tv_nsec;
|
||||||
|
|
||||||
|
if (_syscall(PM_PROC_NR, CLOCK_SETTIME, &m) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
|
|
||||||
int settimeofday(const struct timeval *tp, const void *tzp)
|
int settimeofday(const struct timeval *tp, const void *tzp)
|
||||||
{
|
{
|
||||||
/* Use intermediate variable because stime param is not const */
|
struct timespec ts;
|
||||||
time_t sec = tp->tv_sec;
|
|
||||||
|
ts.tv_sec = tp->tv_sec;
|
||||||
|
ts.tv_nsec = tp->tv_usec * 1000;
|
||||||
|
|
||||||
/* Ignore time zones */
|
/* Ignore time zones */
|
||||||
return stime(&sec);
|
return clock_settime(CLOCK_REALTIME, &ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__minix) && defined(__weak_alias)
|
#if defined(__minix) && defined(__weak_alias)
|
||||||
|
|
|
@ -59,6 +59,7 @@ SRCS+= \
|
||||||
sys_schedule.c \
|
sys_schedule.c \
|
||||||
sys_setalarm.c \
|
sys_setalarm.c \
|
||||||
sys_setgrant.c \
|
sys_setgrant.c \
|
||||||
|
sys_settime.c \
|
||||||
sys_sigreturn.c \
|
sys_sigreturn.c \
|
||||||
sys_sigsend.c \
|
sys_sigsend.c \
|
||||||
sys_sprof.c \
|
sys_sprof.c \
|
||||||
|
|
20
lib/libsys/sys_settime.c
Normal file
20
lib/libsys/sys_settime.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "syslib.h"
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
int sys_settime(now, clk_id, sec, nsec)
|
||||||
|
int now;
|
||||||
|
clockid_t clk_id;
|
||||||
|
time_t sec;
|
||||||
|
long nsec;
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
m.T_SETTIME_NOW = now;
|
||||||
|
m.T_CLOCK_ID = clk_id;
|
||||||
|
m.T_TIME_SEC = sec;
|
||||||
|
m.T_TIME_NSEC = nsec;
|
||||||
|
|
||||||
|
r = _kernel_call(SYS_SETTIME, &m);
|
||||||
|
return(r);
|
||||||
|
}
|
|
@ -30,7 +30,9 @@
|
||||||
#define svrctl_req m2_i1
|
#define svrctl_req m2_i1
|
||||||
#define svrctl_argp m2_p1
|
#define svrctl_argp m2_p1
|
||||||
#define stime m2_l1
|
#define stime m2_l1
|
||||||
#define clk_id m2_l1
|
#define clk_id m2_i1
|
||||||
|
#define time_sec m2_l1
|
||||||
|
#define time_nsec m2_l2
|
||||||
#define memsize m4_l1
|
#define memsize m4_l1
|
||||||
#define membase m4_l2
|
#define membase m4_l2
|
||||||
#define sysuname_req m1_i1
|
#define sysuname_req m1_i1
|
||||||
|
|
|
@ -88,6 +88,7 @@ int do_time(void);
|
||||||
int do_times(void);
|
int do_times(void);
|
||||||
int do_getres(void);
|
int do_getres(void);
|
||||||
int do_gettime(void);
|
int do_gettime(void);
|
||||||
|
int do_settime(void);
|
||||||
|
|
||||||
/* trace.c */
|
/* trace.c */
|
||||||
int do_trace(void);
|
int do_trace(void);
|
||||||
|
|
|
@ -127,6 +127,7 @@ int (*call_vec[])(void) = {
|
||||||
do_get, /* 113 = getsid */
|
do_get, /* 113 = getsid */
|
||||||
do_getres, /* 114 = clock_getres */
|
do_getres, /* 114 = clock_getres */
|
||||||
do_gettime, /* 115 = clock_gettime */
|
do_gettime, /* 115 = clock_gettime */
|
||||||
|
do_settime, /* 116 = clock_settime */
|
||||||
};
|
};
|
||||||
/* This should not fail with "array size is negative": */
|
/* This should not fail with "array size is negative": */
|
||||||
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];
|
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* The entry points into this file are
|
* The entry points into this file are
|
||||||
* do_getres: perform the CLOCK_GETRES system call
|
* do_getres: perform the CLOCK_GETRES system call
|
||||||
* do_gettime: perform the CLOCK_GETTIME system call
|
* do_gettime: perform the CLOCK_GETTIME system call
|
||||||
|
* do_settime: perform the CLOCK_SETTIME system call
|
||||||
* do_time: perform the TIME system call
|
* do_time: perform the TIME system call
|
||||||
* do_stime: perform the STIME system call
|
* do_stime: perform the STIME system call
|
||||||
* do_times: perform the TIMES system call
|
* do_times: perform the TIMES system call
|
||||||
|
@ -62,6 +63,27 @@ int do_getres()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* do_settime *
|
||||||
|
*===========================================================================*/
|
||||||
|
int do_settime()
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
|
||||||
|
if (mp->mp_effuid != SUPER_USER) {
|
||||||
|
return(EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_in.clk_id) {
|
||||||
|
case CLOCK_REALTIME:
|
||||||
|
s= sys_settime(1, m_in.clk_id, m_in.time_sec, m_in.time_nsec);
|
||||||
|
return(s);
|
||||||
|
case CLOCK_MONOTONIC: /* monotonic cannot be changed */
|
||||||
|
default:
|
||||||
|
return EINVAL; /* invalid/unsupported clock_id */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_time *
|
* do_time *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
|
|
@ -131,6 +131,7 @@ int (*call_vec[])(void) = {
|
||||||
no_sys, /* 113 = (getsid) */
|
no_sys, /* 113 = (getsid) */
|
||||||
no_sys, /* 114 = (clock_getres) */
|
no_sys, /* 114 = (clock_getres) */
|
||||||
no_sys, /* 115 = (clock_gettime) */
|
no_sys, /* 115 = (clock_gettime) */
|
||||||
|
no_sys, /* 116 = (clock_settime) */
|
||||||
};
|
};
|
||||||
/* This should not fail with "array size is negative": */
|
/* This should not fail with "array size is negative": */
|
||||||
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];
|
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];
|
||||||
|
|
|
@ -20,6 +20,7 @@ int main(void);
|
||||||
void quit(void);
|
void quit(void);
|
||||||
static void test_clock_getres();
|
static void test_clock_getres();
|
||||||
static void test_clock_gettime();
|
static void test_clock_gettime();
|
||||||
|
static void test_clock_settime();
|
||||||
static void show_timespec(char *msg, struct timespec *ts);
|
static void show_timespec(char *msg, struct timespec *ts);
|
||||||
|
|
||||||
static void test_clock_getres()
|
static void test_clock_getres()
|
||||||
|
@ -63,6 +64,37 @@ static void test_clock_gettime()
|
||||||
if (clock_gettime(-1, &ts) == 0) e(31);
|
if (clock_gettime(-1, &ts) == 0) e(31);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_clock_settime(void)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
struct timespec ts2;
|
||||||
|
|
||||||
|
/* shouldn't be able to set MONOTONIC */
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) e(50);
|
||||||
|
if (clock_settime(CLOCK_MONOTONIC, &ts) == 0) e(51);
|
||||||
|
if (errno != EINVAL) e(52); /* reponse should be EINVAL */
|
||||||
|
|
||||||
|
/* set the time of REALTIME to that of MONOTONIC */
|
||||||
|
if (clock_settime(CLOCK_REALTIME, &ts) == -1) e(53);
|
||||||
|
|
||||||
|
ts.tv_sec += 600; /* time travel 10 minutes into the future */
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, &ts2) == -1) e(54);
|
||||||
|
if (clock_settime(CLOCK_REALTIME, &ts) == -1) e(55);
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) e(56);
|
||||||
|
|
||||||
|
/* get the value we set, if it's not about 10 minutes ahead, it failed */
|
||||||
|
if (ts.tv_sec - ts2.tv_sec < 500 ||
|
||||||
|
ts.tv_sec - ts2.tv_sec > 700) e(57);
|
||||||
|
|
||||||
|
/* back to current time - don't leave the system time 10 ahead */
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) e(58);
|
||||||
|
ts.tv_sec -= 600;
|
||||||
|
if (clock_settime(CLOCK_REALTIME, &ts) == -1) e(59);
|
||||||
|
|
||||||
|
/* Test with an invalid clock */
|
||||||
|
if (clock_settime(-1, &ts) == 0) e(60);
|
||||||
|
}
|
||||||
|
|
||||||
static void show_timespec(char *msg, struct timespec *ts)
|
static void show_timespec(char *msg, struct timespec *ts)
|
||||||
{
|
{
|
||||||
#if DEBUG == 1
|
#if DEBUG == 1
|
||||||
|
@ -80,6 +112,7 @@ int main()
|
||||||
|
|
||||||
test_clock_getres();
|
test_clock_getres();
|
||||||
test_clock_gettime();
|
test_clock_gettime();
|
||||||
|
test_clock_settime();
|
||||||
|
|
||||||
/* get test end time */
|
/* get test end time */
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &endtime) == -1) e(2);
|
if (clock_gettime(CLOCK_MONOTONIC, &endtime) == -1) e(2);
|
||||||
|
|
Loading…
Reference in a new issue