Apply patch from Alessandro Vesely for WINDOWS32-specific bug # 9748.
authorPaul Smith <psmith@gnu.org>
Wed, 6 Oct 2004 13:09:22 +0000 (13:09 +0000)
committerPaul Smith <psmith@gnu.org>
Wed, 6 Oct 2004 13:09:22 +0000 (13:09 +0000)
ChangeLog
job.c

index 51d599da383338d7edbc9052e726f730622167ee..fd5aaa3943d4a4bccdab5c3e6c632c8662535387 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2004-10-06  Paul D. Smith  <psmith@gnu.org>
+
+       Apply patch from Alessandro Vesely, provided with bug # 9748.
+       Fix use of tmpnam() to work with Borland C.
+
+       * job.c (construct_command_argv_internal) [WINDOWS32]: Remove
+       construction of a temporary filename, and call new function
+       create_batch_filename().
+       (create_batch_filename) [WINDOWS32]: New function to create a
+       temporary filename.
+
 2004-10-05  Boris Kolpackov  <boris@kolpackov.net>
 
        * read.c (record_target_var): Expand simple pattern-specific
diff --git a/job.c b/job.c
index c45889331ff72efc6e5e92949c0afb6ab8a9d83e..f198fc562da42e17c858e38869f5601b4dd0a476 100644 (file)
--- a/job.c
+++ b/job.c
@@ -239,7 +239,90 @@ unsigned long job_counter = 0;
 int
 w32_kill(int pid, int sig)
 {
-  return ((process_kill(pid, sig) == TRUE) ? 0 : -1);
+  return ((process_kill((HANDLE)pid, sig) == TRUE) ? 0 : -1);
+}
+
+/* This function creates a temporary file name with the given extension
+ * the unixy param controls both the extension and the path separator
+ * return an xmalloc'ed string of a newly created temp file or die.  */
+static char *
+create_batch_filename(char const *base, int unixy)
+{
+  const char *const ext = unixy ? "sh" : "bat";
+  const char *error = NULL;
+  char temp_path[MAXPATHLEN]; /* need to know its length */
+  unsigned path_size = GetTempPath(sizeof temp_path, temp_path);
+  int path_is_dot = 0;
+  unsigned uniq = 1;
+  const unsigned sizemax = strlen (base) + strlen (ext) + 10;
+
+  if (path_size == 0)
+    {
+      path_size = GetCurrentDirectory (sizeof temp_path, temp_path);
+      path_is_dot = 1;
+    }
+
+  while (path_size > 0 &&
+         path_size + sizemax < sizeof temp_path &&
+         uniq < 0x10000)
+    {
+      unsigned size = sprintf (temp_path + path_size,
+                               "%s%s-%x.%s",
+                               temp_path[path_size - 1] == '\\' ? "" : "\\",
+                               base, uniq, ext);
+      HANDLE h = CreateFile (temp_path,  /* file name */
+                             GENERIC_READ | GENERIC_WRITE, /* desired access */
+                             0,                            /* no share mode */
+                             NULL,                         /* default security attributes */
+                             CREATE_NEW,                   /* creation disposition */
+                             FILE_ATTRIBUTE_NORMAL |       /* flags and attributes */
+                             FILE_ATTRIBUTE_TEMPORARY,     /* we'll delete it */
+                             NULL);                        /* no template file */
+
+      if (h == INVALID_HANDLE_VALUE)
+        {
+          const DWORD er = GetLastError();
+
+          if (er == ERROR_FILE_EXISTS || er == ERROR_ALREADY_EXISTS)
+            ++uniq;
+
+          /* the temporary path is not guaranteed to exist */
+          else if (path_is_dot == 0)
+            {
+              path_size = GetCurrentDirectory (sizeof temp_path, temp_path);
+              path_is_dot = 1;
+            }
+
+          else
+            {
+              error = map_windows32_error_to_string (er);
+              break;
+            }
+        }
+      else
+        {
+          const unsigned final_size = path_size + size + 1;
+          char *const path = (char *) xmalloc (final_size);
+          memcpy (path, temp_path, final_size);
+          CloseHandle (h);
+          if (unixy)
+            {
+              char *p;
+              int ch;
+              for (p = path; (ch = *p) != 0; ++p)
+                if (ch == '\\')
+                  *p = '/';
+            }
+          return path; /* good return */
+        }
+    }
+
+  if (error == NULL)
+    error = _("Cannot create a temporary file\n");
+  fatal (NILF, error);
+
+  /* not reached */
+  return NULL;
 }
 #endif /* WINDOWS32 */
 
@@ -3249,26 +3332,10 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
       FILE* batch = NULL;
       int id = GetCurrentProcessId();
       PATH_VAR(fbuf);
-      char* fname = NULL;
 
       /* create a file name */
       sprintf(fbuf, "make%d", id);
-      fname = tempnam(".", fbuf);
-
-         /* create batch file name */
-      *batch_filename_ptr = xmalloc(strlen(fname) + 5);
-      strcpy(*batch_filename_ptr, fname);
-
-      /* make sure path name is in DOS backslash format */
-      if (!unixy_shell) {
-        fname = *batch_filename_ptr;
-        for (i = 0; fname[i] != '\0'; ++i)
-          if (fname[i] == '/')
-            fname[i] = '\\';
-        strcat(*batch_filename_ptr, ".bat");
-      } else {
-        strcat(*batch_filename_ptr, ".sh");
-      }
+      *batch_filename_ptr = create_batch_filename (fbuf, unixy_shell);
 
       DB (DB_JOBS, (_("Creating temporary batch file %s\n"),
                     *batch_filename_ptr));