Temporary file tweaks.
authorJames W. Barnett <jbarnet4@tulane.edu>
Mon, 17 Aug 2015 18:51:01 +0000 (13:51 -0500)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Mon, 5 Oct 2015 19:17:13 +0000 (21:17 +0200)
Create gmx_fopen_temporary which creates tmp file via mkstemp and opens it,
returning a file pointer. gmx_tmpnam is still used to return a tmp
file name when the file is not opened right away. Use make_backup
and gmx rename tool when moving temp file to updated file.

Change-Id: I0a5aa0ec284324717751755598438a5e2fc33146

src/gromacs/gmxana/gmx_genion.cpp
src/gromacs/gmxpreprocess/solvate.cpp
src/gromacs/utility/futil.cpp
src/gromacs/utility/futil.h
src/programs/view/dialogs.cpp
src/programs/view/filter.cpp

index 98888397d55a7dba591e9b8bb7393e99b986d4c7..81cf326297f6aa9d7de0b8a692cd35532df2dac6 100644 (file)
@@ -241,8 +241,7 @@ static void update_topol(const char *topinout, int p_num, int n_num,
     printf("\nProcessing topology\n");
     fpin  = gmx_ffopen(topinout, "r");
     std::strncpy(temporary_filename, "temp.topXXXXXX", STRLEN);
-    gmx_tmpnam(temporary_filename);
-    fpout = gmx_ffopen(temporary_filename, "w");
+    fpout = gmx_fopen_temporary(temporary_filename);
 
     line       = 0;
     bMolecules = FALSE;
@@ -335,10 +334,8 @@ static void update_topol(const char *topinout, int p_num, int n_num,
         }
     }
     gmx_ffclose(fpout);
-    /* use gmx_ffopen to generate backup of topinout */
-    fpout = gmx_ffopen(topinout, "w");
-    gmx_ffclose(fpout);
-    rename(temporary_filename, topinout);
+    make_backup(topinout);
+    gmx_file_rename(temporary_filename, topinout);
 }
 
 int gmx_genion(int argc, char *argv[])
index f8111ae22cf3c612a7276ff62f91e960a7db21af..1b65a5c4d594ed6207cff67fe4fce926bdeb83bf 100644 (file)
@@ -722,8 +722,7 @@ static void update_top(t_atoms *atoms, matrix box, int NFILE, t_filenm fnm[],
 
         fprintf(stderr, "Processing topology\n");
         fpin    = gmx_ffopen(topinout, "r");
-        gmx_tmpnam(temporary_filename);
-        fpout   = gmx_ffopen(temporary_filename, "w");
+        fpout   = gmx_fopen_temporary(temporary_filename);
         line    = 0;
         bSystem = bMolecules = FALSE;
         while (fgets(buf, STRLEN, fpin))
@@ -800,10 +799,8 @@ static void update_top(t_atoms *atoms, matrix box, int NFILE, t_filenm fnm[],
             fprintf(fpout, "%-15s %5d\n", "SOL", nsol);
         }
         gmx_ffclose(fpout);
-        /* use gmx_ffopen to generate backup of topinout */
-        fpout = gmx_ffopen(topinout, "w");
-        gmx_ffclose(fpout);
-        rename(temporary_filename, topinout);
+        make_backup(topinout);
+        gmx_file_rename(temporary_filename, topinout);
     }
 }
 
index 2ca5514005b934bce484410de85303e6402c4af7..896088cc1d0f984aa9482ad13873bd14ad6bedfb 100644 (file)
@@ -584,17 +584,71 @@ void gmx_tmpnam(char *buf)
      */
 #ifdef GMX_NATIVE_WINDOWS
     _mktemp(buf);
+    if (buf == NULL)
+    {
+        gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf,
+                  strerror(errno));
+    }
 #else
     int fd = mkstemp(buf);
 
     if (fd < 0)
     {
-        gmx_fatal(FARGS, "Creating temporary file %s: %s", buf,
+        gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf,
                   strerror(errno));
     }
     close(fd);
+
+#endif
+
+    /* name in Buf should now be OK and file is CLOSED */
+
+    return;
+}
+
+FILE *gmx_fopen_temporary(char *buf)
+{
+    int   i, len;
+    FILE *fpout = NULL;
+
+    if ((len = strlen(buf)) < 7)
+    {
+        gmx_fatal(FARGS, "Buf passed to gmx_fopentmp must be at least 7 bytes long");
+    }
+    for (i = len-6; (i < len); i++)
+    {
+        buf[i] = 'X';
+    }
+    /* mktemp is dangerous and we should use mkstemp instead, but
+     * since windows doesnt support it we have to separate the cases.
+     * 20090307: mktemp deprecated, use iso c++ _mktemp instead.
+     */
+#ifdef GMX_NATIVE_WINDOWS
+    _mktemp(buf);
+    if (buf == NULL)
+    {
+        gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf,
+                  strerror(errno));
+    }
+    if ((fpout = fopen(buf, "w")) == NULL)
+    {
+        gmx_fatal(FARGS, "Cannot open temporary file %s", buf);
+    }
+#else
+    int fd = mkstemp(buf);
+    if (fd < 0)
+    {
+        gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf,
+                  strerror(errno));
+    }
+    if ((fpout = fdopen(fd, "w")) == NULL)
+    {
+        gmx_fatal(FARGS, "Cannot open temporary file %s", buf);
+    }
 #endif
