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. 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