On Sat, Jul 24, 2021 at 10:39:49PM -0500, Scott Cheloha wrote:
> Okay, the nanosleep.2 changes are committed, let's do sleep.3 next.
>
> Here's a changelist by section. I have some questions in there at end
> of sections where I'm unsure about something.
>
> NAME
>
> - This is clunky. Tighten it up.
>
> - It's also wrong. Remove reference to the process: sleep suspends
> the calling thread.
>
> DESCRIPTION
>
> - Again, it suspends the thread, not the process.
>
> - If we borrow language/style from nanosleep.2 we can condense this
> first paragraph into a single sentence.
>
> - In the second paragraph I don't think we need to talk about SIGALRM
> explicitly. It isn't relevant to our implementation.
>
> I think such comments belong in the Standards section. See below.
>
> - Probably worth mentioning the sole implication of an implementation
> based on nanosleep(2) here instead of telling the reader to schlep
> off to that page to get the details there.
>
> I'm not positive about cutting the discussion of timers and SIGALARM
> here. My thinking is: here in 2021, the fact that our sleep() doesn't
> touch the process timer or the signal mask doesn't seem significant
> enough to warrant inclusion. I wonder if this detail confuses some
> readers ("why are they bringing this up?").
>
> RETURN VALUES
>
> - Tighten this up.
>
> - Prefer a literal "0" for an integral return value.
>
> Should we mention that sleep(3) can set errno?
>
> If so, do we need to mention how to check whether it was interrupted
> by a signal? It's similar to other libc syscall wrappers:
>
> errno = 0;
> sleep(...);
> if (errno != 0)
> warn("sleep");
>
> No, you can't just check if the return value is greater than 0. If we
> get a signal but the scheduler doesn't choose to run us until after
> the timeout has elapsed we'll get 0 back but errno will be set. No
> way to avoid this race.
>
> ERRORS
>
> Is this section missing? Maybe just a nod to nanosleep(2), like:
>
> The sleep() function may fail for any of the reasons
> given in nanosleep(2).
>
> Something else?
>
> SEE ALSO
>
> - Add sigaction(2). We mention SA_RESTART and signals in the
> Description.
>
> STANDARDS
>
> - Bump the relevant standard to POSIX.1-2001. That version
> incorporates details about threads, which our version respects.
>
> For sake of completeness, I will note that SUSv2 mentions threads
> too:
>
> https://pubs.opengroup.org/onlinepubs/7908799/xsh/sleep.html
>
> SUSv2 is older than POSIX.1-2001. Do we prefer the earlier
> standard?
>
> - Mention the two possible implementations. Mention that they
> are not the same and might behave differently. Offer a
> solution for portable applications.
>
> For the portability paragraph I'm just spitballing. No idea what the
> right language is here or what recommendations are appropriate.
>
> In general, the nanosleep() spec is simple and the sleep() spec is
> complex due to some historical mishaps. From a spec perspective,
> nanosleep(2) is the safer bet because you know what you're getting,
> warts and all.
>
> However:
>
> I honestly haven't looked very deeply into the specific behavioral
> differences between the two approaches, I'm just taking POSIX at their
> word. We have an old-school implementation in CVS:
>
> http://cvsweb.openbsd.org/src/lib/libc/gen/sleep.c?rev=1.6&content-type=text/x-cvsweb-markup
>
> ... at a glance I can imagine how it might behave differently from the
> current approach:
>
> http://cvsweb.openbsd.org/src/lib/libc/gen/sleep.c?rev=1.13&content-type=text/x-cvsweb-markup
>
> I also don't know where you would find an alarm(3)-based approach
> anymore. I caveat my recommendation with the "although the
> alarm(3)-based approach is increasingly rare" bit to acknowledge this,
> though still I feel like we ought to say something, just in case.
>
> HISTORY
>
> - I cannot find a sleep() system call in Research UNIX v2.
>
> I can find it in v3:
>
>
> https://github.com/dspinellis/unix-history-repo/blob/Research-V3/man/man2/sleep.2
>
> So, change ".At v2" to ".At v3".
>
> I must admit I have a hard time tracking the changes in the Research
> UNIX code. Shit moves around *constantly*. So sleep() might indeed
> be in v2 and I'm just not seeing it.
See the "Combined Tables of Contents" in Doug McIlroy's
"A Research UNIX Reader".
2. System calls
Edition Title Purpose
1 2 3 4 5 6 7 8 9
. + + + + + . . . sleep delay execution [alarm]
And indeed it is documented in
https://www.tuhs.org/Archive/Distributions/Research/Dennis_v2/v2man.pdf
>
> --
>
> Index: sleep.3
> ===================================================================
> RCS file: /cvs/src/lib/libc/gen/sleep.3,v
> retrieving revision 1.16
> diff -u -p -r1.16 sleep.3
> --- sleep.3 8 Feb 2020 01:09:57 -0000 1.16
> +++ sleep.3 25 Jul 2021 03:27:27 -0000
> @@ -32,7 +32,7 @@
> .Os
> .Sh NAME
> .Nm sleep
> -.Nd suspend process execution for interval measured in seconds
> +.Nd suspend execution for a count of seconds
> .Sh SYNOPSIS
> .In unistd.h
> .Ft unsigned int
> @@ -40,46 +40,57 @@
> .Sh DESCRIPTION
> The
> .Fn sleep
> -function suspends execution of the calling process until either
> +function suspends execution until at least the given number of
> .Fa seconds
> -seconds have elapsed or a signal is delivered to the process and its
> -action is to invoke a signal-catching function or to terminate the
> -process.
> -The suspension time may be longer than requested due to the
> -scheduling of other activity by the system.
> +have elapsed or an unmasked signal is delivered to the calling thread.
> .Pp
> -This function is implemented using
> -.Xr nanosleep 2
> -by pausing for
> -.Fa seconds
> -seconds or until a signal occurs.
> -Consequently, in this implementation,
> -sleeping has no effect on the state of process timers,
> -and there is no special handling for
> -.Dv SIGALRM .
> +This version of
> +.Fn sleep
> +is implemented with
> +.Xr nanosleep 2 ,
> +so delivery of any signal will terminate the sleep early,
> +even if
> +.Dv SA_RESTART
> +is set for the interrupting signal.
> .Sh RETURN VALUES
> -If the
> +If
> +.Fn sleep
> +sleeps for the full count of
> +.Fa seconds
> +it returns 0.
> +Otherwise,
> .Fn sleep
> -function returns because the requested time has elapsed, the value
> -returned will be zero.
> -If the
> -.Fn sleep
> -function returns due to the delivery of a signal, the value returned
> -will be the unslept amount (the request time minus the time actually
> -slept) in seconds.
> +returns the number of seconds remaining from the original request.
> .Sh SEE ALSO
> .Xr sleep 1 ,
> -.Xr nanosleep 2
> +.Xr nanosleep 2 ,
> +.Xr sigaction 2
> .Sh STANDARDS
> The
> .Fn sleep
> function conforms to
> -.St -p1003.1-90 .
> +.St -p1003.1-2001 .
> +.Pp
> +For historical reasons,
> +the standard permits
> +.Fn sleep
> +implementations based on either
> +.Xr nanosleep 2
> +or
> +.Xr alarm 3 .
> +There are subtle and unavoidable behavioral differences between the two
> +approaches.
> +Although the
> +.Xr alarm 3 Ns -based
> +approach is increasingly rare,
> +portable applications should prefer calling
> +.Xr nanosleep 2
> +directly to avoid behavior changes when running on different systems.
> .Sh HISTORY
> A
> .Fn sleep
> system call first appeared in
> -.At v2 .
> +.At v3 .
> In
> .At v7 ,
> it was removed and replaced by a C library implementation based on
>
>