c++: Windows rename [PR 98412]
authorNathan Sidwell <nathan@acm.org>
Mon, 21 Dec 2020 17:48:28 +0000 (09:48 -0800)
committerNathan Sidwell <nathan@acm.org>
Mon, 21 Dec 2020 17:48:28 +0000 (09:48 -0800)
Some system's rename(2) fails if the target already exists, so delete it
first.

gcc/cp/
* module.cc (create_dirs): Add logging.
(finish_module_processing): Unlink before rename.

gcc/cp/module.cc

index fc918d296a21f7f7ad773f4f4a6380eb6edfb8e3..7e38293545fbf6b974b2ec77226cd298d4a55a5b 100644 (file)
@@ -4693,6 +4693,7 @@ create_dirs (char *path)
        char sep = *base;
        *base = 0;
        int failed = mkdir (path, S_IRWXU | S_IRWXG | S_IRWXO);
+       dump () && dump ("Mkdir ('%s') errno:=%u", path, failed ? errno : 0);
        *base = sep;
        if (failed
            /* Maybe racing with another creator (of a *different*
@@ -19744,8 +19745,17 @@ finish_module_processing (cpp_reader *reader)
              input_location = loc;
            }
          if (to.end ())
-           if (rename (tmp_name, path))
-             to.set_error (errno);
+           {
+             /* Some OS's do not replace NEWNAME if it already
+                exists.  This'll have a race condition in erroneous
+                concurrent builds.  */
+             unlink (path);
+             if (rename (tmp_name, path))
+               {
+                 dump () && dump ("Rename ('%s','%s') errno=%u", errno);
+                 to.set_error (errno);
+               }
+           }
 
          if (to.get_error ())
            {