1 /* exechelp.c - Fork and exec helpers for POSIX
2 * Copyright (C) 2004, 2007-2009, 2010 Free Software Foundation, Inc.
3 * Copyright (C) 2004, 2006-2012, 2014-2017 g10 Code GmbH
4 *
5 * This file is part of GnuPG.
6 *
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of either
9 *
10 * - the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * or
15 *
16 * - the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at
18 * your option) any later version.
19 *
20 * or both in parallel, as here.
21 *
22 * This file is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see <https://www.gnu.org/licenses/>.
29 * SPDX-License-Identifier: (LGPL-3.0+ OR GPL-2.0+)
30 */
31
32 #include <config.h>
33
34 #if defined(HAVE_W32_SYSTEM) || defined (HAVE_W32CE_SYSTEM)
35 #error This code is only used on POSIX
36 #endif
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <stdint.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <assert.h>
44 #ifdef HAVE_SIGNAL_H
45 # include <signal.h>
46 #endif
47 #include <unistd.h>
48 #include <fcntl.h>
49
50 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */
51 #undef HAVE_NPTH
52 #undef USE_NPTH
53 #endif
54
55 #ifdef HAVE_NPTH
56 #include <npth.h>
57 #endif
58 #include <sys/wait.h>
59
60 #ifdef HAVE_GETRLIMIT
61 #include <sys/time.h>
62 #include <sys/resource.h>
63 #endif /*HAVE_GETRLIMIT*/
64
65 #ifdef HAVE_STAT
66 # include <sys/stat.h>
67 #endif
68
69 #if __linux__
70 # include <sys/types.h>
71 # include <dirent.h>
72 #endif /*__linux__ */
73
74 #include "util.h"
75 #include "i18n.h"
76 #include "sysutils.h"
77 #include "exechelp.h"
78
79
80 /* Helper */
81 static inline gpg_error_t
my_error_from_syserror(void)82 my_error_from_syserror (void)
83 {
84 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
85 }
86
87 static inline gpg_error_t
my_error(int errcode)88 my_error (int errcode)
89 {
90 return gpg_err_make (default_errsource, errcode);
91 }
92
93
94 /* Return the maximum number of currently allowed open file
95 descriptors. Only useful on POSIX systems but returns a value on
96 other systems too. */
97 int
get_max_fds(void)98 get_max_fds (void)
99 {
100 int max_fds = -1;
101 #ifdef HAVE_GETRLIMIT
102 struct rlimit rl;
103
104 /* Under Linux we can figure out the highest used file descriptor by
105 * reading /proc/PID/fd. This is in the common cases much fast than
106 * for example doing 4096 close calls where almost all of them will
107 * fail. On a system with a limit of 4096 files and only 8 files
108 * open with the highest number being 10, we speedup close_all_fds
109 * from 125ms to 0.4ms including readdir.
110 *
111 * Another option would be to close the file descriptors as returned
112 * from reading that directory - however then we need to snapshot
113 * that list before starting to close them. */
114 #ifdef __linux__
115 {
116 DIR *dir = NULL;
117 struct dirent *dir_entry;
118 const char *s;
119 int x;
120
121 dir = opendir ("/proc/self/fd");
122 if (dir)
123 {
124 while ((dir_entry = readdir (dir)))
125 {
126 s = dir_entry->d_name;
127 if ( *s < '0' || *s > '9')
128 continue;
129 x = atoi (s);
130 if (x > max_fds)
131 max_fds = x;
132 }
133 closedir (dir);
134 }
135 if (max_fds != -1)
136 return max_fds + 1;
137 }
138 #endif /* __linux__ */
139
140
141 # ifdef RLIMIT_NOFILE
142 if (!getrlimit (RLIMIT_NOFILE, &rl))
143 max_fds = rl.rlim_max;
144 # endif
145
146 # ifdef RLIMIT_OFILE
147 if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
148 max_fds = rl.rlim_max;
149
150 # endif
151 #endif /*HAVE_GETRLIMIT*/
152
153 #ifdef _SC_OPEN_MAX
154 if (max_fds == -1)
155 {
156 long int scres = sysconf (_SC_OPEN_MAX);
157 if (scres >= 0)
158 max_fds = scres;
159 }
160 #endif
161
162 #ifdef _POSIX_OPEN_MAX
163 if (max_fds == -1)
164 max_fds = _POSIX_OPEN_MAX;
165 #endif
166
167 #ifdef OPEN_MAX
168 if (max_fds == -1)
169 max_fds = OPEN_MAX;
170 #endif
171
172 if (max_fds == -1)
173 max_fds = 256; /* Arbitrary limit. */
174
175 /* AIX returns INT32_MAX instead of a proper value. We assume that
176 this is always an error and use an arbitrary limit. */
177 #ifdef INT32_MAX
178 if (max_fds == INT32_MAX)
179 max_fds = 256;
180 #endif
181
182 return max_fds;
183 }
184
185
186 /* Close all file descriptors starting with descriptor FIRST. If
187 EXCEPT is not NULL, it is expected to be a list of file descriptors
188 which shall not be closed. This list shall be sorted in ascending
189 order with the end marked by -1. */
190 void
close_all_fds(int first,int * except)191 close_all_fds (int first, int *except)
192 {
193 int max_fd = get_max_fds ();
194 int fd, i, except_start;
195
196 if (except)
197 {
198 except_start = 0;
199 for (fd=first; fd < max_fd; fd++)
200 {
201 for (i=except_start; except[i] != -1; i++)
202 {
203 if (except[i] == fd)
204 {
205 /* If we found the descriptor in the exception list
206 we can start the next compare run at the next
207 index because the exception list is ordered. */
208 except_start = i + 1;
209 break;
210 }
211 }
212 if (except[i] == -1)
213 close (fd);
214 }
215 }
216 else
217 {
218 for (fd=first; fd < max_fd; fd++)
219 close (fd);
220 }
221
222 gpg_err_set_errno (0);
223 }
224
225
226 /* Returns an array with all currently open file descriptors. The end
227 of the array is marked by -1. The caller needs to release this
228 array using the *standard free* and not with xfree. This allow the
229 use of this function right at startup even before libgcrypt has
230 been initialized. Returns NULL on error and sets ERRNO
231 accordingly. */
232 int *
get_all_open_fds(void)233 get_all_open_fds (void)
234 {
235 int *array;
236 size_t narray;
237 int fd, max_fd, idx;
238 #ifndef HAVE_STAT
239 array = calloc (1, sizeof *array);
240 if (array)
241 array[0] = -1;
242 #else /*HAVE_STAT*/
243 struct stat statbuf;
244
245 max_fd = get_max_fds ();
246 narray = 32; /* If you change this change also t-exechelp.c. */
247 array = calloc (narray, sizeof *array);
248 if (!array)
249 return NULL;
250
251 /* Note: The list we return is ordered. */
252 for (idx=0, fd=0; fd < max_fd; fd++)
253 if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
254 {
255 if (idx+1 >= narray)
256 {
257 int *tmp;
258
259 narray += (narray < 256)? 32:256;
260 tmp = realloc (array, narray * sizeof *array);
261 if (!tmp)
262 {
263 free (array);
264 return NULL;
265 }
266 array = tmp;
267 }
268 array[idx++] = fd;
269 }
270 array[idx] = -1;
271 #endif /*HAVE_STAT*/
272 return array;
273 }
274
275
276 /* The exec core used right after the fork. This will never return. */
277 static void
do_exec(const char * pgmname,const char * argv[],int fd_in,int fd_out,int fd_err,int * except,void (* preexec)(void))278 do_exec (const char *pgmname, const char *argv[],
279 int fd_in, int fd_out, int fd_err,
280 int *except, void (*preexec)(void) )
281 {
282 char **arg_list;
283 int i, j;
284 int fds[3];
285
286 fds[0] = fd_in;
287 fds[1] = fd_out;
288 fds[2] = fd_err;
289
290 /* Create the command line argument array. */
291 i = 0;
292 if (argv)
293 while (argv[i])
294 i++;
295 arg_list = xcalloc (i+2, sizeof *arg_list);
296 arg_list[0] = strrchr (pgmname, '/');
297 if (arg_list[0])
298 arg_list[0]++;
299 else
300 arg_list[0] = xstrdup (pgmname);
301 if (argv)
302 for (i=0,j=1; argv[i]; i++, j++)
303 arg_list[j] = (char*)argv[i];
304
305 /* Assign /dev/null to unused FDs. */
306 for (i=0; i <= 2; i++)
307 {
308 if (fds[i] == -1 )
309 {
310 fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
311 if (fds[i] == -1)
312 log_fatal ("failed to open '%s': %s\n",
313 "/dev/null", strerror (errno));
314 }
315 }
316
317 /* Connect the standard files. */
318 for (i=0; i <= 2; i++)
319 {
320 if (fds[i] != i && dup2 (fds[i], i) == -1)
321 log_fatal ("dup2 std%s failed: %s\n",
322 i==0?"in":i==1?"out":"err", strerror (errno));
323 }
324
325 /* Close all other files. */
326 close_all_fds (3, except);
327
328 if (preexec)
329 preexec ();
330 execv (pgmname, arg_list);
331 /* No way to print anything, as we have closed all streams. */
332 _exit (127);
333 }
334
335
336 static gpg_error_t
do_create_pipe(int filedes[2])337 do_create_pipe (int filedes[2])
338 {
339 gpg_error_t err = 0;
340
341 if (pipe (filedes) == -1)
342 {
343 err = my_error_from_syserror ();
344 filedes[0] = filedes[1] = -1;
345 }
346
347 return err;
348 }
349
350
351 static gpg_error_t
create_pipe_and_estream(int filedes[2],estream_t * r_fp,int outbound,int nonblock)352 create_pipe_and_estream (int filedes[2], estream_t *r_fp,
353 int outbound, int nonblock)
354 {
355 gpg_error_t err;
356
357 if (pipe (filedes) == -1)
358 {
359 err = my_error_from_syserror ();
360 log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
361 filedes[0] = filedes[1] = -1;
362 *r_fp = NULL;
363 return err;
364 }
365
366 if (!outbound)
367 *r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r");
368 else
369 *r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w");
370 if (!*r_fp)
371 {
372 err = my_error_from_syserror ();
373 log_error (_("error creating a stream for a pipe: %s\n"),
374 gpg_strerror (err));
375 close (filedes[0]);
376 close (filedes[1]);
377 filedes[0] = filedes[1] = -1;
378 return err;
379 }
380 return 0;
381 }
382
383
384 /* Portable function to create a pipe. Under Windows the write end is
385 inheritable. If R_FP is not NULL, an estream is created for the
386 read end and stored at R_FP. */
387 gpg_error_t
gnupg_create_inbound_pipe(int filedes[2],estream_t * r_fp,int nonblock)388 gnupg_create_inbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
389 {
390 if (r_fp)
391 return create_pipe_and_estream (filedes, r_fp, 0, nonblock);
392 else
393 return do_create_pipe (filedes);
394 }
395
396
397 /* Portable function to create a pipe. Under Windows the read end is
398 inheritable. If R_FP is not NULL, an estream is created for the
399 write end and stored at R_FP. */
400 gpg_error_t
gnupg_create_outbound_pipe(int filedes[2],estream_t * r_fp,int nonblock)401 gnupg_create_outbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
402 {
403 if (r_fp)
404 return create_pipe_and_estream (filedes, r_fp, 1, nonblock);
405 else
406 return do_create_pipe (filedes);
407 }
408
409
410 /* Portable function to create a pipe. Under Windows both ends are
411 inheritable. */
412 gpg_error_t
gnupg_create_pipe(int filedes[2])413 gnupg_create_pipe (int filedes[2])
414 {
415 return do_create_pipe (filedes);
416 }
417
418
419 /* Close the end of a pipe. */
420 void
gnupg_close_pipe(int fd)421 gnupg_close_pipe (int fd)
422 {
423 if (fd != -1)
424 close (fd);
425 }
426
427
428 /* Fork and exec the PGMNAME, see exechelp.h for details. */
429 gpg_error_t
gnupg_spawn_process(const char * pgmname,const char * argv[],int * except,void (* preexec)(void),unsigned int flags,estream_t * r_infp,estream_t * r_outfp,estream_t * r_errfp,pid_t * pid)430 gnupg_spawn_process (const char *pgmname, const char *argv[],
431 int *except, void (*preexec)(void), unsigned int flags,
432 estream_t *r_infp,
433 estream_t *r_outfp,
434 estream_t *r_errfp,
435 pid_t *pid)
436 {
437 gpg_error_t err;
438 int inpipe[2] = {-1, -1};
439 int outpipe[2] = {-1, -1};
440 int errpipe[2] = {-1, -1};
441 estream_t infp = NULL;
442 estream_t outfp = NULL;
443 estream_t errfp = NULL;
444 int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK);
445
446 if (r_infp)
447 *r_infp = NULL;
448 if (r_outfp)
449 *r_outfp = NULL;
450 if (r_errfp)
451 *r_errfp = NULL;
452 *pid = (pid_t)(-1); /* Always required. */
453
454 if (r_infp)
455 {
456 err = create_pipe_and_estream (inpipe, &infp, 1, nonblock);
457 if (err)
458 return err;
459 }
460
461 if (r_outfp)
462 {
463 err = create_pipe_and_estream (outpipe, &outfp, 0, nonblock);
464 if (err)
465 {
466 if (infp)
467 es_fclose (infp);
468 else if (inpipe[1] != -1)
469 close (inpipe[1]);
470 if (inpipe[0] != -1)
471 close (inpipe[0]);
472
473 return err;
474 }
475 }
476
477 if (r_errfp)
478 {
479 err = create_pipe_and_estream (errpipe, &errfp, 0, nonblock);
480 if (err)
481 {
482 if (infp)
483 es_fclose (infp);
484 else if (inpipe[1] != -1)
485 close (inpipe[1]);
486 if (inpipe[0] != -1)
487 close (inpipe[0]);
488
489 if (outfp)
490 es_fclose (outfp);
491 else if (outpipe[0] != -1)
492 close (outpipe[0]);
493 if (outpipe[1] != -1)
494 close (outpipe[1]);
495
496 return err;
497 }
498 }
499
500
501 *pid = fork ();
502 if (*pid == (pid_t)(-1))
503 {
504 err = my_error_from_syserror ();
505 log_error (_("error forking process: %s\n"), gpg_strerror (err));
506
507 if (infp)
508 es_fclose (infp);
509 else if (inpipe[1] != -1)
510 close (inpipe[1]);
511 if (inpipe[0] != -1)
512 close (inpipe[0]);
513
514 if (outfp)
515 es_fclose (outfp);
516 else if (outpipe[0] != -1)
517 close (outpipe[0]);
518 if (outpipe[1] != -1)
519 close (outpipe[1]);
520
521 if (errfp)
522 es_fclose (errfp);
523 else if (errpipe[0] != -1)
524 close (errpipe[0]);
525 if (errpipe[1] != -1)
526 close (errpipe[1]);
527 return err;
528 }
529
530 if (!*pid)
531 {
532 /* This is the child. */
533 gcry_control (GCRYCTL_TERM_SECMEM);
534 es_fclose (infp);
535 es_fclose (outfp);
536 es_fclose (errfp);
537 do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1],
538 except, preexec);
539 /*NOTREACHED*/
540 }
541
542 /* This is the parent. */
543 if (inpipe[0] != -1)
544 close (inpipe[0]);
545 if (outpipe[1] != -1)
546 close (outpipe[1]);
547 if (errpipe[1] != -1)
548 close (errpipe[1]);
549
550 if (r_infp)
551 *r_infp = infp;
552 if (r_outfp)
553 *r_outfp = outfp;
554 if (r_errfp)
555 *r_errfp = errfp;
556
557 return 0;
558 }
559
560
561
562 /* Simplified version of gnupg_spawn_process. This function forks and
563 then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
564 and ERRFD to stderr (any of them may be -1 to connect them to
565 /dev/null). The arguments for the process are expected in the NULL
566 terminated array ARGV. The program name itself should not be
567 included there. Calling gnupg_wait_process is required.
568
569 Returns 0 on success or an error code. */
570 gpg_error_t
gnupg_spawn_process_fd(const char * pgmname,const char * argv[],int infd,int outfd,int errfd,pid_t * pid)571 gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
572 int infd, int outfd, int errfd, pid_t *pid)
573 {
574 gpg_error_t err;
575
576 *pid = fork ();
577 if (*pid == (pid_t)(-1))
578 {
579 err = my_error_from_syserror ();
580 log_error (_("error forking process: %s\n"), strerror (errno));
581 return err;
582 }
583
584 if (!*pid)
585 {
586 gcry_control (GCRYCTL_TERM_SECMEM);
587 /* Run child. */
588 do_exec (pgmname, argv, infd, outfd, errfd, NULL, NULL);
589 /*NOTREACHED*/
590 }
591
592 return 0;
593 }
594
595
596
597
598 /* Waiting for child processes.
599
600 waitpid(2) may return information about terminated children that we
601 did not yet request, and there is no portable way to wait for a
602 specific set of children.
603
604 As a workaround, we store the results of children for later use.
605
606 XXX: This assumes that PIDs are not reused too quickly. */
607
608 struct terminated_child
609 {
610 pid_t pid;
611 int exitcode;
612 struct terminated_child *next;
613 };
614
615 struct terminated_child *terminated_children;
616
617
618 static gpg_error_t
store_result(pid_t pid,int exitcode)619 store_result (pid_t pid, int exitcode)
620 {
621 struct terminated_child *c;
622
623 c = xtrymalloc (sizeof *c);
624 if (c == NULL)
625 return gpg_err_code_from_syserror ();
626
627 c->pid = pid;
628 c->exitcode = exitcode;
629 c->next = terminated_children;
630 terminated_children = c;
631
632 return 0;
633 }
634
635
636 static int
get_result(pid_t pid,int * r_exitcode)637 get_result (pid_t pid, int *r_exitcode)
638 {
639 struct terminated_child *c, **prevp;
640
641 for (prevp = &terminated_children, c = terminated_children;
642 c;
643 prevp = &c->next, c = c->next)
644 if (c->pid == pid)
645 {
646 *prevp = c->next;
647 *r_exitcode = c->exitcode;
648 xfree (c);
649 return 1;
650 }
651
652 return 0;
653 }
654
655
656 /* See exechelp.h for a description. */
657 gpg_error_t
gnupg_wait_process(const char * pgmname,pid_t pid,int hang,int * r_exitcode)658 gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
659 {
660 gpg_err_code_t ec;
661 int i, status;
662
663 if (r_exitcode)
664 *r_exitcode = -1;
665
666 if (pid == (pid_t)(-1))
667 return gpg_error (GPG_ERR_INV_VALUE);
668
669 #ifdef USE_NPTH
670 i = npth_waitpid (pid, &status, hang? 0:WNOHANG);
671 #else
672 while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1)
673 && errno == EINTR);
674 #endif
675
676 if (i == (pid_t)(-1))
677 {
678 ec = gpg_err_code_from_errno (errno);
679 log_error (_("waiting for process %d to terminate failed: %s\n"),
680 (int)pid, strerror (errno));
681 }
682 else if (!i)
683 {
684 ec = GPG_ERR_TIMEOUT; /* Still running. */
685 }
686 else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
687 {
688 log_error (_("error running '%s': probably not installed\n"), pgmname);
689 ec = GPG_ERR_CONFIGURATION;
690 }
691 else if (WIFEXITED (status) && WEXITSTATUS (status))
692 {
693 if (!r_exitcode)
694 log_error (_("error running '%s': exit status %d\n"), pgmname,
695 WEXITSTATUS (status));
696 else
697 *r_exitcode = WEXITSTATUS (status);
698 ec = GPG_ERR_GENERAL;
699 }
700 else if (!WIFEXITED (status))
701 {
702 log_error (_("error running '%s': terminated\n"), pgmname);
703 ec = GPG_ERR_GENERAL;
704 }
705 else
706 {
707 if (r_exitcode)
708 *r_exitcode = 0;
709 ec = 0;
710 }
711
712 return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
713 }
714
715 /* See exechelp.h for a description. */
716 gpg_error_t
gnupg_wait_processes(const char ** pgmnames,pid_t * pids,size_t count,int hang,int * r_exitcodes)717 gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count,
718 int hang, int *r_exitcodes)
719 {
720 gpg_err_code_t ec = 0;
721 size_t i, left;
722 int *dummy = NULL;
723
724 if (r_exitcodes == NULL)
725 {
726 dummy = r_exitcodes = xtrymalloc (sizeof *r_exitcodes * count);
727 if (dummy == NULL)
728 return gpg_err_code_from_syserror ();
729 }
730
731 for (i = 0, left = count; i < count; i++)
732 {
733 int status = -1;
734
735 /* Skip invalid PID. */
736 if (pids[i] == (pid_t)(-1))
737 {
738 r_exitcodes[i] = -1;
739 left -= 1;
740 continue;
741 }
742
743 /* See if there was a previously stored result for this pid. */
744 if (get_result (pids[i], &status))
745 left -= 1;
746
747 r_exitcodes[i] = status;
748 }
749
750 while (left > 0)
751 {
752 pid_t pid;
753 int status;
754
755 #ifdef USE_NPTH
756 pid = npth_waitpid (-1, &status, hang ? 0 : WNOHANG);
757 #else
758 while ((pid = waitpid (-1, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1)
759 && errno == EINTR);
760 #endif
761
762 if (pid == (pid_t)(-1))
763 {
764 ec = gpg_err_code_from_errno (errno);
765 log_error (_("waiting for processes to terminate failed: %s\n"),
766 strerror (errno));
767 break;
768 }
769 else if (!pid)
770 {
771 ec = GPG_ERR_TIMEOUT; /* Still running. */
772 break;
773 }
774 else
775 {
776 for (i = 0; i < count; i++)
777 if (pid == pids[i])
778 break;
779
780 if (i == count)
781 {
782 /* No match, store this result. */
783 ec = store_result (pid, status);
784 if (ec)
785 break;
786 continue;
787 }
788
789 /* Process PIDS[i] died. */
790 if (r_exitcodes[i] != (pid_t) -1)
791 {
792 log_error ("PID %d was reused", pid);
793 ec = GPG_ERR_GENERAL;
794 break;
795 }
796
797 left -= 1;
798 r_exitcodes[i] = status;
799 }
800 }
801
802 for (i = 0; i < count; i++)
803 {
804 if (r_exitcodes[i] == -1)
805 continue;
806
807 if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i]) == 127)
808 {
809 log_error (_("error running '%s': probably not installed\n"),
810 pgmnames[i]);
811 ec = GPG_ERR_CONFIGURATION;
812 }
813 else if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i]))
814 {
815 if (dummy)
816 log_error (_("error running '%s': exit status %d\n"),
817 pgmnames[i], WEXITSTATUS (r_exitcodes[i]));
818 else
819 r_exitcodes[i] = WEXITSTATUS (r_exitcodes[i]);
820 ec = GPG_ERR_GENERAL;
821 }
822 else if (!WIFEXITED (r_exitcodes[i]))
823 {
824 log_error (_("error running '%s': terminated\n"), pgmnames[i]);
825 ec = GPG_ERR_GENERAL;
826 }
827 }
828
829 xfree (dummy);
830 return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
831 }
832
833
834
835 void
gnupg_release_process(pid_t pid)836 gnupg_release_process (pid_t pid)
837 {
838 (void)pid;
839 }
840
841
842 /* Spawn a new process and immediately detach from it. The name of
843 the program to exec is PGMNAME and its arguments are in ARGV (the
844 programname is automatically passed as first argument).
845 Environment strings in ENVP are set. An error is returned if
846 pgmname is not executable; to make this work it is necessary to
847 provide an absolute file name. All standard file descriptors are
848 connected to /dev/null. */
849 gpg_error_t
gnupg_spawn_process_detached(const char * pgmname,const char * argv[],const char * envp[])850 gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
851 const char *envp[] )
852 {
853 gpg_err_code_t ec;
854 pid_t pid;
855 int i;
856
857 if (getuid() != geteuid())
858 return my_error (GPG_ERR_BUG);
859
860 if ((ec = gnupg_access (pgmname, X_OK)))
861 return gpg_err_make (default_errsource, ec);
862
863 pid = fork ();
864 if (pid == (pid_t)(-1))
865 {
866 log_error (_("error forking process: %s\n"), strerror (errno));
867 return my_error_from_syserror ();
868 }
869 if (!pid)
870 {
871 pid_t pid2;
872
873 gcry_control (GCRYCTL_TERM_SECMEM);
874 if (setsid() == -1 || chdir ("/"))
875 _exit (1);
876
877 pid2 = fork (); /* Double fork to let init take over the new child. */
878 if (pid2 == (pid_t)(-1))
879 _exit (1);
880 if (pid2)
881 _exit (0); /* Let the parent exit immediately. */
882
883 if (envp)
884 for (i=0; envp[i]; i++)
885 putenv (xstrdup (envp[i]));
886
887 do_exec (pgmname, argv, -1, -1, -1, NULL, NULL);
888
889 /*NOTREACHED*/
890 }
891
892 if (waitpid (pid, NULL, 0) == -1)
893 log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
894 strerror (errno));
895
896 return 0;
897 }
898
899
900 /* Kill a process; that is send an appropriate signal to the process.
901 gnupg_wait_process must be called to actually remove the process
902 from the system. An invalid PID is ignored. */
903 void
gnupg_kill_process(pid_t pid)904 gnupg_kill_process (pid_t pid)
905 {
906 if (pid != (pid_t)(-1))
907 {
908 kill (pid, SIGTERM);
909 }
910 }
911