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/>.
31 #ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */
39 #ifndef HAVE_W32_SYSTEM
45 #include <sys/resource.h>
46 #endif /*HAVE_GETRLIMIT*/
49 # include <sys/stat.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
69 #pragma weak pth_waitpid
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
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))
93 /* Return the maximum number of currently allowed open file
94 descriptors. Only useful on POSIX systems but returns a value on
100 #ifdef HAVE_GETRLIMIT
103 # ifdef RLIMIT_NOFILE
104 if (!getrlimit (RLIMIT_NOFILE
, &rl
))
105 max_fds
= rl
.rlim_max
;
109 if (max_fds
== -1 && !getrlimit (RLIMIT_OFILE
, &rl
))
110 max_fds
= rl
.rlim_max
;
113 #endif /*HAVE_GETRLIMIT*/
118 long int scres
= sysconf (_SC_OPEN_MAX
);
124 #ifdef _POSIX_OPEN_MAX
126 max_fds
= _POSIX_OPEN_MAX
;
135 max_fds
= 256; /* Arbitrary limit. */
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. */
146 close_all_fds (int first
, int *except
)
148 int max_fd
= get_max_fds ();
149 int fd
, i
, except_start
;
154 for (fd
=first
; fd
< max_fd
; fd
++)
156 for (i
=except_start
; except
[i
] != -1; i
++)
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;
173 for (fd
=first
; fd
< max_fd
; fd
++)
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
188 get_all_open_fds (void)
194 array
= calloc (1, sizeof *array
);
200 max_fd
= get_max_fds ();
201 narray
= 32; /* If you change this change also t-exechelp.c. */
202 array
= calloc (narray
, sizeof *array
);
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
))
214 narray
+= (narray
< 256)? 32:256;
215 tmp
= realloc (array
, narray
* sizeof *array
);
232 #ifdef HAVE_W32_SYSTEM
233 /* Helper function to build_w32_commandline. */
235 build_w32_commandline_copy (char *buffer
, const char *string
)
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
++)
256 p
= stpcpy (p
, string
);
261 /* Build a command line for use with W32's CreateProcess. On success
262 CMDLINE gets the address of a newly allocated string. */
264 build_w32_commandline (const char *pgmname
, const char * const *argv
,
274 n
+= strlen (s
) + 1 + 2; /* (1 space, 2 quoting */
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 */
283 n
++; /* Need to double inner quotes. */
287 buf
= p
= xtrymalloc (n
);
289 return gpg_error_from_syserror ();
291 p
= build_w32_commandline_copy (p
, pgmname
);
292 for (i
=0; argv
[i
]; i
++)
295 p
= build_w32_commandline_copy (p
, argv
[i
]);
301 #endif /*HAVE_W32_SYSTEM*/
304 #ifdef HAVE_W32_SYSTEM
305 /* Create pipe where the write end is inheritable. */
307 create_inheritable_pipe_w (int filedes
[2])
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))
319 if (!DuplicateHandle (GetCurrentProcess(), w
,
320 GetCurrentProcess(), &h
, 0,
321 TRUE
, DUPLICATE_SAME_ACCESS
))
323 log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
331 filedes
[0] = handle_to_fd (r
);
332 filedes
[1] = handle_to_fd (w
);
336 /* Create pipe where the read end is inheritable. */
338 create_inheritable_pipe_r (int filedes
[2])
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))
350 if (!DuplicateHandle (GetCurrentProcess(), r
,
351 GetCurrentProcess(), &h
, 0,
352 TRUE
, DUPLICATE_SAME_ACCESS
))
354 log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
362 filedes
[0] = handle_to_fd (r
);
363 filedes
[1] = handle_to_fd (w
);
366 #endif /*HAVE_W32_SYSTEM*/
369 #ifdef HAVE_W32_SYSTEM
371 w32_open_null (int for_write
)
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));
383 #endif /*HAVE_W32_SYSTEM*/
386 #ifndef HAVE_W32_SYSTEM
387 /* The exec core used right after the fork. This will never return. */
389 do_exec (const char *pgmname
, const char *argv
[],
390 int fd_in
, int fd_out
, int fd_err
,
391 void (*preexec
)(void) )
401 /* Create the command line argument array. */
406 arg_list
= xcalloc (i
+2, sizeof *arg_list
);
407 arg_list
[0] = strrchr (pgmname
, '/');
411 arg_list
[0] = xstrdup (pgmname
);
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
++)
421 fds
[i
] = open ("/dev/null", i
? O_WRONLY
: O_RDONLY
);
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
);
441 execv (pgmname
, arg_list
);
442 /* No way to print anything, as we have closed all streams. */
445 #endif /*!HAVE_W32_SYSTEM*/
448 /* Portable function to create a pipe. Under Windows the write end is
451 gnupg_create_inbound_pipe (int filedes
[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]));
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]);
475 CloseHandle (fd_to_handle (fds
[1]));
482 if (pipe (filedes
) == -1)
484 err
= gpg_error_from_syserror ();
485 filedes
[0] = filedes
[1] = -1;
492 /* Portable function to create a pipe. Under Windows the read end is
495 gnupg_create_outbound_pipe (int filedes
[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]));
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]);
519 CloseHandle (fd_to_handle (fds
[1]));
526 if (pipe (filedes
) == -1)
528 err
= gpg_error_from_syserror ();
529 filedes
[0] = filedes
[1] = -1;
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
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. */
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
564 SECURITY_ATTRIBUTES sec_attr
;
565 PROCESS_INFORMATION pi
=
567 NULL
, /* Returns process handle. */
568 0, /* Returns primary thread handle. */
569 0, /* Returns pid. */
575 int fd
, fdout
, rp
[2];
579 /* Setup return values. */
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
);
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
));
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
);
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 ())
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));
637 CloseHandle (fd_to_handle (rp
[0]));
638 CloseHandle (fd_to_handle (rp
[1]));
639 return gpg_error (GPG_ERR_GENERAL
);
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). */
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
);
665 x
= _open_osfhandle (rp
[0], 0);
667 log_error ("failed to translate osfhandle %p\n", (void*)rp
[0] );
669 *statusfile
= fdopen (x
, "r");
673 err
= gpg_error_from_syserror ();
674 log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err
));
675 CloseHandle (pi
.hProcess
);
679 *pid
= handle_to_pid (pi
.hProcess
);
682 #else /* !HAVE_W32_SYSTEM */
684 int fd
, fdout
, rp
[2];
686 (void)flags
; /* Currently not used. */
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");
699 err
= gpg_error_from_syserror ();
700 log_error (_("error creating a pipe: %s\n"), strerror (errno
));
705 *pid
= pth_fork
? pth_fork () : fork ();
709 if (*pid
== (pid_t
)(-1))
711 err
= gpg_error_from_syserror ();
712 log_error (_("error forking process: %s\n"), strerror (errno
));
720 gcry_control (GCRYCTL_TERM_SECMEM
);
722 do_exec (pgmname
, argv
, fd
, fdout
, rp
[1], preexec
);
729 *statusfile
= fdopen (rp
[0], "r");
732 err
= gpg_error_from_syserror ();
733 log_error (_("can't fdopen pipe for reading: %s\n"), strerror (errno
));
734 kill (*pid
, SIGTERM
);
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. */
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
759 SECURITY_ATTRIBUTES sec_attr
;
760 PROCESS_INFORMATION pi
= { NULL
, 0, 0, 0 };
766 /* Setup return values. */
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
);
779 memset (&si
, 0, 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
);
811 for (i
=0; i
< 3; i
++)
812 if (stdhd
[i
] != INVALID_HANDLE_VALUE
)
813 CloseHandle (stdhd
[i
]);
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
);
829 #else /* !HAVE_W32_SYSTEM */
833 *pid
= pth_fork
? pth_fork () : fork ();
837 if (*pid
== (pid_t
)(-1))
839 err
= gpg_error_from_syserror ();
840 log_error (_("error forking process: %s\n"), strerror (errno
));
846 gcry_control (GCRYCTL_TERM_SECMEM
);
848 do_exec (pgmname
, argv
, infd
, outfd
, errfd
, NULL
);
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. */
864 gnupg_wait_process (const char *pgmname
, pid_t pid
, int *exitcode
)
868 #ifdef HAVE_W32_SYSTEM
869 HANDLE proc
= fd_to_handle (pid
);
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
882 code
= WaitForSingleObject (proc
, INFINITE
);
886 log_error (_("waiting for process %d to terminate failed: %s\n"),
887 (int)pid
, w32_strerror (-1));
888 ec
= GPG_ERR_GENERAL
;
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
;
900 log_error (_("error running `%s': exit status %d\n"),
903 *exitcode
= (int)exc
;
904 ec
= GPG_ERR_GENERAL
;
916 log_error ("WaitForSingleObject returned unexpected "
917 "code %d for pid %d\n", code
, (int)pid
);
918 ec
= GPG_ERR_GENERAL
;
922 #else /* !HAVE_W32_SYSTEM */
928 if (pid
== (pid_t
)(-1))
929 return gpg_error (GPG_ERR_INV_VALUE
);
932 i
= pth_waitpid
? pth_waitpid (pid
, &status
, 0) : waitpid (pid
, &status
, 0);
934 while ( (i
=waitpid (pid
, &status
, 0)) == -1 && errno
== EINTR
)
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
));
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
;
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. */
981 gnupg_spawn_process_detached (const char *pgmname
, const char *argv
[],
984 #ifdef HAVE_W32_SYSTEM
986 SECURITY_ATTRIBUTES sec_attr
;
987 PROCESS_INFORMATION pi
=
989 NULL
, /* Returns process handle. */
990 0, /* Returns primary thread handle. */
991 0, /* Returns pid. */
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
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
);
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));
1044 return gpg_error (GPG_ERR_GENERAL
);
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
);
1062 if (getuid() != geteuid())
1063 return gpg_error (GPG_ERR_BUG
);
1065 if (access (pgmname
, X_OK
))
1066 return gpg_error_from_syserror ();
1069 pid
= pth_fork
? pth_fork () : fork ();
1073 if (pid
== (pid_t
)(-1))
1075 log_error (_("error forking process: %s\n"), strerror (errno
));
1076 return gpg_error_from_syserror ();
1080 gcry_control (GCRYCTL_TERM_SECMEM
);
1081 if (setsid() == -1 || chdir ("/"))
1083 pid
= fork (); /* Double fork to let init takes over the new child. */
1084 if (pid
== (pid_t
)(-1))
1087 _exit (0); /* Let the parent exit immediately. */
1090 for (i
=0; envp
[i
]; i
++)
1091 putenv (xstrdup (envp
[i
]));
1093 do_exec (pgmname
, argv
, -1, -1, -1, NULL
);
1098 if (waitpid (pid
, NULL
, 0) == -1)
1099 log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
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. */
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);
1124 if (pid
!= (pid_t
)(-1))
1126 kill (pid
, SIGTERM
);