summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osl/file.h31
-rw-r--r--include/osl/file.hxx33
-rw-r--r--sal/osl/unx/file_misc.cxx5
-rw-r--r--sal/osl/w32/file.cxx34
-rw-r--r--sal/util/sal.map5
-rw-r--r--sfx2/source/doc/docfile.cxx3
6 files changed, 110 insertions, 1 deletions
diff --git a/include/osl/file.h b/include/osl/file.h
index 133b93de0c93..cf0bbfb9495d 100644
--- a/include/osl/file.h
+++ b/include/osl/file.h
@@ -1634,6 +1634,37 @@ SAL_DLLPUBLIC oslFileError SAL_CALL osl_createTempFile(
oslFileHandle* pHandle,
rtl_uString** ppustrTempFileURL);
+/** Move a file to a new destination or rename it, taking old file's identity (if exists).
+
+ Moves or renames a file, replacing an existing file if exist. If the old file existed,
+ moved file's metadata, e.g. creation time (on FSes which keep files' creation time) or
+ ACLs, are set to old one's (to keep the old file's identity) - currently this is only
+ implemented on Windows; on other platforms, this is equivalent to osl_moveFile.
+
+ @param[in] pustrSourceFileURL
+ Full qualified URL of the source file.
+
+ @param[in] pustrDestFileURL
+ Full qualified URL of the destination file.
+
+ @retval osl_File_E_None on success
+ @retval osl_File_E_INVAL the format of the parameters was not valid
+ @retval osl_File_E_NOMEM not enough memory for allocating structures
+ @retval osl_File_E_ACCES permission denied
+ @retval osl_File_E_PERM operation not permitted
+ @retval osl_File_E_NAMETOOLONG file name too long
+ @retval osl_File_E_NOENT no such file
+ @retval osl_File_E_ROFS read-only file system
+ @retval osl_File_E_BUSY if the implementation internally requires resources that are
+ (temporarily) unavailable
+
+ @see osl_moveFile()
+
+ @since LibreOffice 6.2
+*/
+SAL_DLLPUBLIC oslFileError SAL_CALL osl_replaceFile(rtl_uString* pustrSourceFileURL,
+ rtl_uString* pustrDestFileURL);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/osl/file.hxx b/include/osl/file.hxx
index a154aa4f27bc..855398db4038 100644
--- a/include/osl/file.hxx
+++ b/include/osl/file.hxx
@@ -1298,6 +1298,39 @@ public:
return static_cast< RC >( osl_moveFile( ustrSourceFileURL.pData, ustrDestFileURL.pData ) );
}
+ /** Move a file to a new destination or rename it, taking old file's identity (if exists).
+
+ Moves or renames a file, replacing an existing file if exist. If the old file existed,
+ moved file's metadata, e.g. creation time (on FSes which keep files' creation time) or
+ ACLs, are set to old one's (to keep the old file's identity) - currently this is only
+ implemented on Windows; on other platforms, this is equivalent to osl_moveFile.
+
+ @param[in] ustrSourceFileURL
+ Full qualified URL of the source file.
+
+ @param[in] ustrDestFileURL
+ Full qualified URL of the destination file.
+
+ @retval E_None on success
+ @retval E_INVAL the format of the parameters was not valid
+ @retval E_NOMEM not enough memory for allocating structures
+ @retval E_ACCES permission denied
+ @retval E_PERM operation not permitted
+ @retval E_NAMETOOLONG file name too long
+ @retval E_NOENT no such file
+ @retval E_ROFS read-only file system
+ @retval E_BUSY device or resource busy
+
+ @see move()
+
+ @since LibreOffice 6.2
+ */
+ static RC replace(const ::rtl::OUString& ustrSourceFileURL,
+ const ::rtl::OUString& ustrDestFileURL)
+ {
+ return static_cast<RC>(osl_replaceFile(ustrSourceFileURL.pData, ustrDestFileURL.pData));
+ }
+
/** Remove a regular file.
@param[in] ustrFileURL
diff --git a/sal/osl/unx/file_misc.cxx b/sal/osl/unx/file_misc.cxx
index 873bec3cb988..8ae8c74062ee 100644
--- a/sal/osl/unx/file_misc.cxx
+++ b/sal/osl/unx/file_misc.cxx
@@ -604,6 +604,11 @@ oslFileError SAL_CALL osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrD
return oslDoMoveFile( srcPath, destPath );
}
+oslFileError SAL_CALL osl_replaceFile(rtl_uString* ustrFileURL, rtl_uString* ustrDestURL)
+{
+ return osl_moveFile(ustrFileURL, ustrDestURL);
+}
+
oslFileError SAL_CALL osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
{
char srcPath[PATH_MAX];
diff --git a/sal/osl/w32/file.cxx b/sal/osl/w32/file.cxx
index c8b001e9847d..a5e6c640b8ed 100644
--- a/sal/osl/w32/file.cxx
+++ b/sal/osl/w32/file.cxx
@@ -1099,4 +1099,38 @@ oslFileError SAL_CALL osl_moveFile(rtl_uString* strPath, rtl_uString *strDestPat
return error;
}
+oslFileError SAL_CALL osl_replaceFile(rtl_uString* strPath, rtl_uString* strDestPath)
+{
+ rtl_uString *strSysPath = nullptr, *strSysDestPath = nullptr;
+ oslFileError error = osl_getSystemPathFromFileURL_(strPath, &strSysPath, false);
+
+ if (error == osl_File_E_None)
+ error = osl_getSystemPathFromFileURL_(strDestPath, &strSysDestPath, false);
+
+ if (error == osl_File_E_None)
+ {
+ LPCWSTR src = o3tl::toW(rtl_uString_getStr(strSysPath));
+ LPCWSTR dst = o3tl::toW(rtl_uString_getStr(strSysDestPath));
+
+ if (!ReplaceFileW(dst, src, nullptr,
+ REPLACEFILE_WRITE_THROUGH | REPLACEFILE_IGNORE_MERGE_ERRORS
+ | REPLACEFILE_IGNORE_ACL_ERRORS,
+ nullptr, nullptr))
+ {
+ DWORD dwError = GetLastError();
+ if (dwError == ERROR_FILE_NOT_FOUND) // no strDestPath file?
+ error = osl_moveFile(strPath, strDestPath);
+ else
+ error = oslTranslateFileError(dwError);
+ }
+ }
+
+ if (strSysPath)
+ rtl_uString_release(strSysPath);
+ if (strSysDestPath)
+ rtl_uString_release(strSysDestPath);
+
+ return error;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/util/sal.map b/sal/util/sal.map
index 07150ab0340d..9292d50ca423 100644
--- a/sal/util/sal.map
+++ b/sal/util/sal.map
@@ -700,6 +700,11 @@ LIBO_UDK_5.3 { # symbols available in >= LibO 5.3
rtl_uString_newReplaceFirstUtf16LUtf16L;
} LIBO_UDK_5.2;
+LIBO_UDK_6.2 { # symbols available in >= LibO 6.2
+ global:
+ osl_replaceFile;
+} LIBO_UDK_5.3;
+
PRIVATE_1.0 {
global:
osl_detail_ObjectRegistry_storeAddresses;
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 8da6f3a6e7b8..4cebc868e2bd 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -1845,7 +1845,8 @@ void SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource,
OUString aDestMainURL = aDest.GetMainURL(INetURLObject::DecodeMechanism::NONE);
sal_uInt64 nAttributes = GetDefaultFileAttributes(aDestMainURL);
- if (IsFileMovable(aDestMainURL) && osl::File::move(aSourceMainURL, aDestMainURL) == osl::FileBase::E_None)
+ if (IsFileMovable(aDestMainURL)
+ && osl::File::replace(aSourceMainURL, aDestMainURL) == osl::FileBase::E_None)
{
if (nAttributes)
// Adjust attributes, source might be created with