On Fri, Jul 30, 2021 at 09:41:38AM -0500, Scott Cheloha wrote: > Hi, > > The Description section in this page has always bugged me. The author > chose to save space by merging the description of two different system > calls into a single paragraph. Then the rules and caveats for > settimeofday() are off in a separate paragraph. Meh. > > I recently revised the clock_gettime.2 page and I have bits I want to > crib from there to improve this page. Then there are other things on > the page that nag at me. > > Anyway, here are the changes by section. Any questions or > uncertainties I have are appended after the list in each section. >
reads fine to me. jmc > NAME > > - Explicitly note that this is the UTC time. > > I like the sound of "get or set the time of day" better, but the > phrase "time of day" feels a little imprecise. Unsure. > > SYNOPSIS > > - I think the variable name "tp" is mediocre. Change "tp" to "now", > just like we did in clock_gettime.2. "now" helps reinforce what the > variable represents. > > - While here change "tzp" to "tz". If we have no "tp" we don't need > the trailing 'p' for consistency. > > DESCRIPTION > > - Talk about gettimeofday() first, in its own paragraph. It is the most > important interface here and belongs right at the top. > > - Then describe the UTC clock itself. Call it "UTC," not "Greenwich > time". Describe how the clock behaves, too. > > I think a discussion of the granularity of the clock is outside the > scope of this page. Tick-based timecounters (i.e., those that are > only advanced during the clock interrupt) are exceedingly rare. The > time is almost always kept by a dedicated hardware counter. > > Explicitly discourage people from using gettimeofday() to measure > elapsed time. Point them to clock_gettime(2). > > - Then talk about settimeofday(). Merge the settimeofday() paragraph > with the paragraph describing its rules and caveats. > > I don't think we need to mention that adjtime(2) can still slow the > effective clock frequency when securelevel >= 2. The adjustment is > capped at 5000ppm, which hardly cripples the system. You can do way, > way more damage with the newer adjfreq(2) call, anyway, and I don't > want to mention both. > > I *do* think we ought to mention that settimeofday(2) cancels > whatever adjtime(2) was doing. That is a side effect of the call > and we need to mention it explicitly. > > - Update the timeval structure description to match the current code > in sys/time.h > > - Last and very much least, the historical timezone parameter. > > Clarify that we no longer keep timezone information in the > kernel, not that we just don't track it at all. > > Use active voice when describing the consequences when tz is not > NULL. > > I am a little uncertain about telling the reader not to use > gettimeofday() to measure time right in the middle of the Description. > That said, it's an extremely common mistake, and I don't think it > should be appended in Caveats. > > Thoughts? > > SEE ALSO > > - Reference timeradd(3). We're working with timevals on this page. > > ERRORS > > - Simplify leading sentences. > > - Use more active voice. > > - Strictly speaking, you don't need to try to set the time to get > EPERM. Any unprivileged process gets EPERM when it calls > settimeofday(), even if the first argument is NULL. More accurate to > say that the caller wasn't root, not what the caller tried to do. > > - Document the securelevel(7) EPERM error. > > Should we document the other error, the UINT_MAX seconds cap? See > settime() in sys/kern/kern_time.c. I'm leaning towards "no". > > STANDARDS > > - settimeofday() has never been standardized, but it's available > everywhere. I think we should note this. It's not unique to > us, or even to BSD. Linux, Solaris, AIX, whatever, they all > have it. > > HISTORY > > I want to rework the first sentence here but I'm stumped at the > moment. I'll circle back to it. > > CAVEATS > > Should this warning be here? Isn't this more relevant to a system > administrator in the date(1) page? > > It feels out of scope for a system call manpage to be making > recommendations about rebooting the system after you use it. A system > administrator doesn't use the settimeofday(2) system call directly, > nor are they necessarily even aware of the underlying system call at > all. They use a tool like date(1) to set the clock. > > Thoughts? > > -- > > Index: gettimeofday.2 > =================================================================== > RCS file: /cvs/src/lib/libc/sys/gettimeofday.2,v > retrieving revision 1.31 > diff -u -p -r1.31 gettimeofday.2 > --- gettimeofday.2 4 Sep 2019 14:27:55 -0000 1.31 > +++ gettimeofday.2 30 Jul 2021 14:37:46 -0000 > @@ -35,97 +35,121 @@ > .Sh NAME > .Nm gettimeofday , > .Nm settimeofday > -.Nd get/set date and time > +.Nd get or set the UTC time > .Sh SYNOPSIS > .In sys/time.h > .Ft int > -.Fn gettimeofday "struct timeval *tp" "struct timezone *tzp" > +.Fn gettimeofday "struct timeval *now" "struct timezone *tz" > .Ft int > -.Fn settimeofday "const struct timeval *tp" "const struct timezone *tzp" > +.Fn settimeofday "const struct timeval *now" "const struct timezone *tz" > .Sh DESCRIPTION > -The system's notion of the current Greenwich time is obtained with the > +The > +.Fn gettimeofday > +function writes the absolute value of the system's Coordinated Universal Time > +.Pq UTC > +clock to > +.Fa now > +unless > +.Fa now > +is > +.Dv NULL . > +.Pp > +The UTC clock's absolute value is the time elapsed since > +Jan 1 1970 00:00:00 +0000 > +.Pq the Epoch . > +The clock normally advances continuously, > +though it may jump discontinuously if a process calls > +.Fn settimeofday > +or > +.Xr clock_settime 2 . > +For this reason, > .Fn gettimeofday > -call and set with the > +is not generally suitable for measuring elapsed time. > +Whenever possible, > +use > +.Xr clock_gettime 2 > +to measure elapsed time with one of the system's monotonic clocks instead. > +.Pp > +The > .Fn settimeofday > -call. > -The time is expressed in seconds and microseconds > -since midnight (0 hour), January 1, 1970. > -The resolution of the system clock is hardware dependent, and the time > -may be updated continuously or in > -.Dq ticks . > -If > -.Fa tp > +function sets the system's UTC clock to the absolute value > +.Fa now > +unless > +.Fa now > is > -.Dv NULL , > -the time will not be returned or set. > +.Dv NULL . > +Only the superuser may set the clock. > +If the system > +.Xr securelevel 7 > +is 2 or greater the clock may only be advanced. > +This limitation is imposed to prevent a malicious superuser > +from setting arbitrary timestamps on files. > +Setting the clock cancels any ongoing > +.Xr adjtime 2 > +adjustment. > +.Pp > The structure pointed to by > -.Fa tp > +.Fa now > is defined in > .In sys/time.h > as: > .Bd -literal > struct timeval { > - time_t tv_sec; /* seconds since Jan. 1, 1970 */ > + time_t tv_sec; /* seconds */ > suseconds_t tv_usec; /* and microseconds */ > }; > .Ed > .Pp > The > -.Fa tzp > -parameter is historical and timezone information is no longer > -tracked by the system. > -All code should pass > -.Dv NULL > -for > -.Fa tzp . > -For > -.Fn gettimeofday , > -if > -.Fa tzp > -is > -.Pf non- Dv NULL > -an empty > -.Dv timezone > -structure will be returned. > -For > -.Fn settimeofday , > -if > -.Fa tzp > -is > -.Pf non- Dv NULL > -its contents are ignored. > -.Pp > -Only the superuser may set the time of day. > -If the system securelevel is greater than 1 (see > -.Xr init 8 ) , > -the time may only be advanced. > -This limitation is imposed to prevent a malicious superuser > -from setting arbitrary time stamps on files. > -The system time can still be adjusted backwards using the > -.Xr adjtime 2 > -system call even when the system is secure. > +.Fa tz > +argument is historical: > +the system no longer maintains timezone information in the kernel. > +The > +.Fa tz > +argument should always be > +.Dv NULL . > +.Fn gettimeofday > +zeroes > +.Fa tz > +if it is not > +.Dv NULL . > +.Fn settimeofday > +ignores the contents of > +.Fa tz > +if it is not > +.Dv NULL . > .Sh RETURN VALUES > .Rv -std > .Sh ERRORS > .Fn gettimeofday > and > .Fn settimeofday > -will succeed unless: > +will fail if: > .Bl -tag -width Er > .It Bq Er EFAULT > -An argument address referenced invalid memory. > +.Fa now > +or > +.Fa tz > +are not > +.Dv NULL > +and reference invalid memory. > .El > .Pp > -In addition, > .Fn settimeofday > -may return the following errors: > +will also fail if: > .Bl -tag -width Er > .It Bq Er EINVAL > -.Fa tp > -specified a microsecond value less than zero or greater than or equal to > -1 million. > +.Fa now > +specifies a microsecond value less than zero or greater than or equal to > +one million. > +.It Bq Er EPERM > +The caller is not the superuser. > .It Bq Er EPERM > -A user other than the superuser attempted to set the time. > +The system > +.Xr securelevel 7 > +is 2 or greater and > +.Fa now > +specifies a time in the past. > .El > .Sh SEE ALSO > .Xr date 1 , > @@ -133,14 +157,21 @@ A user other than the superuser attempte > .Xr clock_gettime 2 , > .Xr getitimer 2 , > .Xr ctime 3 , > -.Xr time 3 > +.Xr time 3 , > +.Xr timeradd 3 > .Sh STANDARDS > The > .Fn gettimeofday > function conforms to > .St -p1003.1-2008 . > +.Pp > +The > +.Fn settimeofday > +function is non-standard, > +though many systems offer it. > .Sh HISTORY > -As predecessors of these functions, former system calls > +As predecessors of these functions, > +former system calls > .Fn time > and > .Fn stime >