xref: /minix/minix/kernel/system/do_settime.c (revision 83133719)
1 /* The kernel call implemented in this file:
2  *   m_type:	SYS_SETTIME
3  *
4  * The parameters for this kernel call are:
5  *   m_lsys_krn_sys_settime.now
6  *   m_lsys_krn_sys_settime.clock_id
7  *   m_lsys_krn_sys_settime.sec
8  *   m_lsys_krn_sys_settime.nsec
9  */
10 
11 #include "kernel/system.h"
12 #include <minix/endpoint.h>
13 #include <time.h>
14 
15 /*===========================================================================*
16  *				do_settime				     *
17  *===========================================================================*/
18 int do_settime(struct proc * caller, message * m_ptr)
19 {
20   clock_t newclock;
21   int32_t ticks;
22   time_t timediff, timediff_ticks;
23 
24   if (m_ptr->m_lsys_krn_sys_settime.clock_id != CLOCK_REALTIME) /* only realtime can change */
25 	return EINVAL;
26 
27   if (m_ptr->m_lsys_krn_sys_settime.now == 0) { /* user just wants to adjtime() */
28 	/* convert delta value from seconds and nseconds to ticks */
29 	ticks = (m_ptr->m_lsys_krn_sys_settime.sec * system_hz) +
30 			(m_ptr->m_lsys_krn_sys_settime.nsec/(1000000000/system_hz));
31 	set_adjtime_delta(ticks);
32 	return(OK);
33   } /* else user wants to set the time */
34 
35   timediff = m_ptr->m_lsys_krn_sys_settime.sec - boottime;
36   timediff_ticks = timediff * system_hz;
37 
38   /* prevent a negative value for realtime */
39   if (m_ptr->m_lsys_krn_sys_settime.sec <= boottime ||
40       timediff_ticks < LONG_MIN/2 || timediff_ticks > LONG_MAX/2) {
41   	/* boottime was likely wrong, try to correct it. */
42 	boottime = m_ptr->m_lsys_krn_sys_settime.sec;
43 	set_realtime(1);
44 	return(OK);
45   }
46 
47   /* calculate the new value of realtime in ticks */
48   newclock = timediff_ticks +
49       (m_ptr->m_lsys_krn_sys_settime.nsec/(1000000000/system_hz));
50 
51   set_realtime(newclock);
52 
53   return(OK);
54 }
55