From: "Edwin Török" <edwin@etorok.net>
To: Alejandro Colomar <alx@kernel.org>
Cc: linux-man@vger.kernel.org
Subject: puts sets errno, but manpage doesn't mention it
Date: Wed, 23 Apr 2025 00:02:18 +0100 [thread overview]
Message-ID: <666f7e00a28f4dec59f02cdd4c9d63d493215674.camel@etorok.net> (raw)
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
next reply other threads:[~2025-04-22 23:02 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-22 23:02 Edwin Török [this message]
2025-04-23 7:52 ` puts sets errno, but manpage doesn't mention it Alejandro Colomar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=666f7e00a28f4dec59f02cdd4c9d63d493215674.camel@etorok.net \
--to=edwin@etorok.net \
--cc=alx@kernel.org \
--cc=linux-man@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox