[Gpg4win-commits] r729 - in trunk: . src

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Thu Feb 28 18:13:23 CET 2008


Author: marcus
Date: 2008-02-28 18:13:23 +0100 (Thu, 28 Feb 2008)
New Revision: 729

Modified:
   trunk/ChangeLog
   trunk/src/kleowrap.c
Log:
2008-02-28  Marcus Brinkmann  <marcus at g10code.de>

	* src/kleowrap.c: Use CreateProcess instead of spawn for ksycoca
	to suppress console window.


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-02-28 10:41:26 UTC (rev 728)
+++ trunk/ChangeLog	2008-02-28 17:13:23 UTC (rev 729)
@@ -1,3 +1,8 @@
+2008-02-28  Marcus Brinkmann  <marcus at g10code.de>
+
+	* src/kleowrap.c: Use CreateProcess instead of spawn for ksycoca
+	to suppress console window.
+
 2008-02-27  Marcus Brinkmann  <marcus at g10code.de>
 
 	* src/kleowrap.c: Include errno.h.

Modified: trunk/src/kleowrap.c
===================================================================
--- trunk/src/kleowrap.c	2008-02-28 10:41:26 UTC (rev 728)
+++ trunk/src/kleowrap.c	2008-02-28 17:13:23 UTC (rev 729)
@@ -1,4 +1,4 @@
-/* kleopatrawrap.c - Wrapper to call gpg udner Windows.
+/* kleowrap.c - Wrapper to call gpg under Windows.
  * Copyright (C) 2007, 2008 g10 Code GmbH
  *
  * This file is part of Gpg4win.
@@ -30,11 +30,201 @@
 #include <errno.h>
 
 
+#define DEBUG_W32_SPAWN 0
+
+
+static HANDLE
+w32_open_null (int for_write)
+{
+  HANDLE hfile;
+
+  hfile = CreateFile ("nul",
+                      for_write ? GENERIC_WRITE : GENERIC_READ,
+                      FILE_SHARE_READ | FILE_SHARE_WRITE,
+                      NULL, OPEN_EXISTING, 0, NULL);
+  return hfile;
+}
+
+
+char *
+stpcpy(char *a,const char *b)
+{
+    while( *b )
+	*a++ = *b++;
+    *a = 0;
+
+    return (char*)a;
+}
+
+
+/* Helper function to build_w32_commandline. */
+static char *
+build_w32_commandline_copy (char *buffer, const char *string)
+{
+  char *p = buffer;
+  const char *s;
+
+  if (!*string) /* Empty string. */
+    p = stpcpy (p, "\"\"");
+  else if (strpbrk (string, " \t\n\v\f\""))
+    {
+      /* Need top do some kind of quoting.  */
+      p = stpcpy (p, "\"");
+      for (s=string; *s; s++)
+        {
+          *p++ = *s;
+          if (*s == '\"')
+            *p++ = *s;
+        }
+      *p++ = '\"';
+      *p = 0;
+    }
+  else
+    p = stpcpy (p, string);
+
+  return p;
+}
+
+
+/* Build a command line for use with W32's CreateProcess.  On success
+   CMDLINE gets the address of a newly allocated string.  */
+static char *
+build_w32_commandline (const char *pgmname, const char * const *argv)
+{
+  int i, n;
+  const char *s;
+  char *buf, *p;
+
+  n = 0;
+  s = pgmname;
+  n += strlen (s) + 1 + 2;  /* (1 space, 2 quoting */
+  for (; *s; s++)
+    if (*s == '\"')
+      n++;  /* Need to double inner quotes.  */
+  for (i=0; (s=argv[i]); i++)
+    {
+      n += strlen (s) + 1 + 2;  /* (1 space, 2 quoting */
+      for (; *s; s++)
+        if (*s == '\"')
+          n++;  /* Need to double inner quotes.  */
+    }
+  n++;
+
+  buf = p = malloc (n);
+  if (! buf)
+    return NULL;
+
+  p = build_w32_commandline_copy (p, pgmname);
+  for (i = 0; argv[i]; i++) 
+    {
+      *p++ = ' ';
+      p = build_w32_commandline_copy (p, argv[i]);
+    }
+
+  return buf;
+}
+
+
+int
+spawn_process_and_wait (const char *pgmname, const char * const *argv)
+{
+  int err;
+  SECURITY_ATTRIBUTES sec_attr;
+  PROCESS_INFORMATION pi = 
+    {
+      NULL,      /* Returns process handle.  */
+      0,         /* Returns primary thread handle.  */
+      0,         /* Returns pid.  */
+      0          /* Returns tid.  */
+    };
+  STARTUPINFO si;
+  int cr_flags;
+  char *cmdline;
+  HANDLE proc;
+  int code;
+  DWORD exc;
+
+  /* Prepare security attributes.  */
+  memset (&sec_attr, 0, sizeof sec_attr);
+  sec_attr.nLength = sizeof sec_attr;
+  sec_attr.bInheritHandle = FALSE;
+  
+  /* Build the command line.  */
+  cmdline = build_w32_commandline (pgmname, argv);
+  if (! cmdline)
+    return -1; 
+
+  /* Start the process.  Note that we can't run the PREEXEC function
+     because this would change our own environment. */
+  memset (&si, 0, sizeof si);
+  si.cb = sizeof (si);
+  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+  si.wShowWindow = DEBUG_W32_SPAWN ? SW_SHOW : SW_MINIMIZE;
+  si.hStdInput = w32_open_null (0);
+  si.hStdOutput = w32_open_null (1);
+  si.hStdError = w32_open_null (1);
+
+  cr_flags = (CREATE_DEFAULT_ERROR_MODE
+              | DETACHED_PROCESS
+              | GetPriorityClass (GetCurrentProcess ())
+              | CREATE_SUSPENDED); 
+  if (!CreateProcess (pgmname,       /* Program to start.  */
+                      cmdline,       /* Command line arguments.  */
+                      &sec_attr,     /* Process security attributes.  */
+                      &sec_attr,     /* Thread security attributes.  */
+                      TRUE,          /* Inherit handles.  */
+                      cr_flags,      /* Creation flags.  */
+                      NULL,          /* Environment.  */
+                      NULL,          /* Use current drive/directory.  */
+                      &si,           /* Startup information. */
+                      &pi            /* Returns process information.  */
+                      ))
+    {
+      free (cmdline);
+      CloseHandle (si.hStdInput);
+      CloseHandle (si.hStdOutput);
+      CloseHandle (si.hStdError);
+      return -1;
+    }
+  free (cmdline);
+  cmdline = NULL;
+
+  /* Process has been created suspended; resume it now. */
+  ResumeThread (pi.hThread);
+  CloseHandle (pi.hThread); 
+
+  /* Wait for it to finish.  */
+
+  proc = pi.hProcess;
+  err = 0;
+
+  code = WaitForSingleObject (proc, INFINITE);
+  switch (code) 
+    {
+      case WAIT_OBJECT_0:
+        if (! GetExitCodeProcess (proc, &exc))
+	  err = -1;
+	else
+	  err = exc;
+	break;
+
+      default:
+	err = -1;
+        break;
+    }
+
+  CloseHandle (proc);
+
+  return err;
+}
+
+
 /* Assumes that the current working directory is the Gpg4win INSTDIR
    installation directory.  */
 int
 run_kbuildsycoca (void)
 {
+  const char *argv[1];
   int rc;
 
   if (! SetEnvironmentVariable ("XDG_DATA_DIRS", "share")
@@ -44,11 +234,11 @@
 	       "Could not set XDG environment variables\n");
       return -1;
     }
