common/exechelp: Add general pipe function.
[gnupg.git] / common / exechelp-posix.c
1 /* exechelp.c - Fork and exec helpers for POSIX
2  * Copyright (C) 2004, 2007, 2008, 2009,
3  *               2010 Free Software Foundation, Inc.
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 <http://www.gnu.org/licenses/>.
29  */
30
31 #include <config.h>
32
33 #if defined(HAVE_W32_SYSTEM) || defined (HAVE_W32CE_SYSTEM)
34 #error This code is only used on POSIX
35 #endif
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #ifdef HAVE_STDINT_H
40 # include <stdint.h>
41 #endif
42 #include <string.h>
43 #include <errno.h>
44 #include <assert.h>
45 #ifdef HAVE_SIGNAL_H
46 # include <signal.h>
47 #endif
48 #include <unistd.h>
49 #include <fcntl.h>
50
51 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
52 #undef HAVE_NPTH
53 #undef USE_NPTH
54 #endif
55
56 #ifdef HAVE_NPTH
57 #include <npth.h>
58 #endif
59 #include <sys/wait.h>
60
61 #ifdef HAVE_GETRLIMIT
62 #include <sys/time.h>
63 #include <sys/resource.h>
64 #endif /*HAVE_GETRLIMIT*/
65
66 #ifdef HAVE_STAT
67 # include <sys/stat.h>
68 #endif
69
70 #include "util.h"
71 #include "i18n.h"
72 #include "sysutils.h"
73 #include "exechelp.h"
74
75
76 /* Return the maximum number of currently allowed open file
77    descriptors.  Only useful on POSIX systems but returns a value on
78    other systems too.  */
79 int
80 get_max_fds (void)
81 {
82   int max_fds = -1;
83 #ifdef HAVE_GETRLIMIT
84   struct rlimit rl;
85
86 # ifdef RLIMIT_NOFILE
87   if (!getrlimit (RLIMIT_NOFILE, &rl))
88     max_fds = rl.rlim_max;
89 # endif
90
91 # ifdef RLIMIT_OFILE
92   if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
93     max_fds = rl.rlim_max;
94
95 # endif
96 #endif /*HAVE_GETRLIMIT*/
97
98 #ifdef _SC_OPEN_MAX
99   if (max_fds == -1)
100     {
101       long int scres = sysconf (_SC_OPEN_MAX);
102       if (scres >= 0)
103         max_fds = scres;
104     }
105 #endif
106
107 #ifdef _POSIX_OPEN_MAX
108   if (max_fds == -1)
109     max_fds = _POSIX_OPEN_MAX;
110 #endif
111
112 #ifdef OPEN_MAX
113   if (max_fds == -1)
114     max_fds = OPEN_MAX;
115 #endif
116
117   if (max_fds == -1)
118     max_fds = 256;  /* Arbitrary limit.  */
119
120   /* AIX returns INT32_MAX instead of a proper value.  We assume that
121      this is always an error and use an arbitrary limit.  */
122 #ifdef INT32_MAX
123   if (max_fds == INT32_MAX)
124     max_fds = 256;
125 #endif
126
127   return max_fds;
128 }
129
130
131 /* Close all file descriptors starting with descriptor FIRST.  If
132    EXCEPT is not NULL, it is expected to be a list of file descriptors
133    which shall not be closed.  This list shall be sorted in ascending
134    order with the end marked by -1.  */
135 void
136 close_all_fds (int first, int *except)
137 {
138   int max_fd = get_max_fds ();
139   int fd, i, except_start;
140
141   if (except)
142     {
143       except_start = 0;
144       for (fd=first; fd < max_fd; fd++)
145         {
146           for (i=except_start; except[i] != -1; i++)
147             {
148               if (except[i] == fd)
149                 {
150                   /* If we found the descriptor in the exception list
151                      we can start the next compare run at the next
152                      index because the exception list is ordered.  */
153                 except_start = i + 1;
154                 break;
155                 }
156             }
157           if (except[i] == -1)
158             close (fd);
159         }
160     }
161   else
162     {
163       for (fd=first; fd < max_fd; fd++)
164         close (fd);
165     }
166
167   gpg_err_set_errno (0);
168 }
169
170
171 /* Returns an array with all currently open file descriptors.  The end
172    of the array is marked by -1.  The caller needs to release this
173    array using the *standard free* and not with xfree.  This allow the
174    use of this function right at startup even before libgcrypt has
175    been initialized.  Returns NULL on error and sets ERRNO
176    accordingly.  */
177 int *
178 get_all_open_fds (void)
179 {
180   int *array;
181   size_t narray;
182   int fd, max_fd, idx;
183 #ifndef HAVE_STAT
184   array = calloc (1, sizeof *array);
185   if (array)
186     array[0] = -1;
187 #else /*HAVE_STAT*/
188   struct stat statbuf;
189
190   max_fd = get_max_fds ();
191   narray = 32;  /* If you change this change also t-exechelp.c.  */
192   array = calloc (narray, sizeof *array);
193   if (!array)
194     return NULL;
195
196   /* Note:  The list we return is ordered.  */
197   for (idx=0, fd=0; fd < max_fd; fd++)
198     if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
199       {
200         if (idx+1 >= narray)
201           {
202             int *tmp;
203
204             narray += (narray < 256)? 32:256;
205             tmp = realloc (array, narray * sizeof *array);
206             if (!tmp)
207               {
208                 free (array);
209                 return NULL;
210               }
211             array = tmp;
212           }
213         array[idx++] = fd;
214       }
215   array[idx] = -1;
216 #endif /*HAVE_STAT*/
217   return array;
218 }
219
220
221 /* The exec core used right after the fork. This will never return. */
222 static void
223 do_exec (const char *pgmname, const char *argv[],
224          int fd_in, int fd_out, int fd_err,
225          void (*preexec)(void) )
226 {
227   char **arg_list;
228   int i, j;
229   int fds[3];
230
231   fds[0] = fd_in;
232   fds[1] = fd_out;
233   fds[2] = fd_err;
234
235   /* Create the command line argument array.  */
236   i = 0;
237   if (argv)
238     while (argv[i])
239       i++;
240   arg_list = xcalloc (i+2, sizeof *arg_list);
241   arg_list[0] = strrchr (pgmname, '/');
242   if (arg_list[0])
243     arg_list[0]++;
244   else
245     arg_list[0] = xstrdup (pgmname);
246   if (argv)
247     for (i=0,j=1; argv[i]; i++, j++)
248       arg_list[j] = (char*)argv[i];
249
250   /* Assign /dev/null to unused FDs. */
251   for (i=0; i <= 2; i++)
252     {
253       if (fds[i] == -1 )
254         {
255           fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
256           if (fds[i] == -1)
257             log_fatal ("failed to open '%s': %s\n",
258                        "/dev/null", strerror (errno));
259         }
260     }
261
262   /* Connect the standard files.  */
263   for (i=0; i <= 2; i++)
264     {
265       if (fds[i] != i && dup2 (fds[i], i) == -1)
266         log_fatal ("dup2 std%s failed: %s\n",
267                    i==0?"in":i==1?"out":"err", strerror (errno));
268     }
269
270   /* Close all other files. */
271   close_all_fds (3, NULL);
272
273   if (preexec)
274     preexec ();
275   execv (pgmname, arg_list);
276   /* No way to print anything, as we have closed all streams. */
277   _exit (127);
278 }
279
280
281 static gpg_error_t
282 do_create_pipe (int filedes[2])
283 {
284   gpg_error_t err = 0;
285
286   if (pipe (filedes) == -1)
287     {
288       err = gpg_error_from_syserror ();
289       filedes[0] = filedes[1] = -1;
290     }
291
292   return err;
293 }
294
295 /* Portable function to create a pipe.  Under Windows the write end is
296    inheritable.  */
297 gpg_error_t
298 gnupg_create_inbound_pipe (int filedes[2])
299 {
300   return do_create_pipe (filedes);
301 }
302
303
304 /* Portable function to create a pipe.  Under Windows the read end is
305    inheritable.  */
306 gpg_error_t
307 gnupg_create_outbound_pipe (int filedes[2])
308 {
309   return do_create_pipe (filedes);
310 }
311
312
313 /* Portable function to create a pipe.  Under Windows both ends are
314    inheritable.  */
315 gpg_error_t
316 gnupg_create_pipe (int filedes[2])
317 {
318   return do_create_pipe (filedes);
319 }
320
321
322
323 static gpg_error_t
324 create_pipe_and_estream (int filedes[2], estream_t *r_fp,
325                          int outbound, int nonblock,
326                          gpg_err_source_t errsource)
327 {
328   gpg_error_t err;
329
330   if (pipe (filedes) == -1)
331     {
332       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
333       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
334       filedes[0] = filedes[1] = -1;
335       *r_fp = NULL;
336       return err;
337     }
338
339   if (outbound)
340     *r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r");
341   else
342     *r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w");
343   if (!*r_fp)
344     {
345       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
346       log_error (_("error creating a stream for a pipe: %s\n"),
347                  gpg_strerror (err));
348       close (filedes[0]);
349       close (filedes[1]);
350       filedes[0] = filedes[1] = -1;
351       return err;
352     }
353   return 0;
354 }
355
356
357
358 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
359 gpg_error_t
360 gnupg_spawn_process (const char *pgmname, const char *argv[],
361                      gpg_err_source_t errsource,
362                      void (*preexec)(void), unsigned int flags,
363                      estream_t *r_infp,
364                      estream_t *r_outfp,
365                      estream_t *r_errfp,
366                      pid_t *pid)
367 {
368   gpg_error_t err;
369   int inpipe[2] = {-1, -1};
370   int outpipe[2] = {-1, -1};
371   int errpipe[2] = {-1, -1};
372   estream_t infp = NULL;
373   estream_t outfp = NULL;
374   estream_t errfp = NULL;
375   int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK);
376
377   if (r_infp)
378     *r_infp = NULL;
379   if (r_outfp)
380     *r_outfp = NULL;
381   if (r_errfp)
382     *r_errfp = NULL;
383   *pid = (pid_t)(-1); /* Always required.  */
384
385   if (r_infp)
386     {
387       err = create_pipe_and_estream (inpipe, &infp, 0, nonblock, errsource);
388       if (err)
389         return err;
390     }
391
392   if (r_outfp)
393     {
394       err = create_pipe_and_estream (outpipe, &outfp, 1, nonblock, errsource);
395       if (err)
396         {
397           if (infp)
398             es_fclose (infp);
399           else if (inpipe[1] != -1)
400             close (inpipe[1]);
401           if (inpipe[0] != -1)
402             close (inpipe[0]);
403
404           return err;
405         }
406     }
407
408   if (r_errfp)
409     {
410       err = create_pipe_and_estream (errpipe, &errfp, 1, nonblock, errsource);
411       if (err)
412         {
413           if (infp)
414             es_fclose (infp);
415           else if (inpipe[1] != -1)
416             close (inpipe[1]);
417           if (inpipe[0] != -1)
418             close (inpipe[0]);
419
420           if (outfp)
421             es_fclose (outfp);
422           else if (outpipe[0] != -1)
423             close (outpipe[0]);
424           if (outpipe[1] != -1)
425             close (outpipe[1]);
426
427           return err;
428         }
429     }
430
431
432   *pid = fork ();
433   if (*pid == (pid_t)(-1))
434     {
435       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
436       log_error (_("error forking process: %s\n"), gpg_strerror (err));
437
438       if (infp)
439         es_fclose (infp);
440       else if (inpipe[1] != -1)
441         close (inpipe[1]);
442       if (inpipe[0] != -1)
443         close (inpipe[0]);
444
445       if (outfp)
446         es_fclose (outfp);
447       else if (outpipe[0] != -1)
448         close (outpipe[0]);
449       if (outpipe[1] != -1)
450         close (outpipe[1]);
451
452       if (errfp)
453         es_fclose (errfp);
454       else if (errpipe[0] != -1)
455         close (errpipe[0]);
456       if (errpipe[1] != -1)
457         close (errpipe[1]);
458       return err;
459     }
460
461   if (!*pid)
462     {
463       /* This is the child. */
464       gcry_control (GCRYCTL_TERM_SECMEM);
465       es_fclose (outfp);
466       es_fclose (errfp);
467       do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], preexec);
468       /*NOTREACHED*/
469     }
470
471   /* This is the parent. */
472   if (inpipe[0] != -1)
473     close (inpipe[0]);
474   if (outpipe[1] != -1)
475     close (outpipe[1]);
476   if (errpipe[1] != -1)
477     close (errpipe[1]);
478
479   if (r_infp)
480     *r_infp = infp;
481   if (r_outfp)
482     *r_outfp = outfp;
483   if (r_errfp)
484     *r_errfp = errfp;
485
486   return 0;
487 }
488
489
490
491 /* Simplified version of gnupg_spawn_process.  This function forks and
492    then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
493    and ERRFD to stderr (any of them may be -1 to connect them to
494    /dev/null).  The arguments for the process are expected in the NULL
495    terminated array ARGV.  The program name itself should not be
496    included there.  Calling gnupg_wait_process is required.
497
498    Returns 0 on success or an error code. */
499 gpg_error_t
500 gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
501                         int infd, int outfd, int errfd, pid_t *pid)
502 {
503   gpg_error_t err;
504
505   *pid = fork ();
506   if (*pid == (pid_t)(-1))
507     {
508       err = gpg_error_from_syserror ();
509       log_error (_("error forking process: %s\n"), strerror (errno));
510       return err;
511     }
512
513   if (!*pid)
514     {
515       gcry_control (GCRYCTL_TERM_SECMEM);
516       /* Run child. */
517       do_exec (pgmname, argv, infd, outfd, errfd, NULL);
518       /*NOTREACHED*/
519     }
520
521   return 0;
522 }
523
524
525 /* See exechelp.h for the description.  */
526 gpg_error_t
527 gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
528 {
529   gpg_err_code_t ec;
530   int i, status;
531
532   if (r_exitcode)
533     *r_exitcode = -1;
534
535   if (pid == (pid_t)(-1))
536     return gpg_error (GPG_ERR_INV_VALUE);
537
538 #ifdef USE_NPTH
539   i = npth_waitpid (pid, &status, hang? 0:WNOHANG);
540 #else
541   while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1)
542          && errno == EINTR);
543 #endif
544
545   if (i == (pid_t)(-1))
546     {
547       ec = gpg_err_code_from_errno (errno);
548       log_error (_("waiting for process %d to terminate failed: %s\n"),
549                  (int)pid, strerror (errno));
550     }
551   else if (!i)
552     {
553       ec = GPG_ERR_TIMEOUT; /* Still running.  */
554     }
555   else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
556     {
557       log_error (_("error running '%s': probably not installed\n"), pgmname);
558       ec = GPG_ERR_CONFIGURATION;
559     }
560   else if (WIFEXITED (status) && WEXITSTATUS (status))
561     {
562       if (!r_exitcode)
563         log_error (_("error running '%s': exit status %d\n"), pgmname,
564                    WEXITSTATUS (status));
565       else
566         *r_exitcode = WEXITSTATUS (status);
567       ec = GPG_ERR_GENERAL;
568     }
569   else if (!WIFEXITED (status))
570     {
571       log_error (_("error running '%s': terminated\n"), pgmname);
572       ec = GPG_ERR_GENERAL;
573     }
574   else
575     {
576       if (r_exitcode)
577         *r_exitcode = 0;
578       ec = 0;
579     }
580
581   return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
582 }
583
584
585 void
586 gnupg_release_process (pid_t pid)
587 {
588   (void)pid;
589 }
590
591
592 /* Spawn a new process and immediately detach from it.  The name of
593    the program to exec is PGMNAME and its arguments are in ARGV (the
594    programname is automatically passed as first argument).
595    Environment strings in ENVP are set.  An error is returned if
596    pgmname is not executable; to make this work it is necessary to
597    provide an absolute file name.  All standard file descriptors are
598    connected to /dev/null. */
599 gpg_error_t
600 gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
601                               const char *envp[] )
602 {
603   pid_t pid;
604   int i;
605
606   if (getuid() != geteuid())
607     return gpg_error (GPG_ERR_BUG);
608
609   if (access (pgmname, X_OK))
610     return gpg_error_from_syserror ();
611
612   pid = fork ();
613   if (pid == (pid_t)(-1))
614     {
615       log_error (_("error forking process: %s\n"), strerror (errno));
616       return gpg_error_from_syserror ();
617     }
618   if (!pid)
619     {
620       pid_t pid2;
621
622       gcry_control (GCRYCTL_TERM_SECMEM);
623       if (setsid() == -1 || chdir ("/"))
624         _exit (1);
625
626       pid2 = fork (); /* Double fork to let init take over the new child. */
627       if (pid2 == (pid_t)(-1))
628         _exit (1);
629       if (pid2)
630         _exit (0);  /* Let the parent exit immediately. */
631
632       if (envp)
633         for (i=0; envp[i]; i++)
634           putenv (xstrdup (envp[i]));
635
636       do_exec (pgmname, argv, -1, -1, -1, NULL);
637
638       /*NOTREACHED*/
639     }
640
641   if (waitpid (pid, NULL, 0) == -1)
642     log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
643                strerror (errno));
644
645   return 0;
646 }
647
648
649 /* Kill a process; that is send an appropriate signal to the process.
650    gnupg_wait_process must be called to actually remove the process
651    from the system.  An invalid PID is ignored.  */
652 void
653 gnupg_kill_process (pid_t pid)
654 {
655   if (pid != (pid_t)(-1))
656     {
657       kill (pid, SIGTERM);
658     }
659 }