Hi,

The nanosleep.2 page could use some cleanup.  Here's a bunch of fixes,
rewrites, etc.

I've included my notes on the changes below.  I have some (mostly
stylistic) questions in there, too.

--

DESCRIPTION

- We suspend the calling thread, not the calling process.

- Note that we block for "at least" the given timeout.  After all, we
  might block for longer.

- Be more explicit about signal delivery.

Should we reference sigaction(2) here alongside SA_RESTART?  e.g.:

        ... even if SA_RESTART is set for the interrupting signal
        (see sigaction(2) for further details).

RETURN VALUES

- Make it clear there are three cases here: success, signal,
  and other errors.  Separate them into three paragraphs.

- Note that we update remainder in the success case *and* the signal
  case, but not the other case.

I'm unsure about the correct voice here.  Should nanosleep actively
return values?  Or should values "be returned"?

EXAMPLES

- Add some examples.

  The first example is trivial.  Just warmup.  Show them how to
  pack a timespec and make the call.

  The second example demonstrates how to set up a sub-second timeout.
  Sometimes people screw this up, I think it's worth highlighting.

  The last example is more complex.  Show them how to differentiate
  between a signal and programmer error.  Show how the remainder
  argument works.  Show that timeout and remainder can point to the
  same struct.

I'm unclear on whether I need the indent here in the .Bd block.  I
think it looks better than unindented code, but maybe I'm flouting
some practice we have.

ERRORS

- Simplify the opening sentence.  Yeesh, what a mouthful.

- "1000 million" is better written "one billion".  We've done this
  change already in other pages.

- Note that remainder must be non-NULL for an EFAULT to occur.

- Use the past tense consistently.

Unsure if a second EFAULT case for remainder is a good thing here.
Strictly speaking, NULL is not a valid part of the process address
space.  Maybe that's too pedantic?

Also, do we have a more standard "boilerplate" sentence for EFAULT?

SEE ALSO

- Cross reference sigaction(2).  We mention SA_RESTART in the
  description.

HISTORY

- Clarify what happened to the historical sleep system call a bit.

- I'm pretty sure nanosleep() is a POSIX invention, so note that it
  really first appeared in POSIX.1b (realtime extensions), and then talk
  about the implementation we got from NetBSD.

  If someone can find nanosleep() in the wild before 1993 we can fix
  the attribution.

- No need to mention that FreeBSD also got their implementation from
  NetBSD.

--

Index: nanosleep.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/nanosleep.2,v
retrieving revision 1.16
diff -u -p -r1.16 nanosleep.2
--- nanosleep.2 31 Dec 2018 18:54:00 -0000      1.16
+++ nanosleep.2 20 Jul 2021 22:14:50 -0000
@@ -41,53 +41,114 @@
 .Ft int
 .Fn nanosleep "const struct timespec *timeout" "struct timespec *remainder"
 .Sh DESCRIPTION
+The
 .Fn nanosleep
-suspends execution of the calling process for the duration specified by
+function suspends execution of the calling thread for at least the
+duration specified by
 .Fa timeout .
-An unmasked signal will cause it to terminate the sleep early,
-regardless of the
+Delivery of an unmasked signal to the calling thread will terminate the
+sleep early,
+even if
 .Dv SA_RESTART
-value on the interrupting signal.
+is set for the interrupting signal.
 .Sh RETURN VALUES
-If the
+If
 .Fn nanosleep
-function returns because the requested duration has elapsed, the value
-returned will be zero.
+sleeps the full
+.Fa timeout
+without interruption it returns 0.
+If
+.Fa remainder
+is
+.Pf non- Dv NULL
+it is set to zero.
 .Pp
-If the
+If
 .Fn nanosleep
-function returns due to the delivery of a signal, the value returned
-will be \-1, and the global variable
+is interrupted by a signal it returns -1 and the global variable
 .Va errno
-will be set to indicate the interruption.
+is set to
+.Dv EINTR .
 If
 .Fa remainder
-is non-null, the timespec structure it references is updated to contain the
-unslept amount (the requested duration minus the duration actually slept).
-.Sh ERRORS
-If any of the following conditions occur, the
+is
+.Pf non- Dv NULL
+it is set to the unslept portion of the
+.Fa timeout .
+.Pp
+Otherwise,
 .Fn nanosleep
-function shall return \-1 and set
+returns -1 and the global variable
 .Va errno
-to the corresponding value.
+is set to indicate the error.
+.Sh EXAMPLES
+Count down from ten:
+.Bd -literal
+       struct timespec one_second;
+       int i;
+
+       one_second.tv_sec = 1;
+       one_second.tv_nsec = 0;
+
+       for (i = 10; i >= 0; i--) {
+               if (nanosleep(&one_second, NULL) == -1)
+                       err(1, "nanosleep");
+               printf("%4d\\n", i);
+       }
+.Ed
+.Pp
+Check a condition once every one hundred milliseconds:
+.Bd -literal
+       struct timespec hundred_ms;
+       extern int done;
+
+       hundred_ms.tv_sec = 0;
+       hundred_ms.tv_nsec = 100 * 1000 * 1000;
+
+       while (!done) {
+               if (nanosleep(&hundred_ms, NULL) == -1)
+                       err(1, "nanosleep");
+       }
+.Ed
+.Pp
+Sleep for at least sixty seconds and print the time remaining whenever
+a signal interrupts the sleep:
+.Bd -literal
+       struct timespec timeout;
+
+       timeout.tv_sec = 60;
+       timeout.tv_nsec = 0;
+
+       while (nanosleep(&timeout, &timeout) == -1) {
+               if (errno != EINTR)
+                       err(1, "nanosleep");
+               printf("time left: %lld.%09ld seconds\\n",
+                   (long long)timeout.tv_sec, timeout.tv_nsec);
+       }
+.Ed
+.Sh ERRORS
+.Fn nanosleep
+will fail if:
 .Bl -tag -width Er
 .It Bq Er EINTR
-.Fn nanosleep
-was interrupted by the delivery of a signal.
+The call was interrupted by the delivery of a signal.
 .It Bq Er EINVAL
 .Fa timeout
 specified a nanosecond value less than zero or greater than or equal to
-1000 million,
+one billion,
 or a second value less than zero.
 .It Bq Er EFAULT
-Either
 .Fa timeout
-or
+pointed to memory that is not a valid part of the process address space.
+.It Bq Er EFAULT
 .Fa remainder
-points to memory that is not a valid part of the process address space.
+was
+.Pf non- Dv NULL
+and pointed to memory that is not a valid part of the process address space.
 .El
 .Sh SEE ALSO
 .Xr sleep 1 ,
+.Xr sigaction 2 ,
 .Xr sleep 3
 .Sh STANDARDS
 The
@@ -97,17 +158,23 @@ function conforms to
 .Sh HISTORY
 The predecessor of this system call,
 .Fn sleep ,
-appeared in
-.At v3 ,
-but was removed when
+first appeared in
+.At v3 .
+It was removed in
+.At v7
+and replaced with a C library implementation based on
 .Xr alarm 3
-was introduced into
-.At v7 .
+and
+.Xr signal 3 .
+.Pp
 The
 .Fn nanosleep
-system call has been available since
+function first appeared in
+.St -p1003.1b-93 .
+.Pp
+This implementation of
+.Fn nanosleep
+first appeared in
 .Nx 1.3
 and was ported to
-.Ox 2.1
-and
-.Fx 3.0 .
+.Ox 2.1 .

Reply via email to