diff --git a/packager/file/file.cc b/packager/file/file.cc index 51bb2c27ba..6f3a9cf4d7 100644 --- a/packager/file/file.cc +++ b/packager/file/file.cc @@ -74,7 +74,19 @@ bool DeleteLocalFile(const char* file_name) { bool WriteLocalFileAtomically(const char* file_name, const std::string& contents) { - const auto file_path = std::filesystem::u8path(file_name); + std::error_code ec; + // To atomically move the temporary file to the target location after write, + // they must be on the same device. For relative paths without a directory + // part, the parent path is empty, which fails TempFilePath's empty directory + // path check, thus falling back to /tmp that is on a potentially different + // device. We prevent this by resolving the absolute file path. + const auto file_path = + std::filesystem::absolute(std::filesystem::u8path(file_name), ec); + if (ec) { + LOG(ERROR) << "Failed to resolve file path '" << file_name + << "', error: " << ec; + return false; + } const auto dir_path = file_path.parent_path(); std::string temp_file_name; @@ -83,7 +95,6 @@ bool WriteLocalFileAtomically(const char* file_name, if (!File::WriteStringToFile(temp_file_name.c_str(), contents)) return false; - std::error_code ec; auto temp_file_path = std::filesystem::u8path(temp_file_name); std::filesystem::rename(temp_file_path, file_name, ec); if (ec) {