-  errno = 0;
-  rc = _spawnl (_P_WAIT, "kbuildsycoca4", "kbuildsycoca4", NULL);
+
+  argv[0] = NULL;
+  rc = spawn_process_and_wait ("kbuildsycoca4.exe", argv);
   if (rc)
-    fprintf (stderr, "Executing kbuildsycoca4.exe failed: %s\n",
-	     strerror (errno));
+    fprintf (stderr, "Executing kbuildsycoca4.exe failed: %i\n", rc);
 
   return rc;
 }
@@ -135,7 +325,7 @@
 
   if (!GetModuleFileNameA (NULL, pgm, sizeof (pgm) - 1))
     {
-      fprintf (stderr, "kleopatrawrap: error getting my own name: rc=%d\n",
+      fprintf (stderr, "kleowrap: error getting my own name: rc=%d\n",
                GetLastError());
       return 2;
     }
@@ -157,7 +347,7 @@
       && !strcmp(argv[1], "--version")
       && !strcmp(argv[2], "--version"))
     {
-      fputs ("kleopatrawrap (Gpg4win) " PACKAGE_VERSION " ;", stdout);
+      fputs ("kleowrap (Gpg4win) " PACKAGE_VERSION " ;", stdout);
       fputs (pgm, stdout);
       fputc ('\n', stdout);
       fflush (stdout);
@@ -179,7 +369,7 @@
   rc = _spawnv (_P_WAIT, pgm, (const char **) argv_quoted);
   if (rc < 0)
     {
-      fprintf (stderr, "kleopatrawrap: executing `%s' failed: %s\n",
+      fprintf (stderr, "kleowrap: executing `%s' failed: %s\n",
 	       pgm, strerror (errno));
       return 2;
     }
@@ -187,7 +377,7 @@
   return rc;
 
  leave:
-  fprintf (stderr, "kleopatrawrap: internal error parsing my own name `%s'\n",
+  fprintf (stderr, "kleowrap: internal error parsing my own name `%s'\n",
            pgm);
   return 2;
 }



More information about the Gpg4win-commits mailing list