From: Bruno Haible <bruno@clisp.org>
To: bug-gnulib@gnu.org
Cc: "Jörg Sonnenberger" <joerg@netbsd.org>,
"Thomas Klausner" <tk@giga.or.at>
Subject: supersede: Avoid a failure when writing to /dev/null in Solaris zones
Date: Sun, 23 Aug 2020 19:38:36 +0200 [thread overview]
Message-ID: <1852871.mQFH9W2BVG@omega> (raw)
Jörg Sonnenberger noticed that the new gnulib module 'supersede', when
writing to /dev/null in Solaris/Illumos zones, fails [1][2].
Per POSIX [3],
open ("/dev/null", O_TRUNC | O_WRONLY)
and
open ("/dev/null", O_CREAT | O_TRUNC | O_WRONLY)
should be equivalent. But in Solaris/Illumos zones, the second form is needed
because the first one fails with EINVAL.
Should we extend the 'open' module to cover this bug? Probably overkill,
especially since I can't see how we could test for it in an autoconf test.
Here's a workaround, specifically in the 'supersede' module.
[1] https://www.illumos.org/issues/13035
[2] https://pkgsrc.se/files.php?messageId=20200812233110.30230FB28@cvs.NetBSD.org
[3] https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/open.html
2020-08-23 Bruno Haible <bruno@clisp.org>
supersede: Avoid a failure when writing to /dev/null in Solaris zones.
Reported by Jörg Sonnenberger <joerg@netbsd.org>
via Thomas Klausner <tk@giga.or.at> in
<https://pkgsrc.se/files.php?messageId=20200812233110.30230FB28@cvs.NetBSD.org>.
* lib/supersede.c (open_supersede): When opening an existing non-regular
file on Solaris, use O_CREAT although it should not be necessary.
diff --git a/lib/supersede.c b/lib/supersede.c
index 92317f2..a03cc6d 100644
--- a/lib/supersede.c
+++ b/lib/supersede.c
@@ -78,6 +78,16 @@ open_supersede (const char *filename, int flags, mode_t mode,
struct supersede_final_action *action)
{
int fd;
+ /* Extra flags for existing devices. */
+ int extra_flags =
+ #if defined __sun
+ /* open ("/dev/null", O_TRUNC | O_WRONLY) fails with error EINVAL on Solaris
+ zones. See <https://www.illumos.org/issues/13035>. As a workaround, add
+ the O_CREAT flag, although it ought not to be necessary. */
+ O_CREAT;
+ #else
+ 0;
+ #endif
if (supersede_if_exists)
{
@@ -89,7 +99,7 @@ open_supersede (const char *filename, int flags, mode_t mode,
&& ! S_ISREG (statbuf.st_mode)
/* The file exists and is possibly a character device, socket, or
something like that. */
- && ((fd = open (filename, flags, mode)) >= 0
+ && ((fd = open (filename, flags | extra_flags, mode)) >= 0
|| errno != ENOENT))
{
if (fd >= 0)
@@ -167,7 +177,7 @@ open_supersede (const char *filename, int flags, mode_t mode,
{
/* It is possibly a character device, socket, or
something like that. */
- fd = open (canon_filename, flags, mode);
+ fd = open (canon_filename, flags | extra_flags, mode);
if (fd >= 0)
{
free (canon_filename);
@@ -197,6 +207,28 @@ open_supersede (const char *filename, int flags, mode_t mode,
action->final_rename_temp = NULL;
action->final_rename_dest = NULL;
}
+ #if defined __sun
+ /* Work around <https://www.illumos.org/issues/13035>. */
+ else if (errno == EINVAL)
+ {
+ struct stat statbuf;
+
+ if (stat (filename, &statbuf) >= 0
+ && ! S_ISREG (statbuf.st_mode))
+ {
+ /* The file exists and is possibly a character device, socket,
+ or something like that. As a workaround, add the O_CREAT
+ flag, although it ought not to be necessary.*/
+ fd = open (filename, flags | extra_flags, mode);
+ if (fd >= 0)
+ {
+ /* The file exists. */
+ action->final_rename_temp = NULL;
+ action->final_rename_dest = NULL;
+ }
+ }
+ }
+ #endif
else if (errno == ENOENT)
{
/* The file does not exist. Use a temporary file. */
next reply other threads:[~2020-08-23 17:38 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-23 17:38 Bruno Haible [this message]
2020-09-20 19:31 ` supersede: Avoid a failure when writing to /dev/null in Solaris zones Bruno Haible
-- strict thread matches above, loose matches on Subject: below --
2022-09-12 8:51 Bruno Haible
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
List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1852871.mQFH9W2BVG@omega \
--to=bruno@clisp.org \
--cc=bug-gnulib@gnu.org \
--cc=joerg@netbsd.org \
--cc=tk@giga.or.at \
/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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).