]> granicus.if.org Git - check/commitdiff
If tmpfile() fails, try to make a unique file with tempnam() and getpid()
authorbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Sat, 28 Sep 2013 03:10:40 +0000 (03:10 +0000)
committerbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Sat, 28 Sep 2013 03:10:40 +0000 (03:10 +0000)
On systems where tmpfile() does not work, we try to fallback on
using tempnam() and fopen() to get a temporary unique file.

However, tempnam is not enough to get a unique name. Between
getting the name and opening the file, something else also
calling tempnam() could get the same name. It has been observed
on MinGW-w64 builds on Wine that this exact thing happens
if multiple instances of a unit tests are running concurrently.
To prevent two concurrent unit tests from getting the same file,
we append the pid to the file. The pid should be unique on the
system.

git-svn-id: svn+ssh://svn.code.sf.net/p/check/code/trunk@812 64e312b2-a51f-0410-8e61-82d0ca0eb02a

src/check_msg.c

index 2cb18b115d2b9a52964774d4ba9a60d85d659937..fcb63524d185c2a7345a36310619cedeeee09677 100644 (file)
@@ -190,14 +190,25 @@ open_tmp_file (void)
   /* also note that mkstemp is apparently a C90 replacement for tmpfile */
   /* perhaps all we need to do on Windows is set TMPDIR to whatever is
      stored in TEMP for tmpfile to work */
-  /* it's also not clear if we need _tempnam instead of tempnam on WIN32 */
   /* and finally, the "b" from "w+b" is ignored on OS X, not sure about WIN32 */
   FILE *file = tmpfile ();
   if (file == NULL)
     {
       char *tmp = getenv ("TEMP");
       char *tmp_file = tempnam (tmp, "check_");
-      file = fopen (tmp_file, "w+b");
+      /*
+       * Note, tempnam is not enough to get a unique name. Between
+       * getting the name and opening the file, something else also
+       * calling tempnam() could get the same name. It has been observed
+       * on MinGW-w64 builds on Wine that this exact thing happens
+       * if multiple instances of a unit tests are running concurrently.
+       * To prevent two concurrent unit tests from getting the same file,
+       * we append the pid to the file. The pid should be unique on the
+       * system.
+       */
+      char *uniq_tmp_file = ck_strdup_printf("%s.%d",tmp_file, getpid());
+      file = fopen (uniq_tmp_file, "w+b");
+      free(uniq_tmp_file);
       free (tmp_file);
     }
   return file;