In PSPP we are using the path_search function from the tmpdir module to 
determine the path for temporary files.
Windows users have complained that it puts temporary files in places they
consider to be inappropriate.  I did a bit of research, and found that the 
"normal" path on windows depends on exactly which version of windows it is.
So I came up with this patch, which uses the w32 native functions to get this 
path.

Our windows port maintainer has been using it for a few weeks now and hasn't
discovered any problems.

J'

-- 
PGP Public key ID: 1024D/2DE827B3 
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://pgp.mit.edu or any PGP keyserver for public key.

diff --git a/lib/tmpdir.c b/lib/tmpdir.c
index 5590ac3..ef77c9c 100644
--- a/lib/tmpdir.c
+++ b/lib/tmpdir.c
@@ -31,9 +31,15 @@
 # define __set_errno(Val) errno = (Val)
 #endif
 
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# define TMP_FALLBACK "\\"
+#else
+# define TMP_FALLBACK "/tmp"
+#endif
+
 #include <stdio.h>
 #ifndef P_tmpdir
-# define P_tmpdir "/tmp"
+# define P_tmpdir TMP_FALLBACK
 #endif
 
 #include <sys/stat.h>
@@ -49,6 +55,59 @@
 # define __secure_getenv getenv
 #endif
 
+
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+static DWORD length;
+static LPSTR str = NULL;
+
+static char *
+get_tmp_dir (void)
+{
+  DWORD l = 0;
+
+  if (NULL == str)
+    {
+      length = 255;
+      str = malloc (sizeof (*str) * length);
+      if ( str == NULL)
+	return NULL;
+      l = GetTempPathA (length, str);
+    }
+
+  if ( l == 0)
+    return NULL;
+
+  /* If this condition is true, then GetTempPath is 
+     asking for a larger buffer.  We must run it again
+     with the requested size. */
+  if ( l > length )
+    {
+      length = l;
+      free (str);
+      str = malloc (sizeof (*str) * length);
+      if ( str == NULL)
+	return NULL;
+
+      l = GetTempPathA (length, str);
+    }
+  if ( l == 0)
+    return NULL;
+  
+  return str;
+}
+#else
+static char *
+get_tmp_dir (void)
+{
+  return __secure_getenv ("TMPDIR");
+}
+#endif
+
+
 /* Pathname support.
    ISSLASH(C)           tests whether C is a directory separator character.
  */
@@ -96,7 +155,7 @@ path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
 
   if (try_tmpdir)
     {
-      d = __secure_getenv ("TMPDIR");
+      d = get_tmp_dir ();
       if (d != NULL && direxists (d))
         dir = d;
       else if (dir != NULL && direxists (dir))
@@ -108,8 +167,8 @@ path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
     {
       if (direxists (P_tmpdir))
         dir = P_tmpdir;
-      else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
-        dir = "/tmp";
+      else if (strcmp (P_tmpdir, TMP_FALLBACK) != 0 && direxists (TMP_FALLBACK))
+        dir = TMP_FALLBACK;
       else
         {
           __set_errno (ENOENT);

Attachment: signature.asc
Description: Digital signature

Reply via email to