Date: Mon, 15 Mar 1999 23:57:10 -0500 (EST) From: Brian Haug <haug@hawaii.conterra.com> To: FreeBSD-gnats-submit@freebsd.org Subject: kern/10609: adjtime bug (tv_sec >2147 ) and enhancement (nil first arg) Message-ID: <199903160457.XAA05229@hawaii.conterra.com>
next in thread | raw e-mail | index | archive | help
>Number: 10609 >Category: kern >Synopsis: adjtime bug (tv_sec > 2147) and enhancement (nil first arg) >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Mar 15 21:00:00 PST 1999 >Closed-Date: >Last-Modified: >Originator: Brian Haug >Release: FreeBSD 3.1-RELEASE i386 (?? send-pr from different system) >Organization: None >Environment: probably any system with adjtime system call >Description: 1. Bug: adjtime can not handle adjustments whos absolute value exceeds 2148 (or stricly exceeds 2147) 2. Change request: adjtime does not accept a nil first argument to allow the application to determine the current delta being applied to the clock. 3. Documentation doesn't note the first issue (code fix attached). >How-To-Repeat: use "date -a 2148" (code in follow on report) or examine the code. Note that 2147 seconds (expressed as microseconds) is real close to MAXINT, and 2148 seconds would exceed this. Call adjtime with the value NULL for the first argument, note that the system call will fail. >Fix: Hopefully the code diffs are all correct. I've used BRH_ to diferentiate the two fixes, and would actually suggest not using the ifdefs. The two problems are somewhat intertwined, so I appologize for tying them together. The man page only attempts to dealwith the NIL first argument issue since the other problem is now fixed in the kernel. *** /usr/src/sys/kern/kern_time.c.old Sun Oct 25 10:44:51 1998 --- /usr/src/sys/kern/kern_time.c Sun Mar 14 08:02:31 1999 *************** *** 322,328 **** --- 322,332 ---- } int tickdelta; /* current clock skew, us. per tick */ + #ifdef BRH_ADJTIME_BIG + long long timedelta; /* unapplied time correction, us. */ + #else long timedelta; /* unapplied time correction, us. */ + #endif static long bigadj = 1000000; /* use 10x skew above bigadj us. */ #ifndef _SYS_SYSPROTO_H_ *************** *** 338,351 **** --- 342,370 ---- register struct adjtime_args *uap; { struct timeval atv; + #ifdef BRH_ADJTIME_BIG + long long ndelta, odelta; + register long ntickdelta; + #else register long ndelta, ntickdelta, odelta; + #endif int s, error; + #ifdef BRH_ADJTIME_NULL + int for_real; + #endif if ((error = suser(p->p_ucred, &p->p_acflag))) return (error); + #ifndef BRH_ADJTIME_NULL if ((error = copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval)))) return (error); + #else + for_real = (caddr_t)NULL != (caddr_t)uap->delta; + if (for_real && (error = + copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval)))) + return (error); + #endif /* * Compute the total correction and the rate at which to apply it. *************** *** 354,360 **** --- 373,386 ---- * hardclock(), tickdelta will become zero, lest the correction * overshoot and start taking us away from the desired final time. */ + #ifdef BRH_ADJTIME_NULL + if (for_real) { + #endif + #ifdef BRH_ADJTIME_BIG + ndelta = (long long)atv.tv_sec * 1000000 + atv.tv_usec; + #else ndelta = atv.tv_sec * 1000000 + atv.tv_usec; + #endif if (ndelta > bigadj || ndelta < -bigadj) ntickdelta = 10 * tickadj; else *************** *** 369,378 **** --- 395,413 ---- */ if (ndelta < 0) ntickdelta = -ntickdelta; + #ifdef BRH_ADJTIME_NULL + } + #endif s = splclock(); odelta = timedelta; + #ifdef BRH_ADJTIME_NULL + if (for_real) { + #endif timedelta = ndelta; tickdelta = ntickdelta; + #ifdef BRH_ADJTIME_NULL + } + #endif splx(s); if (uap->olddelta) { *** /usr/src/sys/sys/kernel.h.old Sun Mar 14 07:56:11 1999 --- /usr/src/sys/sys/kernel.h Sun Mar 14 07:57:04 1999 *************** *** 73,79 **** --- 73,83 ---- extern int ticks; extern int lbolt; /* once a second sleep address */ extern int tickdelta; + #ifdef BRH_ADJTIME_BIG + extern long long timedelta; + #else extern long timedelta; + #endif #endif /* KERNEL */ *** /usr/src/lib/libc/sys/adjtime.2.old Sun Mar 14 08:08:37 1999 --- /usr/src/lib/libc/sys/adjtime.2 Sun Mar 14 08:14:13 1999 *************** *** 66,71 **** --- 66,76 ---- .Fn adjtime is called again. If + .Fa delta + is nil, then no changes are made to the clock. + This is useful when one wants to determine the amount of adjustment which + is yet to be performed. + If .Fa olddelta is non-nil, the structure pointed to will contain, upon return, the >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199903160457.XAA05229>