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