1 /* This file takes care of those system calls that deal with time. 2 * 3 * The entry points into this file are 4 * do_getres: perform the CLOCK_GETRES system call 5 * do_gettime: perform the CLOCK_GETTIME system call 6 * do_settime: perform the CLOCK_SETTIME system call 7 * do_time: perform the GETTIMEOFDAY system call 8 * do_stime: perform the STIME system call 9 */ 10 11 #include "pm.h" 12 #include <minix/callnr.h> 13 #include <minix/com.h> 14 #include <signal.h> 15 #include <sys/time.h> 16 #include "mproc.h" 17 18 /*===========================================================================* 19 * do_gettime * 20 *===========================================================================*/ 21 int do_gettime() 22 { 23 clock_t ticks, realtime, clock; 24 time_t boottime; 25 int s; 26 27 if ( (s=getuptime(&ticks, &realtime, &boottime)) != OK) 28 panic("do_time couldn't get uptime: %d", s); 29 30 switch (m_in.m_lc_pm_time.clk_id) { 31 case CLOCK_REALTIME: 32 clock = realtime; 33 break; 34 case CLOCK_MONOTONIC: 35 clock = ticks; 36 break; 37 default: 38 return EINVAL; /* invalid/unsupported clock_id */ 39 } 40 41 mp->mp_reply.m_pm_lc_time.sec = boottime + (clock / system_hz); 42 mp->mp_reply.m_pm_lc_time.nsec = 43 (uint32_t) ((clock % system_hz) * 1000000000ULL / system_hz); 44 45 return(OK); 46 } 47 48 /*===========================================================================* 49 * do_getres * 50 *===========================================================================*/ 51 int do_getres() 52 { 53 switch (m_in.m_lc_pm_time.clk_id) { 54 case CLOCK_REALTIME: 55 case CLOCK_MONOTONIC: 56 /* tv_sec is always 0 since system_hz is an int */ 57 mp->mp_reply.m_pm_lc_time.sec = 0; 58 mp->mp_reply.m_pm_lc_time.nsec = 1000000000 / system_hz; 59 return(OK); 60 default: 61 return EINVAL; /* invalid/unsupported clock_id */ 62 } 63 } 64 65 /*===========================================================================* 66 * do_settime * 67 *===========================================================================*/ 68 int do_settime() 69 { 70 int s; 71 72 if (mp->mp_effuid != SUPER_USER) { 73 return(EPERM); 74 } 75 76 switch (m_in.m_lc_pm_time.clk_id) { 77 case CLOCK_REALTIME: 78 s = sys_settime(m_in.m_lc_pm_time.now, m_in.m_lc_pm_time.clk_id, 79 m_in.m_lc_pm_time.sec, m_in.m_lc_pm_time.nsec); 80 return(s); 81 case CLOCK_MONOTONIC: /* monotonic cannot be changed */ 82 default: 83 return EINVAL; /* invalid/unsupported clock_id */ 84 } 85 } 86 87 /*===========================================================================* 88 * do_time * 89 *===========================================================================*/ 90 int do_time() 91 { 92 /* Perform the time(tp) system call. This returns the time in seconds since 93 * 1.1.1970. MINIX is an astrophysically naive system that assumes the earth 94 * rotates at a constant rate and that such things as leap seconds do not 95 * exist. 96 */ 97 clock_t ticks, realtime; 98 time_t boottime; 99 int s; 100 101 if ( (s=getuptime(&ticks, &realtime, &boottime)) != OK) 102 panic("do_time couldn't get uptime: %d", s); 103 104 mp->mp_reply.m_pm_lc_time.sec = boottime + (realtime / system_hz); 105 mp->mp_reply.m_pm_lc_time.nsec = 106 (uint32_t) ((realtime % system_hz) * 1000000000ULL / system_hz); 107 return(OK); 108 } 109 110 /*===========================================================================* 111 * do_stime * 112 *===========================================================================*/ 113 int do_stime() 114 { 115 /* Perform the stime(tp) system call. Retrieve the system's uptime (ticks 116 * since boot) and pass the new time in seconds at system boot to the kernel. 117 */ 118 clock_t uptime, realtime; 119 time_t boottime; 120 int s; 121 122 if (mp->mp_effuid != SUPER_USER) { 123 return(EPERM); 124 } 125 if ( (s=getuptime(&uptime, &realtime, &boottime)) != OK) 126 panic("do_stime couldn't get uptime: %d", s); 127 boottime = m_in.m_lc_pm_time.sec - (realtime/system_hz); 128 129 s= sys_stime(boottime); /* Tell kernel about boottime */ 130 if (s != OK) 131 panic("pm: sys_stime failed: %d", s); 132 133 return(OK); 134 } 135