From 51a655d9c70fa43743f40ed4de101b60dcf08b7c Mon Sep 17 00:00:00 2001 From: sramamoorthy Date: Mon, 18 Mar 2019 00:18:05 -0700 Subject: [PATCH] atomicReplace to preserve owner & permission info atomicReplace currently does not preserve the ownership and permission info, this fix will preserves the ownership and permission info - it fails the call if it is not able to do so. --- flow/Platform.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/flow/Platform.cpp b/flow/Platform.cpp index 8d358229b8..a317bed2f2 100644 --- a/flow/Platform.cpp +++ b/flow/Platform.cpp @@ -1666,6 +1666,27 @@ void atomicReplace( std::string const& path, std::string const& content, bool te f = textmode ? fopen( tempfilename.c_str(), "wt" ) : fopen(tempfilename.c_str(), "wb"); if(!f) throw io_error(); + #ifdef _WIN32 + #elif defined(__unixish__) + // get the uid/gid/mode bits of old file and set it on new file, else fail + struct stat info; + if (stat(path.c_str(), &info) < 0) { + TraceEvent("StatFailed").detail("path", path); + throw io_error(); + } + if (chown(tempfilename.c_str(), info.st_uid, info.st_gid) < 0) { + deleteFile(tempfilename); + TraceEvent("ChownFailed").detail("tempfilename", tempfilename).detail("uid", info.st_uid).detail("gid", info.st_gid); + throw io_error(); + } + if (chmod(tempfilename.c_str(), info.st_mode) < 0) { + deleteFile(tempfilename); + TraceEvent("ChmodFailed").detail("tempfilename", tempfilename).detail("mode", info.st_mode); + throw io_error(); + } + #else + #error Port me! + #endif if( textmode && fprintf( f, "%s", content.c_str() ) < 0) throw io_error();