Add help strings for all commands.
[gnupg.git] / common / exechelp.c
blob4a385bcd7e704cad4a9ee9108e982821c4dd87f9
1 /* exechelp.c - fork and exec helpers
2 * Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
20 #include <config.h>
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>
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
36 #ifdef USE_GNU_PTH
37 #include <pth.h>
38 #endif
39 #ifndef HAVE_W32_SYSTEM
40 #include <sys/wait.h>
41 #endif
43 #ifdef HAVE_GETRLIMIT
44 #include <sys/time.h>
45 #include <sys/resource.h>
46 #endif /*HAVE_GETRLIMIT*/
48 #ifdef HAVE_STAT
49 # include <sys/stat.h>
50 #endif
53 #include "util.h"
54 #include "i18n.h"
55 #include "sysutils.h"
56 #include "exechelp.h"
58 /* Define to 1 do enable debugging. */
59 #define DEBUG_W32_SPAWN 1
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
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 */
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
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)
99 int max_fds = -1;
100 #ifdef HAVE_GETRLIMIT
101 struct rlimit rl;
103 # ifdef RLIMIT_NOFILE
104 if (!getrlimit (RLIMIT_NOFILE, &rl))
105 max_fds = rl.rlim_max;
106 # endif
108 # ifdef RLIMIT_OFILE
109 if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
110 max_fds = rl.rlim_max;
112 # endif
113 #endif /*HAVE_GETRLIMIT*/
115 #ifdef _SC_OPEN_MAX
116 if (max_fds == -1)
118 long int scres = sysconf (_SC_OPEN_MAX);
119 if (scres >= 0)
120 max_fds = scres;
122 #endif
124 #ifdef _POSIX_OPEN_MAX
125 if (max_fds == -1)
126 max_fds = _POSIX_OPEN_MAX;
127 #endif
129 #ifdef OPEN_MAX
130 if (max_fds == -1)
131 max_fds = OPEN_MAX;
132 #endif
134 if (max_fds == -1)
135 max_fds = 256; /* Arbitrary limit. */
137 return max_fds;
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)
148 int max_fd = get_max_fds ();
149 int fd, i, except_start;
151 if (except)
153 except_start = 0;
154 for (fd=first; fd < max_fd; fd++)
156 for (i=except_start; except[i] != -1; i++)
158 if (except[i] == fd)
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;
167 if (except[i] == -1)
168 close (fd);
171 else
173 for (fd=first; fd < max_fd; fd++)
174 close (fd);
177 errno = 0;
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)
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;
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;
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))
210 if (idx+1 >= narray)
212 int *tmp;
214 narray += (narray < 256)? 32:256;
215 tmp = realloc (array, narray * sizeof *array);
216 if (!tmp)
218 free (array);
219 return NULL;
221 array = tmp;
223 array[idx++] = fd;
225 array[idx] = -1;
226 #endif /*HAVE_STAT*/
227 return array;
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)
237 char *p = buffer;
238 const char *s;
240 if (!*string) /* Empty string. */
241 p = stpcpy (p, "\"\"");
242 else if (strpbrk (string, " \t\n\v\f\""))
244 /* Need top do some kind of quoting. */
245 p = stpcpy (p, "\"");
246 for (s=string; *s; s++)
248 *p++ = *s;
249 if (*s == '\"')
250 *p++ = *s;
252 *p++ = '\"';
253 *p = 0;
255 else
256 p = stpcpy (p, string);
258 return p;
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)
267 int i, n;
268 const char *s;
269 char *buf, *p;
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++)
280 n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
281 for (; *s; s++)
282 if (*s == '\"')
283 n++; /* Need to double inner quotes. */
285 n++;
287 buf = p = xtrymalloc (n);
288 if (!buf)
289 return gpg_error_from_syserror ();
291 p = build_w32_commandline_copy (p, pgmname);
292 for (i=0; argv[i]; i++)
294 *p++ = ' ';
295 p = build_w32_commandline_copy (p, argv[i]);
298 *cmdline= buf;
299 return 0;
301 #endif /*HAVE_W32_SYSTEM*/
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])
309 HANDLE r, w, h;
310 SECURITY_ATTRIBUTES sec_attr;
312 memset (&sec_attr, 0, sizeof sec_attr );
313 sec_attr.nLength = sizeof sec_attr;
314 sec_attr.bInheritHandle = FALSE;
316 if (!CreatePipe (&r, &w, &sec_attr, 0))
317 return -1;
319 if (!DuplicateHandle (GetCurrentProcess(), w,
320 GetCurrentProcess(), &h, 0,
321 TRUE, DUPLICATE_SAME_ACCESS ))
323 log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
324 CloseHandle (r);
325 CloseHandle (w);
326 return -1;
328 CloseHandle (w);
329 w = h;
331 filedes[0] = handle_to_fd (r);
332 filedes[1] = handle_to_fd (w);
333 return 0;
336 /* Create pipe where the read end is inheritable. */
337 static int
338 create_inheritable_pipe_r (int filedes[2])
340 HANDLE r, w, h;
341 SECURITY_ATTRIBUTES sec_attr;
343 memset (&sec_attr, 0, sizeof sec_attr );
344 sec_attr.nLength = sizeof sec_attr;
345 sec_attr.bInheritHandle = FALSE;
347 if (!CreatePipe (&r, &w, &sec_attr, 0))
348 return -1;
350 if (!DuplicateHandle (GetCurrentProcess(), r,
351 GetCurrentProcess(), &h, 0,
352 TRUE, DUPLICATE_SAME_ACCESS ))
354 log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
355 CloseHandle (r);
356 CloseHandle (w);
357 return -1;
359 CloseHandle (r);
360 r = h;
362 filedes[0] = handle_to_fd (r);
363 filedes[1] = handle_to_fd (w);
364 return 0;
366 #endif /*HAVE_W32_SYSTEM*/
369 #ifdef HAVE_W32_SYSTEM
370 static HANDLE
371 w32_open_null (int for_write)
373 HANDLE hfile;
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;
383 #endif /*HAVE_W32_SYSTEM*/
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) )
393 char **arg_list;
394 int i, j;
395 int fds[3];
397 fds[0] = fd_in;
398 fds[1] = fd_out;
399 fds[2] = fd_err;
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];
416 /* Assign /dev/null to unused FDs. */
417 for (i=0; i <= 2; i++)
419 if (fds[i] == -1 )
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));
428 /* Connect the standard files. */
429 for (i=0; i <= 2; i++)
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));
436 /* Close all other files. */
437 close_all_fds (3, NULL);
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);
445 #endif /*!HAVE_W32_SYSTEM*/
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])
453 gpg_error_t err = 0;
454 #if HAVE_W32_SYSTEM
455 int fds[2];
457 filedes[0] = filedes[1] = -1;
458 err = gpg_error (GPG_ERR_GENERAL);
459 if (!create_inheritable_pipe_w (fds))
461 filedes[0] = _open_osfhandle (fds[0], 0);
462 if (filedes[0] == -1)
464 log_error ("failed to translate osfhandle %p\n", (void*)fds[0]);
465 CloseHandle (fd_to_handle (fds[1]));
467 else
469 filedes[1] = _open_osfhandle (fds[1], 1);
470 if (filedes[1] == -1)
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]));
477 else
478 err = 0;
481 #else
482 if (pipe (filedes) == -1)
484 err = gpg_error_from_syserror ();
485 filedes[0] = filedes[1] = -1;
487 #endif
488 return err;
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])
497 gpg_error_t err = 0;
498 #if HAVE_W32_SYSTEM
499 int fds[2];
501 filedes[0] = filedes[1] = -1;
502 err = gpg_error (GPG_ERR_GENERAL);
503 if (!create_inheritable_pipe_r (fds))
505 filedes[0] = _open_osfhandle (fds[0], 0);
506 if (filedes[0] == -1)
508 log_error ("failed to translate osfhandle %p\n", (void*)fds[0]);
509 CloseHandle (fd_to_handle (fds[1]));
511 else
513 filedes[1] = _open_osfhandle (fds[1], 1);
514 if (filedes[1] == -1)
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]));
521 else
522 err = 0;
525 #else
526 if (pipe (filedes) == -1)
528 err = gpg_error_from_syserror ();
529 filedes[0] = filedes[1] = -1;
531 #endif
532 return err;
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.
544 FLAGS is a bit vector with just one bit defined for now:
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
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.
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)
562 #ifdef HAVE_W32_SYSTEM
563 gpg_error_t err;
564 SECURITY_ATTRIBUTES sec_attr;
565 PROCESS_INFORMATION pi =
567 NULL, /* Returns process handle. */
568 0, /* Returns primary thread handle. */
569 0, /* Returns pid. */
570 0 /* Returns tid. */
572 STARTUPINFO si;
573 int cr_flags;
574 char *cmdline;
575 int fd, fdout, rp[2];
577 (void)preexec;
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");
589 /* Prepare security attributes. */
590 memset (&sec_attr, 0, sizeof sec_attr );
591 sec_attr.nLength = sizeof sec_attr;
592 sec_attr.bInheritHandle = FALSE;
594 /* Build the command line. */
595 err = build_w32_commandline (pgmname, argv, &cmdline);
596 if (err)
597 return err;
599 /* Create a pipe. */
600 if (create_inheritable_pipe_w (rp))
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;
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]);
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. */
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);
641 xfree (cmdline);
642 cmdline = NULL;
644 /* Close the other end of the pipe. */
645 CloseHandle (fd_to_handle (rp[1]));
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); */
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*/);
658 /* Process has been created suspended; resume it now. */
659 ResumeThread (pi.hThread);
660 CloseHandle (pi.hThread);
663 int x;
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");
671 if (!*statusfile)
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;
679 *pid = handle_to_pid (pi.hProcess);
680 return 0;
682 #else /* !HAVE_W32_SYSTEM */
683 gpg_error_t err;
684 int fd, fdout, rp[2];
686 (void)flags; /* Currently not used. */
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");
697 if (pipe (rp) == -1)
699 err = gpg_error_from_syserror ();
700 log_error (_("error creating a pipe: %s\n"), strerror (errno));
701 return err;
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))
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;
718 if (!*pid)
720 gcry_control (GCRYCTL_TERM_SECMEM);
721 /* Run child. */
722 do_exec (pgmname, argv, fd, fdout, rp[1], preexec);
723 /*NOTREACHED*/
726 /* Parent. */
727 close (rp[1]);
729 *statusfile = fdopen (rp[0], "r");
730 if (!*statusfile)
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;
739 return 0;
740 #endif /* !HAVE_W32_SYSTEM */
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.
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)
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];
766 /* Setup return values. */
767 *pid = (pid_t)(-1);
769 /* Prepare security attributes. */
770 memset (&sec_attr, 0, sizeof sec_attr );
771 sec_attr.nLength = sizeof sec_attr;
772 sec_attr.bInheritHandle = FALSE;
774 /* Build the command line. */
775 err = build_w32_commandline (pgmname, argv, &cmdline);
776 if (err)
777 return err;
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);
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. */
805 log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
806 err = gpg_error (GPG_ERR_GENERAL);
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;
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); */
822 /* Process has been created suspended; resume it now. */
823 ResumeThread (pi.hThread);
824 CloseHandle (pi.hThread);
826 *pid = handle_to_pid (pi.hProcess);
827 return 0;
829 #else /* !HAVE_W32_SYSTEM */
830 gpg_error_t err;
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))
839 err = gpg_error_from_syserror ();
840 log_error (_("error forking process: %s\n"), strerror (errno));
841 return err;
844 if (!*pid)
846 gcry_control (GCRYCTL_TERM_SECMEM);
847 /* Run child. */
848 do_exec (pgmname, argv, infd, outfd, errfd, NULL);
849 /*NOTREACHED*/
852 return 0;
853 #endif /* !HAVE_W32_SYSTEM */
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)
866 gpg_err_code_t ec;
868 #ifdef HAVE_W32_SYSTEM
869 HANDLE proc = fd_to_handle (pid);
870 int code;
871 DWORD exc;
873 if (exitcode)
874 *exitcode = -1;
876 if (pid == (pid_t)(-1))
877 return gpg_error (GPG_ERR_INV_VALUE);
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)
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;
891 case WAIT_OBJECT_0:
892 if (!GetExitCodeProcess (proc, &exc))
894 log_error (_("error getting exit code of process %d: %s\n"),
895 (int)pid, w32_strerror (-1) );
896 ec = GPG_ERR_GENERAL;
898 else if (exc)
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;
906 else
908 if (exitcode)
909 *exitcode = 0;
910 ec = 0;
912 CloseHandle (proc);
913 break;
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;
922 #else /* !HAVE_W32_SYSTEM */
923 int i, status;
925 if (exitcode)
926 *exitcode = -1;
928 if (pid == (pid_t)(-1))
929 return gpg_error (GPG_ERR_INV_VALUE);
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)
936 #endif
937 if (i == (pid_t)(-1))
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);
943 else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
945 log_error (_("error running `%s': probably not installed\n"), pgmname);
946 ec = GPG_ERR_CONFIGURATION;
948 else if (WIFEXITED (status) && WEXITSTATUS (status))
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;
956 else if (!WIFEXITED (status))
958 log_error (_("error running `%s': terminated\n"), pgmname);
959 ec = GPG_ERR_GENERAL;
961 else
963 if (exitcode)
964 *exitcode = 0;
965 ec = 0;
967 #endif /* !HAVE_W32_SYSTEM */
969 return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
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[] )
984 #ifdef HAVE_W32_SYSTEM
985 gpg_error_t err;
986 SECURITY_ATTRIBUTES sec_attr;
987 PROCESS_INFORMATION pi =
989 NULL, /* Returns process handle. */
990 0, /* Returns primary thread handle. */
991 0, /* Returns pid. */
992 0 /* Returns tid. */
994 STARTUPINFO si;
995 int cr_flags;
996 char *cmdline;
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;
1005 if (access (pgmname, X_OK))
1006 return gpg_error_from_syserror ();
1008 /* Prepare security attributes. */
1009 memset (&sec_attr, 0, sizeof sec_attr );
1010 sec_attr.nLength = sizeof sec_attr;
1011 sec_attr.bInheritHandle = FALSE;
1013 /* Build the command line. */
1014 err = build_w32_commandline (pgmname, argv, &cmdline);
1015 if (err)
1016 return err;
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;
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. */
1042 log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1));
1043 xfree (cmdline);
1044 return gpg_error (GPG_ERR_GENERAL);
1046 xfree (cmdline);
1047 cmdline = NULL;
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); */
1054 CloseHandle (pi.hThread);
1056 return 0;
1058 #else
1059 pid_t pid;
1060 int i;
1062 if (getuid() != geteuid())
1063 return gpg_error (GPG_ERR_BUG);
1065 if (access (pgmname, X_OK))
1066 return gpg_error_from_syserror ();
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))
1075 log_error (_("error forking process: %s\n"), strerror (errno));
1076 return gpg_error_from_syserror ();
1078 if (!pid)
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. */
1089 if (envp)
1090 for (i=0; envp[i]; i++)
1091 putenv (xstrdup (envp[i]));
1093 do_exec (pgmname, argv, -1, -1, -1, NULL);
1095 /*NOTREACHED*/
1098 if (waitpid (pid, NULL, 0) == -1)
1099 log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
1100 strerror (errno));
1102 return 0;
1103 #endif /* !HAVE_W32_SYSTEM*/
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)
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)
1118 HANDLE process = (HANDLE) pid;
1120 /* Arbitrary error code. */
1121 TerminateProcess (process, 1);
1123 #else
1124 if (pid != (pid_t)(-1))
1126 kill (pid, SIGTERM);
1128 #endif