Throw on failure in gmx_file_rename
[alexxy/gromacs.git] / src / gromacs / utility / futil.cpp
index 8a54e0d864093fe150f932176e41ee495ee03b9c..34467e1f1d120f3adfefee22f4a11fb9c06cc4ea 100644 (file)
@@ -342,7 +342,7 @@ gmx_bool gmx_fexist(const std::string& fname)
     FILE* test = fopen(fname.c_str(), "r");
     if (test == nullptr)
     {
-/*Windows doesn't allow fopen of directory - so we need to check this seperately */
+/*Windows doesn't allow fopen of directory - so we need to check this separately */
 #if GMX_NATIVE_WINDOWS
         DWORD attr = GetFileAttributes(fname.c_str());
         return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY);
@@ -521,6 +521,8 @@ FilePtr openLibraryFile(const char* filename, bool bAddCWD, bool bFatal)
 /*! \brief Use mkstemp (or similar function to make a new temporary
  * file and (on non-Windows systems) return a file descriptor to it.
  *
+ * Note: not thread-safe on non-Windows systems
+ *
  * \todo Use std::string and std::vector<char>. */
 static int makeTemporaryFilename(char* buf)
 {
@@ -548,6 +550,11 @@ static int makeTemporaryFilename(char* buf)
 #else
     int fd = mkstemp(buf);
 
+    /* mkstemp creates 0600 files - respect umask instead */
+    mode_t currUmask = umask(0);
+    umask(currUmask);
+    fchmod(fd, 0666 & ~currUmask);
+
     if (fd < 0)
     {
         gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf, strerror(errno));
@@ -585,11 +592,12 @@ FILE* gmx_fopen_temporary(char* buf)
     return fpout;
 }
 
-int gmx_file_rename(const char* oldname, const char* newname)
+void gmx_file_rename(const char* oldname, const char* newname)
 {
+    int code;
 #if !GMX_NATIVE_WINDOWS
     /* under unix, rename() is atomic (at least, it should be). */
-    return rename(oldname, newname);
+    code = rename(oldname, newname);
 #else
     if (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
     {
@@ -597,13 +605,18 @@ int gmx_file_rename(const char* oldname, const char* newname)
         /* This just lets the F@H checksumming system know about the rename */
         fcRename(oldname, newname);
 #    endif
-        return 0;
+        code = 0;
     }
     else
     {
-        return 1;
+        code = 1;
     }
 #endif
+    if (code != 0)
+    {
+        auto errorMsg = gmx::formatString("Failed to rename %s to %s.", oldname, newname);
+        GMX_THROW(gmx::FileIOError(errorMsg));
+    }
 }
 
 int gmx_file_copy(const char* oldname, const char* newname, gmx_bool copy_if_empty)