summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--TSRM/tsrm_virtual_cwd.c8
-rw-r--r--TSRM/tsrm_virtual_cwd.h10
-rw-r--r--ext/standard/tests/file/bug44805.phpt15
4 files changed, 31 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 384069b8b7..5027353f7f 100644
--- a/NEWS
+++ b/NEWS
@@ -148,6 +148,7 @@ PHP NEWS
- Fixed possible crash in ext/soap because of uninitialized value. (Zdash Urf)
- Fixed PECL bug #12431 (OCI8 ping functionality is broken). (Oracle Corp.)
+- Fixed bug #44805 (rename() function is not portable to Windows). (Pierre)
- Fixed bug #44648 (Attribute names not checked for wellformedness). (Rob)
- Fixed bug #44414 (Incomplete reporting about abstract methods). (Dmitry)
- Fixed bug #44390 (mysqli_bind_param/bind_result and Object member variables)
diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c
index 27f6dffa68..ecad7b4960 100644
--- a/TSRM/tsrm_virtual_cwd.c
+++ b/TSRM/tsrm_virtual_cwd.c
@@ -1042,8 +1042,14 @@ CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC) /* {{{ */
return -1;
}
newname = new_state.cwd;
-
+
+ /* rename on windows will fail if newname already exists.
+ MoveFileEx has to be used */
+#ifdef TSRM_WIN32
+ retval = (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) == 0) ? -1 : 0;
+#else
retval = rename(oldname, newname);
+#endif
CWD_STATE_FREE(&old_state);
CWD_STATE_FREE(&new_state);
diff --git a/TSRM/tsrm_virtual_cwd.h b/TSRM/tsrm_virtual_cwd.h
index d4e2415b10..df9428d7f2 100644
--- a/TSRM/tsrm_virtual_cwd.h
+++ b/TSRM/tsrm_virtual_cwd.h
@@ -251,7 +251,7 @@ CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC);
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
#if !defined(TSRM_WIN32)
-#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
+# define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
#endif
#define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
#define VCWD_MKDIR(pathname, mode) virtual_mkdir(pathname, mode TSRMLS_CC)
@@ -277,7 +277,13 @@ CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC);
#define VCWD_OPEN(path, flags) open(path, flags)
#define VCWD_OPEN_MODE(path, flags, mode) open(path, flags, mode)
#define VCWD_CREAT(path, mode) creat(path, mode)
-#define VCWD_RENAME(oldname, newname) rename(oldname, newname)
+/* rename on windows will fail if newname already exists.
+ MoveFileEx has to be used */
+#if defined(TSRM_WIN32)
+# define VCWD_RENAME(oldname, newname) MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING)
+#else
+# define VCWD_RENAME(oldname, newname) rename(oldname, newname)
+#endif
#define VCWD_CHDIR(path) chdir(path)
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, chdir)
#define VCWD_GETWD(buf) getwd(buf)
diff --git a/ext/standard/tests/file/bug44805.phpt b/ext/standard/tests/file/bug44805.phpt
new file mode 100644
index 0000000000..7054b76cfc
--- /dev/null
+++ b/ext/standard/tests/file/bug44805.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug#44806 (rename() function is not portable to Windows)
+--FILE--
+<?php
+
+file_put_contents("file1.txt", "this is file 1");
+file_put_contents("file2.txt", "this is file 2");
+
+rename("file1.txt", "file2.txt");
+
+echo "reading file 2: ";
+readfile("file2.txt");
+?>
+--EXPECT--
+reading file 2: this is file 1