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
> 

Reply via email to