1/* 2 * Copyright (C) 1993 by Andrew A. Chernov, Moscow, Russia. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 145 unchanged lines hidden (view full) --- 154 mib[0] = CTL_MACHDEP; 155 mib[1] = CPU_ADJKERNTZ; 156 len = sizeof(kern_offset); 157 if (sysctl(mib, 2, &kern_offset, &len, NULL, 0) == -1) { 158 syslog(LOG_ERR, "sysctl(get_offset): %m"); 159 return 1; 160 } 161 |
162 stv = NULL; 163 stz = NULL; 164 |
165 /* correct the kerneltime for this diffs */ 166 /* subtract kernel offset, if present, old offset too */ 167 168 diff = offset - tz.tz_minuteswest * 60 - kern_offset; 169 170 if (diff != 0) { 171 172 /* Yet one step for final time */ --- 27 unchanged lines hidden (view full) --- 200 201 diff = offset - tz.tz_minuteswest * 60 - kern_offset; 202 203 if (diff != 0) { 204 tv.tv_sec += diff; 205 tv.tv_usec = 0; /* we are restarting here... */ 206 stv = &tv; 207 } |
208 } |
209 210 if (tz.tz_dsttime != 0 || tz.tz_minuteswest != 0) { 211 tz.tz_dsttime = tz.tz_minuteswest = 0; /* zone info is garbage */ 212 stz = &tz; 213 } |
214 |
215 /* if init, don't touch RTC at all */ 216 if (init) { 217 mib[0] = CTL_MACHDEP; 218 mib[1] = CPU_DISRTCSET; 219 len = sizeof(disrtcset); 220 if (sysctl(mib, 2, &disrtcset, &len, NULL, 0) == -1) { 221 syslog(LOG_ERR, "sysctl(get_disrtcset): %m"); 222 return 1; 223 } 224 if (disrtcset == 0) { 225 disrtcset = 1; 226 need_restore = 1; 227 if (sysctl(mib, 2, NULL, NULL, &disrtcset, len) == -1) { 228 syslog(LOG_ERR, "sysctl(set_disrtcset): %m"); |
229 return 1; 230 } |
231 } |
232 } 233 |
234 if (( (init && (stv != NULL || stz != NULL)) 235 || (stz != NULL && stv == NULL) 236 ) 237 && settimeofday(stv, stz) 238 ) { 239 syslog(LOG_ERR, "settimeofday: %m"); 240 return 1; 241 } 242 243 /* init: don't write RTC, !init: write RTC */ |
244 if (kern_offset != offset) { 245 kern_offset = offset; 246 mib[0] = CTL_MACHDEP; 247 mib[1] = CPU_ADJKERNTZ; 248 len = sizeof(kern_offset); 249 if (sysctl(mib, 2, NULL, NULL, &kern_offset, len) == -1) { 250 syslog(LOG_ERR, "sysctl(update_offset): %m"); 251 return 1; 252 } 253 } 254 255 if (need_restore) { 256 need_restore = 0; 257 disrtcset = 0; |
258 len = sizeof(disrtcset); |
259 if (sysctl(mib, 2, NULL, NULL, &disrtcset, len) == -1) { 260 syslog(LOG_ERR, "sysctl(restore_disrtcset): %m"); 261 return 1; 262 } 263 } 264 265/****** End of critical section ******/ 266 267 if (init) { 268 init = 0; 269 /* wait for signals and acts like -a */ 270 (void) sigsuspend(&emask); 271 goto again; 272 } 273 274 return 0; 275} |