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