1 /* exechelp.c - fork and exec helpers
2 * Copyright (C) 2004, 2007, 2008 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/>.
31 #ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */
39 #ifndef HAVE_W32_SYSTEM
47 /* Define to 1 do enable debugging. */
48 #define DEBUG_W32_SPAWN 1
51 #ifdef _POSIX_OPEN_MAX
52 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
54 #define MAX_OPEN_FDS 20
57 /* We have the usual problem here: Some modules are linked against pth
58 and some are not. However we want to use pth_fork and pth_waitpid
59 here. Using a weak symbol works but is not portable - we should
60 provide a an explicit dummy pth module instead of using the
64 #pragma weak pth_waitpid
67 #ifdef HAVE_W32_SYSTEM
68 /* It seems Vista doesn't grok X_OK and so fails access() tests.
69 Previous versions interpreted X_OK as F_OK anyway, so we'll just
73 #endif /* HAVE_W32_SYSTEM */
76 #ifdef HAVE_W32_SYSTEM
77 /* We assume that a HANDLE can be represented by an int which should
78 be true for all i386 systems (HANDLE is defined as void *) and
79 these are the only systems for which Windows is available. Further
80 we assume that -1 denotes an invalid handle. */
81 # define fd_to_handle(a) ((HANDLE)(a))
82 # define handle_to_fd(a) ((int)(a))
83 # define pid_to_handle(a) ((HANDLE)(a))
84 # define handle_to_pid(a) ((int)(a))
88 #ifdef HAVE_W32_SYSTEM
89 /* Helper function to build_w32_commandline. */
91 build_w32_commandline_copy (char *buffer
, const char *string
)
96 if (!*string
) /* Empty string. */
97 p
= stpcpy (p
, "\"\"");
98 else if (strpbrk (string
, " \t\n\v\f\""))
100 /* Need top do some kind of quoting. */
101 p
= stpcpy (p
, "\"");
102 for (s
=string
; *s
; s
++)
112 p
= stpcpy (p
, string
);
117 /* Build a command line for use with W32's CreateProcess. On success
118 CMDLINE gets the address of a newly allocated string. */
120 build_w32_commandline (const char *pgmname
, const char * const *argv
,
130 n
+= strlen (s
) + 1 + 2; /* (1 space, 2 quoting */
133 n
++; /* Need to double inner quotes. */
134 for (i
=0; (s
=argv
[i
]); i
++)
136 n
+= strlen (s
) + 1 + 2; /* (1 space, 2 quoting */
139 n
++; /* Need to double inner quotes. */
143 buf
= p
= xtrymalloc (n
);
145 return gpg_error_from_syserror ();
147 p
= build_w32_commandline_copy (p
, pgmname
);
148 for (i
=0; argv
[i
]; i
++)
151 p
= build_w32_commandline_copy (p
, argv
[i
]);
157 #endif /*HAVE_W32_SYSTEM*/
160 #ifdef HAVE_W32_SYSTEM
161 /* Create pipe where the write end is inheritable. */
163 create_inheritable_pipe (int filedes
[2])
166 SECURITY_ATTRIBUTES sec_attr
;
168 memset (&sec_attr
, 0, sizeof sec_attr
);
169 sec_attr
.nLength
= sizeof sec_attr
;
170 sec_attr
.bInheritHandle
= FALSE
;
172 if (!CreatePipe (&r
, &w
, &sec_attr
, 0))
175 if (!DuplicateHandle (GetCurrentProcess(), w
,
176 GetCurrentProcess(), &h
, 0,
177 TRUE
, DUPLICATE_SAME_ACCESS
))
179 log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
187 filedes
[0] = handle_to_fd (r
);
188 filedes
[1] = handle_to_fd (w
);
191 #endif /*HAVE_W32_SYSTEM*/
194 #ifdef HAVE_W32_SYSTEM
196 w32_open_null (int for_write
)
200 hfile
= CreateFile ("nul",
201 for_write
? GENERIC_WRITE
: GENERIC_READ
,
202 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
203 NULL
, OPEN_EXISTING
, 0, NULL
);
204 if (hfile
== INVALID_HANDLE_VALUE
)
205 log_debug ("can't open `nul': %s\n", w32_strerror (-1));
208 #endif /*HAVE_W32_SYSTEM*/
211 #ifndef HAVE_W32_SYSTEM
212 /* The exec core used right after the fork. This will never return. */
214 do_exec (const char *pgmname
, const char *argv
[],
215 int fd_in
, int fd_out
, int fd_err
,
216 void (*preexec
)(void) )
226 /* Create the command line argument array. */
231 arg_list
= xcalloc (i
+2, sizeof *arg_list
);
232 arg_list
[0] = strrchr (pgmname
, '/');
236 arg_list
[0] = xstrdup (pgmname
);
238 for (i
=0,j
=1; argv
[i
]; i
++, j
++)
239 arg_list
[j
] = (char*)argv
[i
];
241 /* Connect the standard files. */
242 for (i
=0; i
<= 2; i
++)
246 fds
[i
] = open ("/dev/null", i
? O_WRONLY
: O_RDONLY
);
248 log_fatal ("failed to open `%s': %s\n",
249 "/dev/null", strerror (errno
));
251 else if (fds
[i
] != i
&& dup2 (fds
[i
], i
) == -1)
252 log_fatal ("dup2 std%s failed: %s\n",
253 i
==0?"in":i
==1?"out":"err", strerror (errno
));
256 /* Close all other files. */
257 n
= sysconf (_SC_OPEN_MAX
);
260 for (i
=3; i
< n
; i
++)
266 execv (pgmname
, arg_list
);
267 /* No way to print anything, as we have closed all streams. */
270 #endif /*!HAVE_W32_SYSTEM*/
273 /* Portable function to create a pipe. Under Windows the write end is
276 gnupg_create_inbound_pipe (int filedes
[2])
282 filedes
[0] = filedes
[1] = -1;
283 err
= gpg_error (GPG_ERR_GENERAL
);
284 if (!create_inheritable_pipe (fds
))
286 filedes
[0] = _open_osfhandle (fds
[0], 0);
287 if (filedes
[0] == -1)
289 log_error ("failed to translate osfhandle %p\n", (void*)fds
[0]);
290 CloseHandle (fd_to_handle (fds
[1]));
294 filedes
[1] = _open_osfhandle (fds
[1], 1);
295 if (filedes
[1] == -1)
297 log_error ("failed to translate osfhandle %p\n", (void*)fds
[1]);
300 CloseHandle (fd_to_handle (fds
[1]));
307 if (pipe (filedes
) == -1)
309 err
= gpg_error_from_syserror ();
310 filedes
[0] = filedes
[1] = -1;
317 /* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
318 stdin, write the output to OUTFILE, return a new stream in
319 STATUSFILE for stderr and the pid of the process in PID. The
320 arguments for the process are expected in the NULL terminated array
321 ARGV. The program name itself should not be included there. If
322 PREEXEC is not NULL, that function will be called right before the
323 exec. Calling gnupg_wait_process is required.
325 FLAGS is a bit vector with just one bit defined for now:
327 Bit 7: If set the process will be started as a background process.
328 This flag is only useful under W32 systems, so that no new
329 console is created and pops up a console window when
332 Returns 0 on success or an error code. */
334 gnupg_spawn_process (const char *pgmname
, const char *argv
[],
335 FILE *infile
, FILE *outfile
,
336 void (*preexec
)(void), unsigned int flags
,
337 FILE **statusfile
, pid_t
*pid
)
339 #ifdef HAVE_W32_SYSTEM
341 SECURITY_ATTRIBUTES sec_attr
;
342 PROCESS_INFORMATION pi
=
344 NULL
, /* Returns process handle. */
345 0, /* Returns primary thread handle. */
346 0, /* Returns pid. */
352 int fd
, fdout
, rp
[2];
354 /* Setup return values. */
359 fd
= _get_osfhandle (fileno (infile
));
360 fdout
= _get_osfhandle (fileno (outfile
));
361 if (fd
== -1 || fdout
== -1)
362 log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
364 /* Prepare security attributes. */
365 memset (&sec_attr
, 0, sizeof sec_attr
);
366 sec_attr
.nLength
= sizeof sec_attr
;
367 sec_attr
.bInheritHandle
= FALSE
;
369 /* Build the command line. */
370 err
= build_w32_commandline (pgmname
, argv
, &cmdline
);
375 if (create_inheritable_pipe (rp
))
377 err
= gpg_error (GPG_ERR_GENERAL
);
378 log_error (_("error creating a pipe: %s\n"), gpg_strerror (err
));
383 /* Start the process. Note that we can't run the PREEXEC function
384 because this would change our own environment. */
385 memset (&si
, 0, sizeof si
);
387 si
.dwFlags
= STARTF_USESTDHANDLES
| STARTF_USESHOWWINDOW
;
388 si
.wShowWindow
= DEBUG_W32_SPAWN
? SW_SHOW
: SW_MINIMIZE
;
389 si
.hStdInput
= fd_to_handle (fd
);
390 si
.hStdOutput
= fd_to_handle (fdout
);
391 si
.hStdError
= fd_to_handle (rp
[1]);
393 cr_flags
= (CREATE_DEFAULT_ERROR_MODE
394 | ((flags
& 128)? DETACHED_PROCESS
: 0)
395 | GetPriorityClass (GetCurrentProcess ())
397 log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname
, cmdline
);
398 if (!CreateProcess (pgmname
, /* Program to start. */
399 cmdline
, /* Command line arguments. */
400 &sec_attr
, /* Process security attributes. */
401 &sec_attr
, /* Thread security attributes. */
402 TRUE
, /* Inherit handles. */
403 cr_flags
, /* Creation flags. */
404 NULL
, /* Environment. */
405 NULL
, /* Use current drive/directory. */
406 &si
, /* Startup information. */
407 &pi
/* Returns process information. */
410 log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
412 CloseHandle (fd_to_handle (rp
[0]));
413 CloseHandle (fd_to_handle (rp
[1]));
414 return gpg_error (GPG_ERR_GENERAL
);
419 /* Close the other end of the pipe. */
420 CloseHandle (fd_to_handle (rp
[1]));
422 log_debug ("CreateProcess ready: hProcess=%p hThread=%p"
423 " dwProcessID=%d dwThreadId=%d\n",
424 pi
.hProcess
, pi
.hThread
,
425 (int) pi
.dwProcessId
, (int) pi
.dwThreadId
);
427 /* Process has been created suspended; resume it now. */
428 ResumeThread (pi
.hThread
);
429 CloseHandle (pi
.hThread
);
434 x
= _open_osfhandle (rp
[0], 0);
436 log_error ("failed to translate osfhandle %p\n", (void*)rp
[0] );
438 *statusfile
= fdopen (x
, "r");
442 err
= gpg_error_from_syserror ();
443 log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err
));
444 CloseHandle (pi
.hProcess
);
448 *pid
= handle_to_pid (pi
.hProcess
);
451 #else /* !HAVE_W32_SYSTEM */
453 int fd
, fdout
, rp
[2];
459 fd
= fileno (infile
);
460 fdout
= fileno (outfile
);
461 if (fd
== -1 || fdout
== -1)
462 log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
466 err
= gpg_error_from_syserror ();
467 log_error (_("error creating a pipe: %s\n"), strerror (errno
));
472 *pid
= pth_fork
? pth_fork () : fork ();
476 if (*pid
== (pid_t
)(-1))
478 err
= gpg_error_from_syserror ();
479 log_error (_("error forking process: %s\n"), strerror (errno
));
487 gcry_control (GCRYCTL_TERM_SECMEM
);
489 do_exec (pgmname
, argv
, fd
, fdout
, rp
[1], preexec
);
496 *statusfile
= fdopen (rp
[0], "r");
499 err
= gpg_error_from_syserror ();
500 log_error (_("can't fdopen pipe for reading: %s\n"), strerror (errno
));
501 kill (*pid
, SIGTERM
);
507 #endif /* !HAVE_W32_SYSTEM */
512 /* Simplified version of gnupg_spawn_process. This function forks and
513 then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
514 and ERRFD to stderr (any of them may be -1 to connect them to
515 /dev/null). The arguments for the process are expected in the NULL
516 terminated array ARGV. The program name itself should not be
517 included there. Calling gnupg_wait_process is required.
519 Returns 0 on success or an error code. */
521 gnupg_spawn_process_fd (const char *pgmname
, const char *argv
[],
522 int infd
, int outfd
, int errfd
, pid_t
*pid
)
524 #ifdef HAVE_W32_SYSTEM
526 SECURITY_ATTRIBUTES sec_attr
;
527 PROCESS_INFORMATION pi
= { NULL
, 0, 0, 0 };
533 /* Setup return values. */
536 /* Prepare security attributes. */
537 memset (&sec_attr
, 0, sizeof sec_attr
);
538 sec_attr
.nLength
= sizeof sec_attr
;
539 sec_attr
.bInheritHandle
= FALSE
;
541 /* Build the command line. */
542 err
= build_w32_commandline (pgmname
, argv
, &cmdline
);
546 memset (&si
, 0, sizeof si
);
548 si
.dwFlags
= STARTF_USESTDHANDLES
| STARTF_USESHOWWINDOW
;
549 si
.wShowWindow
= DEBUG_W32_SPAWN
? SW_SHOW
: SW_MINIMIZE
;
550 stdhd
[0] = infd
== -1? w32_open_null (0) : INVALID_HANDLE_VALUE
;
551 stdhd
[1] = outfd
== -1? w32_open_null (1) : INVALID_HANDLE_VALUE
;
552 stdhd
[2] = errfd
== -1? w32_open_null (1) : INVALID_HANDLE_VALUE
;
553 si
.hStdInput
= infd
== -1? stdhd
[0] : (void*)_get_osfhandle (infd
);
554 si
.hStdOutput
= outfd
== -1? stdhd
[1] : (void*)_get_osfhandle (outfd
);
555 si
.hStdError
= errfd
== -1? stdhd
[2] : (void*)_get_osfhandle (errfd
);
557 log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname
, cmdline
);
558 if (!CreateProcess (pgmname
, /* Program to start. */
559 cmdline
, /* Command line arguments. */
560 &sec_attr
, /* Process security attributes. */
561 &sec_attr
, /* Thread security attributes. */
562 TRUE
, /* Inherit handles. */
563 (CREATE_DEFAULT_ERROR_MODE
564 | GetPriorityClass (GetCurrentProcess ())
566 NULL
, /* Environment. */
567 NULL
, /* Use current drive/directory. */
568 &si
, /* Startup information. */
569 &pi
/* Returns process information. */
572 log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
573 err
= gpg_error (GPG_ERR_GENERAL
);
578 for (i
=0; i
< 3; i
++)
579 if (stdhd
[i
] != INVALID_HANDLE_VALUE
)
580 CloseHandle (stdhd
[i
]);
584 log_debug ("CreateProcess ready: hProcess=%p hThread=%p"
585 " dwProcessID=%d dwThreadId=%d\n",
586 pi
.hProcess
, pi
.hThread
,
587 (int) pi
.dwProcessId
, (int) pi
.dwThreadId
);
589 /* Process has been created suspended; resume it now. */
590 ResumeThread (pi
.hThread
);
591 CloseHandle (pi
.hThread
);
593 *pid
= handle_to_pid (pi
.hProcess
);
596 #else /* !HAVE_W32_SYSTEM */
600 *pid
= pth_fork
? pth_fork () : fork ();
604 if (*pid
== (pid_t
)(-1))
606 err
= gpg_error_from_syserror ();
607 log_error (_("error forking process: %s\n"), strerror (errno
));
613 gcry_control (GCRYCTL_TERM_SECMEM
);
615 do_exec (pgmname
, argv
, infd
, outfd
, errfd
, NULL
);
620 #endif /* !HAVE_W32_SYSTEM */
624 /* Wait for the process identified by PID to terminate. PGMNAME should
625 be the same as supplied to the spawn function and is only used for
626 diagnostics. Returns 0 if the process succeeded, GPG_ERR_GENERAL
627 for any failures of the spawned program or other error codes. If
628 EXITCODE is not NULL the exit code of the process is stored at this
629 address or -1 if it could not be retrieved. */
631 gnupg_wait_process (const char *pgmname
, pid_t pid
, int *exitcode
)
635 #ifdef HAVE_W32_SYSTEM
636 HANDLE proc
= fd_to_handle (pid
);
643 if (pid
== (pid_t
)(-1))
644 return gpg_error (GPG_ERR_INV_VALUE
);
646 /* FIXME: We should do a pth_waitpid here. However this has not yet
647 been implemented. A special W32 pth system call would even be
649 code
= WaitForSingleObject (proc
, INFINITE
);
653 log_error (_("waiting for process %d to terminate failed: %s\n"),
654 (int)pid
, w32_strerror (-1));
655 ec
= GPG_ERR_GENERAL
;
659 if (!GetExitCodeProcess (proc
, &exc
))
661 log_error (_("error getting exit code of process %d: %s\n"),
662 (int)pid
, w32_strerror (-1) );
663 ec
= GPG_ERR_GENERAL
;
667 log_error (_("error running `%s': exit status %d\n"),
670 *exitcode
= (int)exc
;
671 ec
= GPG_ERR_GENERAL
;
683 log_error ("WaitForSingleObject returned unexpected "
684 "code %d for pid %d\n", code
, (int)pid
);
685 ec
= GPG_ERR_GENERAL
;
689 #else /* !HAVE_W32_SYSTEM */
695 if (pid
== (pid_t
)(-1))
696 return gpg_error (GPG_ERR_INV_VALUE
);
699 i
= pth_waitpid
? pth_waitpid (pid
, &status
, 0) : waitpid (pid
, &status
, 0);
701 while ( (i
=waitpid (pid
, &status
, 0)) == -1 && errno
== EINTR
)
704 if (i
== (pid_t
)(-1))
706 log_error (_("waiting for process %d to terminate failed: %s\n"),
707 (int)pid
, strerror (errno
));
708 ec
= gpg_err_code_from_errno (errno
);
710 else if (WIFEXITED (status
) && WEXITSTATUS (status
) == 127)
712 log_error (_("error running `%s': probably not installed\n"), pgmname
);
713 ec
= GPG_ERR_CONFIGURATION
;
715 else if (WIFEXITED (status
) && WEXITSTATUS (status
))
717 log_error (_("error running `%s': exit status %d\n"), pgmname
,
718 WEXITSTATUS (status
));
720 *exitcode
= WEXITSTATUS (status
);
721 ec
= GPG_ERR_GENERAL
;
723 else if (!WIFEXITED (status
))
725 log_error (_("error running `%s': terminated\n"), pgmname
);
726 ec
= GPG_ERR_GENERAL
;
734 #endif /* !HAVE_W32_SYSTEM */
736 return gpg_err_make (GPG_ERR_SOURCE_DEFAULT
, ec
);
740 /* Spawn a new process and immediatley detach from it. The name of
741 the program to exec is PGMNAME and its arguments are in ARGV (the
742 programname is automatically passed as first argument).
743 Environment strings in ENVP are set. An error is returned if
744 pgmname is not executable; to make this work it is necessary to
745 provide an absolute file name. All standard file descriptors are
746 connected to /dev/null. */
748 gnupg_spawn_process_detached (const char *pgmname
, const char *argv
[],
751 #ifdef HAVE_W32_SYSTEM
753 SECURITY_ATTRIBUTES sec_attr
;
754 PROCESS_INFORMATION pi
=
756 NULL
, /* Returns process handle. */
757 0, /* Returns primary thread handle. */
758 0, /* Returns pid. */
766 /* FIXME: We don't make use of ENVP yet. It is currently only used
767 to pass the GPG_AGENT_INFO variable to gpg-agent. As the default
768 on windows is to use a standard socket, this does not really
772 if (access (pgmname
, X_OK
))
773 return gpg_error_from_syserror ();
775 /* Prepare security attributes. */
776 memset (&sec_attr
, 0, sizeof sec_attr
);
777 sec_attr
.nLength
= sizeof sec_attr
;
778 sec_attr
.bInheritHandle
= FALSE
;
780 /* Build the command line. */
781 err
= build_w32_commandline (pgmname
, argv
, &cmdline
);
785 /* Start the process. */
786 memset (&si
, 0, sizeof si
);
788 si
.dwFlags
= STARTF_USESHOWWINDOW
;
789 si
.wShowWindow
= DEBUG_W32_SPAWN
? SW_SHOW
: SW_MINIMIZE
;
791 cr_flags
= (CREATE_DEFAULT_ERROR_MODE
792 | GetPriorityClass (GetCurrentProcess ())
793 | CREATE_NEW_PROCESS_GROUP
795 log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n",
797 if (!CreateProcess (pgmname
, /* Program to start. */
798 cmdline
, /* Command line arguments. */
799 &sec_attr
, /* Process security attributes. */
800 &sec_attr
, /* Thread security attributes. */
801 FALSE
, /* Inherit handles. */
802 cr_flags
, /* Creation flags. */
803 NULL
, /* Environment. */
804 NULL
, /* Use current drive/directory. */
805 &si
, /* Startup information. */
806 &pi
/* Returns process information. */
809 log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1));
811 return gpg_error (GPG_ERR_GENERAL
);
816 log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p"
817 " dwProcessID=%d dwThreadId=%d\n",
818 pi
.hProcess
, pi
.hThread
,
819 (int) pi
.dwProcessId
, (int) pi
.dwThreadId
);
821 CloseHandle (pi
.hThread
);
829 if (getuid() != geteuid())
830 return gpg_error (GPG_ERR_BUG
);
832 if (access (pgmname
, X_OK
))
833 return gpg_error_from_syserror ();
836 pid
= pth_fork
? pth_fork () : fork ();
840 if (pid
== (pid_t
)(-1))
842 log_error (_("error forking process: %s\n"), strerror (errno
));
843 return gpg_error_from_syserror ();
847 gcry_control (GCRYCTL_TERM_SECMEM
);
848 if (setsid() == -1 || chdir ("/"))
850 pid
= fork (); /* Double fork to let init takes over the new child. */
851 if (pid
== (pid_t
)(-1))
854 _exit (0); /* Let the parent exit immediately. */
857 for (i
=0; envp
[i
]; i
++)
858 putenv (xstrdup (envp
[i
]));
860 do_exec (pgmname
, argv
, -1, -1, -1, NULL
);
865 if (waitpid (pid
, NULL
, 0) == -1)
866 log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
870 #endif /* !HAVE_W32_SYSTEM*/