-    /* name in Buf should now be OK */
+    /* name in Buf should now be OK and file is open */
+
+    return fpout;
 }
 
 int gmx_file_rename(const char *oldname, const char *newname)
index e213c5d6ff8c474b5f4a49e0a93235706ecd20d1..1a964bf87f6854e506b29512132a78111ea17f0c 100644 (file)
@@ -177,6 +177,13 @@ char *low_gmxlibfn(const char *file, gmx_bool bAddCWD, gmx_bool bFatal);
 FILE *low_libopen(const char *file, gmx_bool bFatal);
 
 
+/*! \brief
+ * Creates unique name for temp file (wrapper around mkstemp) and opens it.
+ *
+ * \p buf should be at least 7 bytes long
+ */
+FILE *gmx_fopen_temporary(char *buf);
+
 /*! \brief
  * Creates unique name for temp file (wrapper around mkstemp).
  *
index 8ab330c2f6fcc256236178368bb5668d9b00b34b..2027cab9d16a66721a353b5a97a20e085ce6578a 100644 (file)
@@ -85,25 +85,11 @@ static void shell_comm(const char *title, const char *script, int nsleep)
     char  tmp[32];
 
     std::strcpy(tmp, "dialogXXXXXX");
-    gmx_tmpnam(tmp);
+    tfil = gmx_fopen_temporary(tmp);
 
-    if ((tfil = std::fopen(tmp, "w")) == NULL)
-    {
-        std::sprintf(tmp, "%ctmp%cdialogXXXXXX", DIR_SEPARATOR, DIR_SEPARATOR);
-        gmx_tmpnam(tmp);
-    }
-    else
-    {
-        std::fclose(tfil);
-    }
-    if ((tfil = std::fopen(tmp, "w")) == NULL)
-    {
-        gmx_fatal(FARGS, "Can not open tmp file %s", tmp);
-    }
-
-    std::fprintf(tfil, "%s\n", script);
-    std::fprintf(tfil, "sleep %d\n", nsleep);
-    std::fclose(tfil);
+    fprintf(tfil, "%s\n", script);
+    fprintf(tfil, "sleep %d\n", nsleep);
+    gmx_ffclose(tfil);
 
     std::sprintf(command, "xterm -title %s -e sh %s", title, tmp);
 #ifdef DEBUG
index b576a02f0555fe01a9f647e9e5e8f7c0fabb5876..177e787982b15b3ec4b50e44cc80085d48b4f9e5 100644 (file)
@@ -146,19 +146,10 @@ t_dlg *select_filter(t_x11 *x11, t_gmx *gmx)
         ht = 1+(gmx->filter->grps->nr+1)*2+3;
     }
     std::strcpy(tmpfile, "filterXXXXXX");
-    gmx_tmpnam(tmpfile);
+    tmp = gmx_fopen_temporary(tmpfile);
 #ifdef DEBUG
     std::fprintf(stderr, "file: %s\n", tmpfile);
 #endif
-    if ((tmp = std::fopen(tmpfile, "w")) == NULL)
-    {
-        std::sprintf(tmpfile, "%ctmp%cfilterXXXXXX", DIR_SEPARATOR, DIR_SEPARATOR);
-        gmx_tmpnam(tmpfile);
-        if ((tmp = std::fopen(tmpfile, "w")) == NULL)
-        {
-            gmx_fatal(FARGS, "Can not open tmp file %s", tmpfile);
-        }
-    }
     tlen = 1+ncol*(1+len);
     std::fprintf(tmp, "grid %d %d {\n\n", tlen, ht);
 
@@ -183,7 +174,7 @@ t_dlg *select_filter(t_x11 *x11, t_gmx *gmx)
     std::fprintf(tmp, "simple 1 %d %d 2 {\n", ht-3, tlen-2);
     std::fprintf(tmp, "defbutton %s %s %s %s %s\n", ok, ok, dummy, dummy, dummy);
     std::fprintf(tmp, "}\n\n}\n");
-    std::fclose(tmp);
+    gmx_ffclose(tmp);
 
     dlg = ReadDlg(x11, gmx->wd->self, title, tmpfile,
                   0, 0, true, false, FilterCB, gmx);