2009-12-08 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / common / exechelp.c
1 /* exechelp.c - fork and exec helpers
2  * Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <signal.h>
28 #include <unistd.h> 
29 #include <fcntl.h>
30
31 #ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
32 #undef HAVE_PTH
33 #undef USE_GNU_PTH
34 #endif
35
36 #ifdef USE_GNU_PTH      
37 #include <pth.h>
38 #endif
39 #ifndef HAVE_W32_SYSTEM
40 #include <sys/wait.h>
41 #endif
42
43 #ifdef HAVE_GETRLIMIT
44 #include <sys/time.h>
45 #include <sys/resource.h>
46 #endif /*HAVE_GETRLIMIT*/
47
48 #ifdef HAVE_STAT
49 # include <sys/stat.h>
50 #endif
51
52
53 #include "util.h"
54 #include "i18n.h"
55 #include "sysutils.h"
56 #include "exechelp.h"
57
58 /* Define to 1 do enable debugging.  */
59 #define DEBUG_W32_SPAWN 1
60
61
62 /* We have the usual problem here: Some modules are linked against pth
63    and some are not.  However we want to use pth_fork and pth_waitpid
64    here. Using a weak symbol works but is not portable - we should
65    provide a an explicit dummy pth module instead of using the
66    pragma.  */ 
67 #ifndef _WIN32
68 #pragma weak pth_fork
69 #pragma weak pth_waitpid
70 #endif
71
72 #ifdef HAVE_W32_SYSTEM
73 /* It seems Vista doesn't grok X_OK and so fails access() tests.
74    Previous versions interpreted X_OK as F_OK anyway, so we'll just
75    use F_OK directly. */
76 #undef X_OK
77 #define X_OK F_OK
78 #endif /* HAVE_W32_SYSTEM */
79
80
81 #ifdef HAVE_W32_SYSTEM
82 /* We assume that a HANDLE can be represented by an int which should
83    be true for all i386 systems (HANDLE is defined as void *) and
84    these are the only systems for which Windows is available.  Further
85    we assume that -1 denotes an invalid handle.  */
86 # define fd_to_handle(a)  ((HANDLE)(a))
87 # define handle_to_fd(a)  ((int)(a))
88 # define pid_to_handle(a) ((HANDLE)(a))
89 # define handle_to_pid(a) ((int)(a))
90 #endif
91
92
93 /* Return the maximum number of currently allowed open file
94    descriptors.  Only useful on POSIX systems but returns a value on
95    other systems too.  */
96 int
97 get_max_fds (void)
98 {
99   int max_fds = -1;
100 #ifdef HAVE_GETRLIMIT
101   struct rlimit rl;
102
103 # ifdef RLIMIT_NOFILE
104   if (!getrlimit (RLIMIT_NOFILE, &rl))
105     max_fds = rl.rlim_max;
106 # endif
107
108 # ifdef RLIMIT_OFILE
109   if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
110     max_fds = rl.rlim_max;
111
112 # endif
113 #endif /*HAVE_GETRLIMIT*/
114
115 #ifdef _SC_OPEN_MAX
116   if (max_fds == -1)
117     {
118       long int scres = sysconf (_SC_OPEN_MAX);
119       if (scres >= 0)
120         max_fds = scres;
121     }
122 #endif
123
124 #ifdef _POSIX_OPEN_MAX
125   if (max_fds == -1)
126     max_fds = _POSIX_OPEN_MAX;
127 #endif
128
129 #ifdef OPEN_MAX
130   if (max_fds == -1)
131     max_fds = OPEN_MAX;
132 #endif
133
134   if (max_fds == -1)
135     max_fds = 256;  /* Arbitrary limit.  */
136
137   return max_fds;
138 }
139
140
141 /* Close all file descriptors starting with descriptor FIRST.  If
142    EXCEPT is not NULL, it is expected to be a list of file descriptors
143    which shall not be closed.  This list shall be sorted in ascending
144    order with the end marked by -1.  */
145 void
146 close_all_fds (int first, int *except)
147 {
148   int max_fd = get_max_fds ();
149   int fd, i, except_start;
150
151   if (except)
152     {
153       except_start = 0;
154       for (fd=first; fd < max_fd; fd++)
155         {
156           for (i=except_start; except[i] != -1; i++)
157             {
158               if (except[i] == fd)
159                 {
160                   /* If we found the descriptor in the exception list
161                      we can start the next compare run at the next
162                      index because the exception list is ordered.  */
163                 except_start = i + 1;
164                 break;
165                 }
166             }
167           if (except[i] == -1)
168             close (fd);
169         }
170     }
171   else
172     {
173       for (fd=first; fd < max_fd; fd++)
174         close (fd);
175     }
176
177   errno = 0;
178 }
179
180
181 /* Returns an array with all currently open file descriptors.  The end
182    of the array is marked by -1.  The caller needs to release this
183    array using the *standard free* and not with xfree.  This allow the
184    use of this fucntion right at startup even before libgcrypt has
185    been initialized.  Returns NULL on error and sets ERRNO
186    accordingly.  */
187 int *
188 get_all_open_fds (void)
189 {
190   int *array;
191   size_t narray;
192   int fd, max_fd, idx;
193 #ifndef HAVE_STAT
194   array = calloc (1, sizeof *array);
195   if (array)
196     array[0] = -1;
197 #else /*HAVE_STAT*/
198   struct stat statbuf;
199
200   max_fd = get_max_fds ();
201   narray = 32;  /* If you change this change also t-exechelp.c.  */
202   array = calloc (narray, sizeof *array);
203   if (!array)
204     return NULL;
205   
206   /* Note:  The list we return is ordered.  */
207   for (idx=0, fd=0; fd < max_fd; fd++)
208     if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
209       {
210         if (idx+1 >= narray)
211           {
212             int *tmp;
213
214             narray += (narray < 256)? 32:256;
215             tmp = realloc (array, narray * sizeof *array);
216             if (!tmp)
217               {
218                 free (array);
219                 return NULL;
220               }
221             array = tmp;
222           }
223         array[idx++] = fd;
224       }
225   array[idx] = -1;
226 #endif /*HAVE_STAT*/
227   return array;
228 }
229
230
231
232 #ifdef HAVE_W32_SYSTEM
233 /* Helper function to build_w32_commandline. */
234 static char *
235 build_w32_commandline_copy (char *buffer, const char *string)
236 {
237   char *p = buffer;
238   const char *s;
239
240   if (!*string) /* Empty string. */
241     p = stpcpy (p, "\"\"");
242   else if (strpbrk (string, " \t\n\v\f\""))
243     {
244       /* Need top do some kind of quoting.  */
245       p = stpcpy (p, "\"");
246       for (s=string; *s; s++)
247         {
248           *p++ = *s;
249           if (*s == '\"')
250             *p++ = *s;
251         }
252       *p++ = '\"';
253       *p = 0;
254     }
255   else
256     p = stpcpy (p, string);
257
258   return p;
259 }
260
261 /* Build a command line for use with W32's CreateProcess.  On success
262    CMDLINE gets the address of a newly allocated string.  */
263 static gpg_error_t
264 build_w32_commandline (const char *pgmname, const char * const *argv, 
265                        char **cmdline)
266 {
267   int i, n;
268   const char *s;
269   char *buf, *p;
270
271   *cmdline = NULL;
272   n = 0;
273   s = pgmname;
274   n += strlen (s) + 1 + 2;  /* (1 space, 2 quoting */
275   for (; *s; s++)
276     if (*s == '\"')
277       n++;  /* Need to double inner quotes.  */
278   for (i=0; (s=argv[i]); i++)
279     {
280       n += strlen (s) + 1 + 2;  /* (1 space, 2 quoting */
281       for (; *s; s++)
282         if (*s == '\"')
283           n++;  /* Need to double inner quotes.  */
284     }
285   n++;
286
287   buf = p = xtrymalloc (n);
288   if (!buf)
289     return gpg_error_from_syserror ();
290
291   p = build_w32_commandline_copy (p, pgmname);
292   for (i=0; argv[i]; i++) 
293     {
294       *p++ = ' ';
295       p = build_w32_commandline_copy (p, argv[i]);
296     }
297
298   *cmdline= buf;
299   return 0;
300 }
301 #endif /*HAVE_W32_SYSTEM*/
302
303
304 #ifdef HAVE_W32_SYSTEM
305 /* Create  pipe where the write end is inheritable.  */
306 static int
307 create_inheritable_pipe_w (int filedes[2])
308 {
309   HANDLE r, w, h;
310   SECURITY_ATTRIBUTES sec_attr;
311
312   memset (&sec_attr, 0, sizeof sec_attr );
313   sec_attr.nLength = sizeof sec_attr;
314   sec_attr.bInheritHandle = FALSE;
315     
316   if (!CreatePipe (&r, &w, &sec_attr, 0))
317     return -1;
318
319   if (!DuplicateHandle (GetCurrentProcess(), w,
320                         GetCurrentProcess(), &h, 0,
321                         TRUE, DUPLICATE_SAME_ACCESS ))
322     {
323       log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
324       CloseHandle (r);
325       CloseHandle (w);
326       return -1;
327     }
328   CloseHandle (w);
329   w = h;
330
331   filedes[0] = handle_to_fd (r);
332   filedes[1] = handle_to_fd (w);
333   return 0;
334 }
335
336 /* Create  pipe where the read end is inheritable.  */
337 static int
338 create_inheritable_pipe_r (int filedes[2])
339 {
340   HANDLE r, w, h;
341   SECURITY_ATTRIBUTES sec_attr;
342
343   memset (&sec_attr, 0, sizeof sec_attr );
344   sec_attr.nLength = sizeof sec_attr;
345   sec_attr.bInheritHandle = FALSE;
346     
347   if (!CreatePipe (&r, &w, &sec_attr, 0))
348     return -1;
349
350   if (!DuplicateHandle (GetCurrentProcess(), r,
351                         GetCurrentProcess(), &h, 0,
352                         TRUE, DUPLICATE_SAME_ACCESS ))
353     {
354       log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
355       CloseHandle (r);
356       CloseHandle (w);
357       return -1;
358     }
359   CloseHandle (r);
360   r = h;
361
362   filedes[0] = handle_to_fd (r);
363   filedes[1] = handle_to_fd (w);
364   return 0;
365 }
366 #endif /*HAVE_W32_SYSTEM*/
367
368
369 #ifdef HAVE_W32_SYSTEM
370 static HANDLE
371 w32_open_null (int for_write)
372 {
373   HANDLE hfile;
374
375   hfile = CreateFile ("nul",
376                       for_write? GENERIC_WRITE : GENERIC_READ,
377                       FILE_SHARE_READ | FILE_SHARE_WRITE,
378                       NULL, OPEN_EXISTING, 0, NULL);
379   if (hfile == INVALID_HANDLE_VALUE)
380     log_debug ("can't open `nul': %s\n", w32_strerror (-1));
381   return hfile;
382 }
383 #endif /*HAVE_W32_SYSTEM*/
384
385
386 #ifndef HAVE_W32_SYSTEM
387 /* The exec core used right after the fork. This will never return. */
388 static void
389 do_exec (const char *pgmname, const char *argv[],
390          int fd_in, int fd_out, int fd_err,
391          void (*preexec)(void) )
392 {
393   char **arg_list;
394   int i, j;
395   int fds[3];
396
397   fds[0] = fd_in;
398   fds[1] = fd_out;
399   fds[2] = fd_err;
400
401   /* Create the command line argument array.  */
402   i = 0;
403   if (argv)
404     while (argv[i])
405       i++;
406   arg_list = xcalloc (i+2, sizeof *arg_list);
407   arg_list[0] = strrchr (pgmname, '/');
408   if (arg_list[0])
409     arg_list[0]++;
410   else
411     arg_list[0] = xstrdup (pgmname);
412   if (argv)
413     for (i=0,j=1; argv[i]; i++, j++)
414       arg_list[j] = (char*)argv[i];
415
416   /* Assign /dev/null to unused FDs. */
417   for (i=0; i <= 2; i++)
418     {
419       if (fds[i] == -1 )
420         {
421           fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
422           if (fds[i] == -1)
423             log_fatal ("failed to open `%s': %s\n",
424                        "/dev/null", strerror (errno));
425         }
426     }
427
428   /* Connect the standard files.  */
429   for (i=0; i <= 2; i++)
430     {
431       if (fds[i] != i && dup2 (fds[i], i) == -1)
432         log_fatal ("dup2 std%s failed: %s\n",
433                    i==0?"in":i==1?"out":"err", strerror (errno));
434     }
435
436   /* Close all other files. */
437   close_all_fds (3, NULL);
438   
439   if (preexec)
440     preexec ();
441   execv (pgmname, arg_list);
442   /* No way to print anything, as we have closed all streams. */
443   _exit (127);
444 }
445 #endif /*!HAVE_W32_SYSTEM*/
446
447
448 /* Portable function to create a pipe.  Under Windows the write end is
449    inheritable.  */
450 gpg_error_t
451 gnupg_create_inbound_pipe (int filedes[2])
452 {
453   gpg_error_t err = 0;
454 #if HAVE_W32_SYSTEM
455   int fds[2];
456
457   filedes[0] = filedes[1] = -1;
458   err = gpg_error (GPG_ERR_GENERAL);
459   if (!create_inheritable_pipe_w (fds))
460     {
461       filedes[0] = _open_osfhandle (fds[0], 0);
462       if (filedes[0] == -1)
463         {
464           log_error ("failed to translate osfhandle %p\n", (void*)fds[0]);
465           CloseHandle (fd_to_handle (fds[1]));
466         }
467       else 
468         {
469           filedes[1] = _open_osfhandle (fds[1], 1);
470           if (filedes[1] == -1)
471             {
472               log_error ("failed to translate osfhandle %p\n", (void*)fds[1]);
473               close (filedes[0]);
474               filedes[0] = -1;
475               CloseHandle (fd_to_handle (fds[1]));
476             }
477           else
478             err = 0;
479         }
480     }
481 #else
482   if (pipe (filedes) == -1)
483     {
484       err = gpg_error_from_syserror ();
485       filedes[0] = filedes[1] = -1;
486     }
487 #endif
488   return err;
489 }
490
491
492 /* Portable function to create a pipe.  Under Windows the read end is
493    inheritable.  */
494 gpg_error_t
495 gnupg_create_outbound_pipe (int filedes[2])
496 {
497   gpg_error_t err = 0;
498 #if HAVE_W32_SYSTEM
499   int fds[2];
500
501   filedes[0] = filedes[1] = -1;
502   err = gpg_error (GPG_ERR_GENERAL);
503   if (!create_inheritable_pipe_r (fds))
504     {
505       filedes[0] = _open_osfhandle (fds[0], 0);
506       if (filedes[0] == -1)
507         {
508           log_error ("failed to translate osfhandle %p\n", (void*)fds[0]);
509           CloseHandle (fd_to_handle (fds[1]));
510         }
511       else 
512         {
513           filedes[1] = _open_osfhandle (fds[1], 1);
514           if (filedes[1] == -1)
515             {
516               log_error ("failed to translate osfhandle %p\n", (void*)fds[1]);
517               close (filedes[0]);
518               filedes[0] = -1;
519               CloseHandle (fd_to_handle (fds[1]));
520             }
521           else
522             err = 0;
523         }
524     }
525 #else
526   if (pipe (filedes) == -1)
527     {
528       err = gpg_error_from_syserror ();
529       filedes[0] = filedes[1] = -1;
530     }
531 #endif
532   return err;
533 }
534
535
536 /* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
537    stdin, write the output to OUTFILE, return a new stream in
538    STATUSFILE for stderr and the pid of the process in PID. The
539    arguments for the process are expected in the NULL terminated array
540    ARGV.  The program name itself should not be included there.  If
541    PREEXEC is not NULL, that function will be called right before the
542    exec.  Calling gnupg_wait_process is required.
543
544    FLAGS is a bit vector with just one bit defined for now:
545
546    Bit 7: If set the process will be started as a background process.
547           This flag is only useful under W32 systems, so that no new
548           console is created and pops up a console window when
549           starting the server
550  
551    Bit 6: On W32 run AllowSetForegroundWindow for the child.  Due to
552           error problems this actually allows SetForegroundWindow for
553           childs of this process.
554
555    Returns 0 on success or an error code. */
556 gpg_error_t
557 gnupg_spawn_process (const char *pgmname, const char *argv[],
558                      FILE *infile, FILE *outfile,
559                      void (*preexec)(void), unsigned int flags,
560                      FILE **statusfile, pid_t *pid)
561 {
562 #ifdef HAVE_W32_SYSTEM
563   gpg_error_t err;
564   SECURITY_ATTRIBUTES sec_attr;
565   PROCESS_INFORMATION pi = 
566     {
567       NULL,      /* Returns process handle.  */
568       0,         /* Returns primary thread handle.  */
569       0,         /* Returns pid.  */
570       0          /* Returns tid.  */
571     };
572   STARTUPINFO si;
573   int cr_flags;
574   char *cmdline;
575   int fd, fdout, rp[2];
576
577   (void)preexec;
578
579   /* Setup return values.  */
580   *statusfile = NULL;
581   *pid = (pid_t)(-1);
582   fflush (infile);
583   rewind (infile);
584   fd = _get_osfhandle (fileno (infile));
585   fdout = _get_osfhandle (fileno (outfile));
586   if (fd == -1 || fdout == -1)
587     log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
588
589   /* Prepare security attributes.  */
590   memset (&sec_attr, 0, sizeof sec_attr );
591   sec_attr.nLength = sizeof sec_attr;
592   sec_attr.bInheritHandle = FALSE;
593   
594   /* Build the command line.  */
595   err = build_w32_commandline (pgmname, argv, &cmdline);
596   if (err)
597     return err; 
598
599   /* Create a pipe.  */
600   if (create_inheritable_pipe_w (rp))
601     {
602       err = gpg_error (GPG_ERR_GENERAL);
603       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
604       xfree (cmdline);
605       return err;
606     }
607   
608   /* Start the process.  Note that we can't run the PREEXEC function
609      because this would change our own environment. */
610   memset (&si, 0, sizeof si);
611   si.cb = sizeof (si);
612   si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
613   si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
614   si.hStdInput  = fd_to_handle (fd);
615   si.hStdOutput = fd_to_handle (fdout);
616   si.hStdError  = fd_to_handle (rp[1]);
617
618   cr_flags = (CREATE_DEFAULT_ERROR_MODE
619               | ((flags & 128)? DETACHED_PROCESS : 0)
620               | GetPriorityClass (GetCurrentProcess ())
621               | CREATE_SUSPENDED); 
622 /*   log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */
623   if (!CreateProcess (pgmname,       /* Program to start.  */
624                       cmdline,       /* Command line arguments.  */
625                       &sec_attr,     /* Process security attributes.  */
626                       &sec_attr,     /* Thread security attributes.  */
627                       TRUE,          /* Inherit handles.  */
628                       cr_flags,      /* Creation flags.  */
629                       NULL,          /* Environment.  */
630                       NULL,          /* Use current drive/directory.  */
631                       &si,           /* Startup information. */
632                       &pi            /* Returns process information.  */
633                       ))
634     {
635       log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
636       xfree (cmdline);
637       CloseHandle (fd_to_handle (rp[0]));
638       CloseHandle (fd_to_handle (rp[1]));
639       return gpg_error (GPG_ERR_GENERAL);
640     }
641   xfree (cmdline);
642   cmdline = NULL;
643
644   /* Close the other end of the pipe.  */
645   CloseHandle (fd_to_handle (rp[1]));
646   
647 /*   log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */
648 /*              " dwProcessID=%d dwThreadId=%d\n", */
649 /*              pi.hProcess, pi.hThread, */
650 /*              (int) pi.dwProcessId, (int) pi.dwThreadId); */
651   
652   /* Fixme: For unknown reasons AllowSetForegroundWindow returns an
653      invalid argument error if we pass the correct processID to
654      it.  As a workaround we use -1 (ASFW_ANY).  */
655   if ( (flags & 64) )
656     gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/);
657
658   /* Process has been created suspended; resume it now. */
659   ResumeThread (pi.hThread);
660   CloseHandle (pi.hThread); 
661
662   {
663     int x;
664
665     x = _open_osfhandle (rp[0], 0);
666     if (x == -1)
667       log_error ("failed to translate osfhandle %p\n", (void*)rp[0] );
668     else 
669       *statusfile = fdopen (x, "r");
670   }
671   if (!*statusfile)
672     {
673       err = gpg_error_from_syserror ();
674       log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err));
675       CloseHandle (pi.hProcess);
676       return err;
677     }
678
679   *pid = handle_to_pid (pi.hProcess);
680   return 0;
681
682 #else /* !HAVE_W32_SYSTEM */
683   gpg_error_t err;
684   int fd, fdout, rp[2];
685
686   (void)flags; /* Currently not used.  */
687
688   *statusfile = NULL;
689   *pid = (pid_t)(-1);
690   fflush (infile);
691   rewind (infile);
692   fd = fileno (infile);
693   fdout = fileno (outfile);
694   if (fd == -1 || fdout == -1)
695     log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
696
697   if (pipe (rp) == -1)
698     {
699       err = gpg_error_from_syserror ();
700       log_error (_("error creating a pipe: %s\n"), strerror (errno));
701       return err;
702     }
703
704 #ifdef USE_GNU_PTH      
705   *pid = pth_fork? pth_fork () : fork ();
706 #else
707   *pid = fork ();
708 #endif
709   if (*pid == (pid_t)(-1))
710     {
711       err = gpg_error_from_syserror ();
712       log_error (_("error forking process: %s\n"), strerror (errno));
713       close (rp[0]);
714       close (rp[1]);
715       return err;
716     }
717
718   if (!*pid)
719     { 
720       gcry_control (GCRYCTL_TERM_SECMEM);
721       /* Run child. */
722       do_exec (pgmname, argv, fd, fdout, rp[1], preexec);
723       /*NOTREACHED*/
724     }
725
726   /* Parent. */
727   close (rp[1]);
728
729   *statusfile = fdopen (rp[0], "r");
730   if (!*statusfile)
731     {
732       err = gpg_error_from_syserror ();
733       log_error (_("can't fdopen pipe for reading: %s\n"), strerror (errno));
734       kill (*pid, SIGTERM);
735       *pid = (pid_t)(-1);
736       return err;
737     }
738
739   return 0;
740 #endif /* !HAVE_W32_SYSTEM */
741 }
742
743
744
745 /* Simplified version of gnupg_spawn_process.  This function forks and
746    then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
747    and ERRFD to stderr (any of them may be -1 to connect them to
748    /dev/null).  The arguments for the process are expected in the NULL
749    terminated array ARGV.  The program name itself should not be
750    included there.  Calling gnupg_wait_process is required.
751
752    Returns 0 on success or an error code. */
753 gpg_error_t
754 gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
755                         int infd, int outfd, int errfd, pid_t *pid)
756 {
757 #ifdef HAVE_W32_SYSTEM
758   gpg_error_t err;
759   SECURITY_ATTRIBUTES sec_attr;
760   PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
761   STARTUPINFO si;
762   char *cmdline;
763   int i;
764   HANDLE stdhd[3];
765
766   /* Setup return values.  */
767   *pid = (pid_t)(-1);
768
769   /* Prepare security attributes.  */
770   memset (&sec_attr, 0, sizeof sec_attr );
771   sec_attr.nLength = sizeof sec_attr;
772   sec_attr.bInheritHandle = FALSE;
773   
774   /* Build the command line.  */
775   err = build_w32_commandline (pgmname, argv, &cmdline);
776   if (err)
777     return err; 
778
779   memset (&si, 0, sizeof si);
780   si.cb = sizeof (si);
781   si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
782   si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
783   stdhd[0] = infd  == -1? w32_open_null (0) : INVALID_HANDLE_VALUE;
784   stdhd[1] = outfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE;
785   stdhd[2] = errfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE;
786   si.hStdInput  = infd  == -1? stdhd[0] : (void*)_get_osfhandle (infd);
787   si.hStdOutput = outfd == -1? stdhd[1] : (void*)_get_osfhandle (outfd);
788   si.hStdError  = errfd == -1? stdhd[2] : (void*)_get_osfhandle (errfd);
789
790 /*   log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */
791   if (!CreateProcess (pgmname,       /* Program to start.  */
792                       cmdline,       /* Command line arguments.  */
793                       &sec_attr,     /* Process security attributes.  */
794                       &sec_attr,     /* Thread security attributes.  */
795                       TRUE,          /* Inherit handles.  */
796                       (CREATE_DEFAULT_ERROR_MODE
797                        | GetPriorityClass (GetCurrentProcess ())
798                        | CREATE_SUSPENDED | DETACHED_PROCESS),
799                       NULL,          /* Environment.  */
800                       NULL,          /* Use current drive/directory.  */
801                       &si,           /* Startup information. */
802                       &pi            /* Returns process information.  */
803                       ))
804     {
805       log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
806       err = gpg_error (GPG_ERR_GENERAL);
807     }
808   else
809     err = 0;
810   xfree (cmdline);
811   for (i=0; i < 3; i++)
812     if (stdhd[i] != INVALID_HANDLE_VALUE)
813       CloseHandle (stdhd[i]);
814   if (err)
815     return err;
816
817 /*   log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */
818 /*              " dwProcessID=%d dwThreadId=%d\n", */
819 /*              pi.hProcess, pi.hThread, */
820 /*              (int) pi.dwProcessId, (int) pi.dwThreadId); */
821
822   /* Process has been created suspended; resume it now. */
823   ResumeThread (pi.hThread);
824   CloseHandle (pi.hThread); 
825
826   *pid = handle_to_pid (pi.hProcess);
827   return 0;
828
829 #else /* !HAVE_W32_SYSTEM */
830   gpg_error_t err;
831
832 #ifdef USE_GNU_PTH      
833   *pid = pth_fork? pth_fork () : fork ();
834 #else
835   *pid = fork ();
836 #endif
837   if (*pid == (pid_t)(-1))
838     {
839       err = gpg_error_from_syserror ();
840       log_error (_("error forking process: %s\n"), strerror (errno));
841       return err;
842     }
843
844   if (!*pid)
845     { 
846       gcry_control (GCRYCTL_TERM_SECMEM);
847       /* Run child. */
848       do_exec (pgmname, argv, infd, outfd, errfd, NULL);
849       /*NOTREACHED*/
850     }
851
852   return 0;
853 #endif /* !HAVE_W32_SYSTEM */
854 }
855
856
857 /* Wait for the process identified by PID to terminate. PGMNAME should
858    be the same as supplied to the spawn function and is only used for
859    diagnostics. Returns 0 if the process succeeded, GPG_ERR_GENERAL
860    for any failures of the spawned program or other error codes.  If
861    EXITCODE is not NULL the exit code of the process is stored at this
862    address or -1 if it could not be retrieved. */
863 gpg_error_t
864 gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode)
865 {
866   gpg_err_code_t ec;
867
868 #ifdef HAVE_W32_SYSTEM
869   HANDLE proc = fd_to_handle (pid);
870   int code;
871   DWORD exc;
872
873   if (exitcode)
874     *exitcode = -1;
875
876   if (pid == (pid_t)(-1))
877     return gpg_error (GPG_ERR_INV_VALUE);
878
879   /* FIXME: We should do a pth_waitpid here.  However this has not yet
880      been implemented.  A special W32 pth system call would even be
881      better.  */
882   code = WaitForSingleObject (proc, INFINITE);
883   switch (code) 
884     {
885       case WAIT_FAILED:
886         log_error (_("waiting for process %d to terminate failed: %s\n"),
887                    (int)pid, w32_strerror (-1));
888         ec = GPG_ERR_GENERAL;
889         break;
890
891       case WAIT_OBJECT_0:
892         if (!GetExitCodeProcess (proc, &exc))
893           {
894             log_error (_("error getting exit code of process %d: %s\n"),
895                          (int)pid, w32_strerror (-1) );
896             ec = GPG_ERR_GENERAL;
897           }
898         else if (exc)
899           {
900             log_error (_("error running `%s': exit status %d\n"),
901                        pgmname, (int)exc );
902             if (exitcode)
903               *exitcode = (int)exc;
904             ec = GPG_ERR_GENERAL;
905           }
906         else
907           {
908             if (exitcode)
909               *exitcode = 0;
910             ec = 0;
911           }
912         CloseHandle (proc);
913         break;
914
915       default:
916         log_error ("WaitForSingleObject returned unexpected "
917                    "code %d for pid %d\n", code, (int)pid );
918         ec = GPG_ERR_GENERAL;
919         break;
920     }
921
922 #else /* !HAVE_W32_SYSTEM */
923   int i, status;
924
925   if (exitcode)
926     *exitcode = -1;
927
928   if (pid == (pid_t)(-1))
929     return gpg_error (GPG_ERR_INV_VALUE);
930
931 #ifdef USE_GNU_PTH
932   i = pth_waitpid ? pth_waitpid (pid, &status, 0) : waitpid (pid, &status, 0);
933 #else
934   while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
935     ;
936 #endif
937   if (i == (pid_t)(-1))
938     {
939       log_error (_("waiting for process %d to terminate failed: %s\n"),
940                  (int)pid, strerror (errno));
941       ec = gpg_err_code_from_errno (errno);
942     }
943   else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
944     {
945       log_error (_("error running `%s': probably not installed\n"), pgmname);
946       ec = GPG_ERR_CONFIGURATION;
947     }
948   else if (WIFEXITED (status) && WEXITSTATUS (status))
949     {
950       log_error (_("error running `%s': exit status %d\n"), pgmname,
951                  WEXITSTATUS (status));
952       if (exitcode)
953         *exitcode = WEXITSTATUS (status);
954       ec = GPG_ERR_GENERAL;
955     }
956   else if (!WIFEXITED (status))
957     {
958       log_error (_("error running `%s': terminated\n"), pgmname);
959       ec = GPG_ERR_GENERAL;
960     }
961   else 
962     {
963       if (exitcode)
964         *exitcode = 0;
965       ec = 0;
966     }
967 #endif /* !HAVE_W32_SYSTEM */
968
969   return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
970 }
971
972
973 /* Spawn a new process and immediatley detach from it.  The name of
974    the program to exec is PGMNAME and its arguments are in ARGV (the
975    programname is automatically passed as first argument).
976    Environment strings in ENVP are set.  An error is returned if
977    pgmname is not executable; to make this work it is necessary to
978    provide an absolute file name.  All standard file descriptors are
979    connected to /dev/null. */
980 gpg_error_t
981 gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
982                               const char *envp[] )
983 {
984 #ifdef HAVE_W32_SYSTEM
985   gpg_error_t err;
986   SECURITY_ATTRIBUTES sec_attr;
987   PROCESS_INFORMATION pi = 
988     {
989       NULL,      /* Returns process handle.  */
990       0,         /* Returns primary thread handle.  */
991       0,         /* Returns pid.  */
992       0          /* Returns tid.  */
993     };
994   STARTUPINFO si;
995   int cr_flags;
996   char *cmdline;
997
998
999   /* FIXME: We don't make use of ENVP yet.  It is currently only used
1000      to pass the GPG_AGENT_INFO variable to gpg-agent.  As the default
1001      on windows is to use a standard socket, this does not really
1002      matter.  */
1003   (void)envp;
1004
1005   if (access (pgmname, X_OK))
1006     return gpg_error_from_syserror ();
1007
1008   /* Prepare security attributes.  */
1009   memset (&sec_attr, 0, sizeof sec_attr );
1010   sec_attr.nLength = sizeof sec_attr;
1011   sec_attr.bInheritHandle = FALSE;
1012   
1013   /* Build the command line.  */
1014   err = build_w32_commandline (pgmname, argv, &cmdline);
1015   if (err)
1016     return err; 
1017
1018   /* Start the process.  */
1019   memset (&si, 0, sizeof si);
1020   si.cb = sizeof (si);
1021   si.dwFlags = STARTF_USESHOWWINDOW;
1022   si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
1023
1024   cr_flags = (CREATE_DEFAULT_ERROR_MODE
1025               | GetPriorityClass (GetCurrentProcess ())
1026               | CREATE_NEW_PROCESS_GROUP
1027               | DETACHED_PROCESS); 
1028 /*   log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n", */
1029 /*              pgmname, cmdline); */
1030   if (!CreateProcess (pgmname,       /* Program to start.  */
1031                       cmdline,       /* Command line arguments.  */
1032                       &sec_attr,     /* Process security attributes.  */
1033                       &sec_attr,     /* Thread security attributes.  */
1034                       FALSE,         /* Inherit handles.  */
1035                       cr_flags,      /* Creation flags.  */
1036                       NULL,          /* Environment.  */
1037                       NULL,          /* Use current drive/directory.  */
1038                       &si,           /* Startup information. */
1039                       &pi            /* Returns process information.  */
1040                       ))
1041     {
1042       log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1));
1043       xfree (cmdline);
1044       return gpg_error (GPG_ERR_GENERAL);
1045     }
1046   xfree (cmdline);
1047   cmdline = NULL;
1048
1049 /*   log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p" */
1050 /*              " dwProcessID=%d dwThreadId=%d\n", */
1051 /*              pi.hProcess, pi.hThread, */
1052 /*              (int) pi.dwProcessId, (int) pi.dwThreadId); */
1053
1054   CloseHandle (pi.hThread); 
1055
1056   return 0;
1057
1058 #else
1059   pid_t pid;
1060   int i;
1061
1062   if (getuid() != geteuid())
1063     return gpg_error (GPG_ERR_BUG);
1064
1065   if (access (pgmname, X_OK))
1066     return gpg_error_from_syserror ();
1067
1068 #ifdef USE_GNU_PTH      
1069   pid = pth_fork? pth_fork () : fork ();
1070 #else
1071   pid = fork ();
1072 #endif
1073   if (pid == (pid_t)(-1))
1074     {
1075       log_error (_("error forking process: %s\n"), strerror (errno));
1076       return gpg_error_from_syserror ();
1077     }
1078   if (!pid)
1079     {
1080       gcry_control (GCRYCTL_TERM_SECMEM);
1081       if (setsid() == -1 || chdir ("/"))
1082         _exit (1);
1083       pid = fork (); /* Double fork to let init takes over the new child. */
1084       if (pid == (pid_t)(-1))
1085         _exit (1);
1086       if (pid)
1087         _exit (0);  /* Let the parent exit immediately. */
1088
1089       if (envp)
1090         for (i=0; envp[i]; i++)
1091           putenv (xstrdup (envp[i]));
1092       
1093       do_exec (pgmname, argv, -1, -1, -1, NULL);
1094
1095       /*NOTREACHED*/
1096     }
1097   
1098   if (waitpid (pid, NULL, 0) == -1)
1099     log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
1100                strerror (errno));
1101
1102   return 0;
1103 #endif /* !HAVE_W32_SYSTEM*/
1104 }
1105
1106
1107 /* Kill a process; that is send an appropriate signal to the process.
1108    gnupg_wait_process must be called to actually remove the process
1109    from the system.  An invalid PID is ignored.  */
1110 void
1111 gnupg_kill_process (pid_t pid)
1112 {
1113 #ifdef HAVE_W32_SYSTEM
1114   /* Older versions of libassuan set PID to 0 on Windows to indicate
1115      an invalid value.  */
1116   if (pid != (pid_t) INVALID_HANDLE_VALUE && pid != 0)
1117     {
1118       HANDLE process = (HANDLE) pid;
1119       
1120       /* Arbitrary error code.  */
1121       TerminateProcess (process, 1);
1122     }
1123 #else
1124   if (pid != (pid_t)(-1))
1125     {
1126       kill (pid, SIGTERM); 
1127     }
1128 #endif
1129 }