Linux Manual Pages development
 help / color / mirror / Atom feed
* puts sets errno, but manpage doesn't mention it
@ 2025-04-22 23:02 Edwin Török
  2025-04-23  7:52 ` Alejandro Colomar
  0 siblings, 1 reply; 2+ messages in thread
From: Edwin Török @ 2025-04-22 23:02 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: linux-man

Hello,

The manpage for puts [1] doesn't mention errno.

Therefore for a long time I've avoided looking at errno when any of the
stdio functions fail (errno could've been leftover from a previous
call, or some internal, potentially unrelated and handled error).

What the manpage says is accurate when looking at the C23 standard [2],
however on POSIX systems one can do better!

Both POSIX 2008 [3] and POSIX 2024 [4] say that 'puts' sets 'errno',
and that this is an extension to the C standard. 

The FreeBSD manpage says this too [5], although it doesn't mention that
this is an extension.

It would be useful if the Linux manpages got updated with information
about which stdio functions set errno, and that setting errno is a
POSIX extension (I'm hoping that POSIX is consistent and all stdio
functions would set errno, but I haven't checked in detail).

Should I send a patch that attempts to update the manpages, or do we 
need to check with the libc mailing list whether this is in fact
guaranteed? (e.g. if they've implemented it according to the Linux
manpage, instead of the POSIX standard, then errno may not be set in
all cases that it should...)

I've also tested whether this is true in practice, and the following
program prints a 'Broken pipe' message on 3 libc implementations on
Fedora 42: GNU libc 2.41, musl-libc 1.2.5, dietlibc 0.34, when run as
'./x | dd count=5 of=/dev/null'

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

int main(void)
{
  signal(SIGPIPE, SIG_IGN);
  while(puts("foo") != EOF);
  perror("puts");
  return EXIT_FAILURE;
}

Or perhaps even simpler, this prints 'No such file or directory':

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
  FILE *f = fopen("/nonexistent", "r");
  if (!f) {
    perror("fopen");
    return EXIT_FAILURE;
  }
  fclose(f);
  return EXIT_SUCCESS;
}

P.S. I discovered the possibility that puts may set errno while reading
(the excellent!) book "Modern C"
https://gustedt.gitlabpages.inria.fr/modern-c/

[1]: https://www.man7.org/linux/man-pages/man3/puts.3.html
[2]: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf from
https://www.c-language.org/
[3]:
 https://pubs.opengroup.org/onlinepubs/9699919799/functions/puts.html
[4]:
https://pubs.opengroup.org/onlinepubs/9799919799/functions/puts.html
[5]: https://man.freebsd.org/cgi/man.cgi?fputs


Best regards,
--Edwin

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: puts sets errno, but manpage doesn't mention it
  2025-04-22 23:02 puts sets errno, but manpage doesn't mention it Edwin Török
@ 2025-04-23  7:52 ` Alejandro Colomar
  0 siblings, 0 replies; 2+ messages in thread
From: Alejandro Colomar @ 2025-04-23  7:52 UTC (permalink / raw)
  To: Edwin Török; +Cc: linux-man

[-- Attachment #1: Type: text/plain, Size: 3264 bytes --]

[BCC += Jens]

Hi Edwin,

On Wed, Apr 23, 2025 at 12:02:18AM +0100, Edwin Török wrote:
> Hello,
> 
> The manpage for puts [1] doesn't mention errno.
> 
> Therefore for a long time I've avoided looking at errno when any of the
> stdio functions fail (errno could've been leftover from a previous
> call, or some internal, potentially unrelated and handled error).
> 
> What the manpage says is accurate when looking at the C23 standard [2],
> however on POSIX systems one can do better!

Hmm, I didn't know that.

> Both POSIX 2008 [3] and POSIX 2024 [4] say that 'puts' sets 'errno',
> and that this is an extension to the C standard. 

And POSIX.1-2001 too, as I checked now.

> The FreeBSD manpage says this too [5], although it doesn't mention that
> this is an extension.

The ISO C standard usually doesn't say anything about errno, except for
a few cases, so anything about errno is quite likely an extension to
ISO C, with a few exceptions.  We can also omit the fact that it's an
extension.

> It would be useful if the Linux manpages got updated with information
> about which stdio functions set errno, and that setting errno is a
> POSIX extension (I'm hoping that POSIX is consistent and all stdio
> functions would set errno, but I haven't checked in detail).

Agree.

> Should I send a patch that attempts to update the manpages,

Sure, please do!

> or do we 
> need to check with the libc mailing list whether this is in fact
> guaranteed? (e.g. if they've implemented it according to the Linux
> manpage, instead of the POSIX standard, then errno may not be set in
> all cases that it should...)

I'm pretty sure they would have read the POSIX standard while
implementing them, but it doesn't hurt to
CC <libc-alpha@sourceware.org> in your patch(es).

> I've also tested whether this is true in practice, and the following
> program prints a 'Broken pipe' message on 3 libc implementations on
> Fedora 42: GNU libc 2.41, musl-libc 1.2.5, dietlibc 0.34, when run as
> './x | dd count=5 of=/dev/null'
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <signal.h>
> 
> int main(void)
> {
>   signal(SIGPIPE, SIG_IGN);
>   while(puts("foo") != EOF);
>   perror("puts");
>   return EXIT_FAILURE;
> }
> 
> Or perhaps even simpler, this prints 'No such file or directory':
> 
> #include <stdio.h>
> #include <stdlib.h>
> int main(void)
> {
>   FILE *f = fopen("/nonexistent", "r");
>   if (!f) {
>     perror("fopen");
>     return EXIT_FAILURE;
>   }
>   fclose(f);
>   return EXIT_SUCCESS;
> }
> 
> P.S. I discovered the possibility that puts may set errno while reading
> (the excellent!) book "Modern C"
> https://gustedt.gitlabpages.inria.fr/modern-c/

Nice!

> 
> [1]: https://www.man7.org/linux/man-pages/man3/puts.3.html
> [2]: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf from
> https://www.c-language.org/
> [3]:
>  https://pubs.opengroup.org/onlinepubs/9699919799/functions/puts.html
> [4]:
> https://pubs.opengroup.org/onlinepubs/9799919799/functions/puts.html
> [5]: https://man.freebsd.org/cgi/man.cgi?fputs
> 
> 
> Best regards,
> --Edwin

Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-04-23  7:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-22 23:02 puts sets errno, but manpage doesn't mention it Edwin Török
2025-04-23  7:52 ` Alejandro Colomar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox