changeset 32087:a4fbcbaa0aa2

rename: Consistent behavior cross-platform for existing target file (bug #63803). * liboctave/system/file-ops.cc (octave::sys:rename): Manually enforce consistent behavior on different platforms because the STL allow implementation defined behavior if the target already exists.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 06 May 2023 18:12:59 +0200
parents 3c608abd55f5
children 212145b8e5f0
files liboctave/system/file-ops.cc
diffstat 1 files changed, 20 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/system/file-ops.cc	Sat May 06 17:48:27 2023 +0200
+++ b/liboctave/system/file-ops.cc	Sat May 06 18:12:59 2023 +0200
@@ -569,6 +569,26 @@
 
   msg = "";
 
+  // Do nothing if source and target are the same file.
+  if (same_file (to, from))
+    return 0;
+
+  // The behavior of std::rename with existing target is not defined by the
+  // standard.  Implementations differ vastly.  For Octave, use the following
+  // for the case that the target already exists:
+  // If the source and the target are regular files, overwrite the target.
+  // In other cases, fail.
+  if (file_exists (to))
+    {
+      if (file_exists (to, false) && file_exists (from, false))
+        unlink (to);
+      else
+        {
+          msg = "Target already exists.";
+          return status;
+        }
+    }
+
 #if defined (OCTAVE_USE_WINDOWS_API)
   std::wstring wfrom = u8_to_wstring (from);
   std::wstring wto = u8_to_wstring (to);