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