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