]> Savannah Git Hosting - gnulib.git/commitdiff
supersede: Avoid a failure when writing to /dev/null in Solaris zones.
authorBruno Haible <bruno@clisp.org>
Sun, 23 Aug 2020 17:37:17 +0000 (19:37 +0200)
committerBruno Haible <bruno@clisp.org>
Sun, 23 Aug 2020 17:37:17 +0000 (19:37 +0200)
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.

ChangeLog
lib/supersede.c

index 33d4dc0f7ae861204254a3659440e15a0b3ffbd4..8ab706ac4d7db812817fab6790af1ff09e99f7bf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+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.
+
 2020-08-23  Bruno Haible  <bruno@clisp.org>
 
        verify: Make assume work on bit field expressions (regr. 2020-08-22).
index 92317f2fc776b29f4d2ecc8627fe80968aa94d0d..a03cc6d13d39b1fbc0ffd5072b2a660839dd42ab 100644 (file)
@@ -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.  */