D-Bus  1.13.7
dbus-spawn-unix.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-spawn-unix.c — Wrapper around fork/exec
3  *
4  * Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 
27 #if defined(DBUS_WIN) || !defined(DBUS_UNIX)
28 #error "This file only makes sense on Unix OSs"
29 #endif
30 
31 #include "dbus-spawn.h"
32 #include "dbus-sysdeps-unix.h"
33 #include "dbus-internals.h"
34 #include "dbus-test.h"
35 #include "dbus-protocol.h"
36 
37 #include <unistd.h>
38 #include <fcntl.h>
39 #include <signal.h>
40 #include <sys/wait.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #ifdef HAVE_ERRNO_H
44 #include <errno.h>
45 #endif
46 #ifdef HAVE_SYSTEMD
47 #ifdef HAVE_SYSLOG_H
48 #include <syslog.h>
49 #endif
50 #include <systemd/sd-journal.h>
51 #endif
52 
53 #if defined(__APPLE__)
54 # include <crt_externs.h>
55 # define environ (*_NSGetEnviron ())
56 #elif !HAVE_DECL_ENVIRON
57 extern char **environ;
58 #endif
59 
65 /*
66  * I'm pretty sure this whole spawn file could be made simpler,
67  * if you thought about it a bit.
68  */
69 
73 typedef enum
74 {
78 } ReadStatus;
79 
80 static ReadStatus
81 read_ints (int fd,
82  int *buf,
83  int n_ints_in_buf,
84  int *n_ints_read,
85  DBusError *error)
86 {
87  size_t bytes = 0;
88  ReadStatus retval;
89 
90  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
91 
92  retval = READ_STATUS_OK;
93 
94  while (TRUE)
95  {
96  ssize_t chunk;
97  size_t to_read;
98 
99  to_read = sizeof (int) * n_ints_in_buf - bytes;
100 
101  if (to_read == 0)
102  break;
103 
104  again:
105 
106  chunk = read (fd,
107  ((char*)buf) + bytes,
108  to_read);
109 
110  if (chunk < 0 && errno == EINTR)
111  goto again;
112 
113  if (chunk < 0)
114  {
115  dbus_set_error (error,
117  "Failed to read from child pipe (%s)",
118  _dbus_strerror (errno));
119 
120  retval = READ_STATUS_ERROR;
121  break;
122  }
123  else if (chunk == 0)
124  {
125  retval = READ_STATUS_EOF;
126  break; /* EOF */
127  }
128  else /* chunk > 0 */
129  bytes += chunk;
130  }
131 
132  *n_ints_read = (int)(bytes / sizeof(int));
133 
134  return retval;
135 }
136 
137 static ReadStatus
138 read_pid (int fd,
139  pid_t *buf,
140  DBusError *error)
141 {
142  size_t bytes = 0;
143  ReadStatus retval;
144 
145  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
146 
147  retval = READ_STATUS_OK;
148 
149  while (TRUE)
150  {
151  ssize_t chunk;
152  size_t to_read;
153 
154  to_read = sizeof (pid_t) - bytes;
155 
156  if (to_read == 0)
157  break;
158 
159  again:
160 
161  chunk = read (fd,
162  ((char*)buf) + bytes,
163  to_read);
164  if (chunk < 0 && errno == EINTR)
165  goto again;
166 
167  if (chunk < 0)
168  {
169  dbus_set_error (error,
171  "Failed to read from child pipe (%s)",
172  _dbus_strerror (errno));
173 
174  retval = READ_STATUS_ERROR;
175  break;
176  }
177  else if (chunk == 0)
178  {
179  retval = READ_STATUS_EOF;
180  break; /* EOF */
181  }
182  else /* chunk > 0 */
183  bytes += chunk;
184  }
185 
186  return retval;
187 }
188 
189 /* The implementation uses an intermediate child between the main process
190  * and the grandchild. The grandchild is our spawned process. The intermediate
191  * child is a babysitter process; it keeps track of when the grandchild
192  * exits/crashes, and reaps the grandchild.
193  *
194  * We automatically reap the babysitter process, killing it if necessary,
195  * when the DBusBabysitter's refcount goes to zero.
196  *
197  * Processes:
198  *
199  * main process
200  * | fork() A
201  * \- babysitter
202  * | fork () B
203  * \- grandchild --> exec --> spawned process
204  *
205  * IPC:
206  * child_err_report_pipe
207  * /-----------<---------<--------------\
208  * | ^
209  * v |
210  * main process babysitter grandchild
211  * ^ ^
212  * v v
213  * \-------<->-------/
214  * babysitter_pipe
215  *
216  * child_err_report_pipe is genuinely a pipe.
217  * The READ_END (also called error_pipe_from_child) is used in the main
218  * process. The WRITE_END (also called child_err_report_fd) is used in
219  * the grandchild process.
220  *
221  * On failure, the grandchild process sends CHILD_EXEC_FAILED + errno.
222  * On success, the pipe just closes (because it's close-on-exec) without
223  * sending any bytes.
224  *
225  * babysitter_pipe is mis-named: it's really a bidirectional socketpair.
226  * The [0] end (also called socket_to_babysitter) is used in the main
227  * process, the [1] end (also called parent_pipe) is used in the babysitter.
228  *
229  * If the fork() labelled B in the diagram above fails, the babysitter sends
230  * CHILD_FORK_FAILED + errno.
231  * On success, the babysitter sends CHILD_PID + the grandchild's pid.
232  * On SIGCHLD, the babysitter sends CHILD_EXITED + the exit status.
233  * The main process doesn't explicitly send anything, but when it exits,
234  * the babysitter gets POLLHUP or POLLERR.
235  */
236 
237 /* Messages from children to parents */
238 enum
239 {
240  CHILD_EXITED, /* This message is followed by the exit status int */
241  CHILD_FORK_FAILED, /* Followed by errno */
242  CHILD_EXEC_FAILED, /* Followed by errno */
243  CHILD_PID /* Followed by pid_t */
244 };
245 
250 {
251  int refcount;
253  char *log_name;
259  pid_t sitter_pid;
267  DBusBabysitterFinishedFunc finished_cb;
268  void *finished_data;
269 
270  int errnum;
271  int status;
272  unsigned int have_child_status : 1;
273  unsigned int have_fork_errnum : 1;
274  unsigned int have_exec_errnum : 1;
275 };
276 
277 static DBusBabysitter*
278 _dbus_babysitter_new (void)
279 {
280  DBusBabysitter *sitter;
281 
282  sitter = dbus_new0 (DBusBabysitter, 1);
283  if (sitter == NULL)
284  return NULL;
285 
286  sitter->refcount = 1;
287 
288  sitter->socket_to_babysitter.fd = -1;
289  sitter->error_pipe_from_child = -1;
290 
291  sitter->sitter_pid = -1;
292  sitter->grandchild_pid = -1;
293 
294  sitter->watches = _dbus_watch_list_new ();
295  if (sitter->watches == NULL)
296  goto failed;
297 
298  return sitter;
299 
300  failed:
301  _dbus_babysitter_unref (sitter);
302  return NULL;
303 }
304 
313 {
314  _dbus_assert (sitter != NULL);
315  _dbus_assert (sitter->refcount > 0);
316 
317  sitter->refcount += 1;
318 
319  return sitter;
320 }
321 
322 static void close_socket_to_babysitter (DBusBabysitter *sitter);
323 static void close_error_pipe_from_child (DBusBabysitter *sitter);
324 
333 void
335 {
336  _dbus_assert (sitter != NULL);
337  _dbus_assert (sitter->refcount > 0);
338 
339  sitter->refcount -= 1;
340  if (sitter->refcount == 0)
341  {
342  /* If we haven't forked other babysitters
343  * since this babysitter and socket were
344  * created then this close will cause the
345  * babysitter to wake up from poll with
346  * a hangup and then the babysitter will
347  * quit itself.
348  */
349  close_socket_to_babysitter (sitter);
350 
351  close_error_pipe_from_child (sitter);
352 
353  if (sitter->sitter_pid > 0)
354  {
355  int status;
356  int ret;
357 
358  /* It's possible the babysitter died on its own above
359  * from the close, or was killed randomly
360  * by some other process, so first try to reap it
361  */
362  ret = waitpid (sitter->sitter_pid, &status, WNOHANG);
363 
364  /* If we couldn't reap the child then kill it, and
365  * try again
366  */
367  if (ret == 0)
368  kill (sitter->sitter_pid, SIGKILL);
369 
370  if (ret == 0)
371  {
372  do
373  {
374  ret = waitpid (sitter->sitter_pid, &status, 0);
375  }
376  while (_DBUS_UNLIKELY (ret < 0 && errno == EINTR));
377  }
378 
379  if (ret < 0)
380  {
381  if (errno == ECHILD)
382  _dbus_warn ("Babysitter process not available to be reaped; should not happen");
383  else
384  _dbus_warn ("Unexpected error %d in waitpid() for babysitter: %s",
385  errno, _dbus_strerror (errno));
386  }
387  else
388  {
389  _dbus_verbose ("Reaped %ld, waiting for babysitter %ld\n",
390  (long) ret, (long) sitter->sitter_pid);
391 
392  if (WIFEXITED (sitter->status))
393  _dbus_verbose ("Babysitter exited with status %d\n",
394  WEXITSTATUS (sitter->status));
395  else if (WIFSIGNALED (sitter->status))
396  _dbus_verbose ("Babysitter received signal %d\n",
397  WTERMSIG (sitter->status));
398  else
399  _dbus_verbose ("Babysitter exited abnormally\n");
400  }
401 
402  sitter->sitter_pid = -1;
403  }
404 
405  if (sitter->watches)
406  _dbus_watch_list_free (sitter->watches);
407 
408  dbus_free (sitter->log_name);
409 
410  dbus_free (sitter);
411  }
412 }
413 
414 static ReadStatus
415 read_data (DBusBabysitter *sitter,
416  int fd)
417 {
418  int what;
419  int got;
420  DBusError error = DBUS_ERROR_INIT;
421  ReadStatus r;
422 
423  r = read_ints (fd, &what, 1, &got, &error);
424 
425  switch (r)
426  {
427  case READ_STATUS_ERROR:
428  _dbus_warn ("Failed to read data from fd %d: %s", fd, error.message);
429  dbus_error_free (&error);
430  return r;
431 
432  case READ_STATUS_EOF:
433  return r;
434 
435  case READ_STATUS_OK:
436  break;
437 
438  default:
439  _dbus_assert_not_reached ("invalid ReadStatus");
440  break;
441  }
442 
443  if (got == 1)
444  {
445  switch (what)
446  {
447  case CHILD_EXITED:
448  case CHILD_FORK_FAILED:
449  case CHILD_EXEC_FAILED:
450  {
451  int arg;
452 
453  r = read_ints (fd, &arg, 1, &got, &error);
454 
455  switch (r)
456  {
457  case READ_STATUS_ERROR:
458  _dbus_warn ("Failed to read arg from fd %d: %s", fd, error.message);
459  dbus_error_free (&error);
460  return r;
461  case READ_STATUS_EOF:
462  return r;
463  case READ_STATUS_OK:
464  break;
465  default:
466  _dbus_assert_not_reached ("invalid ReadStatus");
467  break;
468  }
469 
470  if (got == 1)
471  {
472  if (what == CHILD_EXITED)
473  {
474  /* Do not reset sitter->errnum to 0 here. We get here if
475  * the babysitter reports that the grandchild process has
476  * exited, and there are two ways that can happen:
477  *
478  * 1. grandchild successfully exec()s the desired process,
479  * but then the desired process exits or is terminated
480  * by a signal. The babysitter observes this and reports
481  * CHILD_EXITED.
482  *
483  * 2. grandchild fails to exec() the desired process,
484  * attempts to report the exec() failure (which
485  * we will receive as CHILD_EXEC_FAILED), and then
486  * exits itself (which will prompt the babysitter to
487  * send CHILD_EXITED). We want the CHILD_EXEC_FAILED
488  * to take precedence (and have its errno logged),
489  * which _dbus_babysitter_set_child_exit_error() does.
490  */
491  sitter->have_child_status = TRUE;
492  sitter->status = arg;
493  _dbus_verbose ("recorded child status exited = %d signaled = %d exitstatus = %d termsig = %d\n",
494  WIFEXITED (sitter->status), WIFSIGNALED (sitter->status),
495  WEXITSTATUS (sitter->status), WTERMSIG (sitter->status));
496  }
497  else if (what == CHILD_FORK_FAILED)
498  {
499  sitter->have_fork_errnum = TRUE;
500  sitter->errnum = arg;
501  _dbus_verbose ("recorded fork errnum %d\n", sitter->errnum);
502  }
503  else if (what == CHILD_EXEC_FAILED)
504  {
505  sitter->have_exec_errnum = TRUE;
506  sitter->errnum = arg;
507  _dbus_verbose ("recorded exec errnum %d\n", sitter->errnum);
508  }
509  }
510  }
511  break;
512  case CHILD_PID:
513  {
514  pid_t pid = -1;
515 
516  r = read_pid (fd, &pid, &error);
517 
518  switch (r)
519  {
520  case READ_STATUS_ERROR:
521  _dbus_warn ("Failed to read PID from fd %d: %s", fd, error.message);
522  dbus_error_free (&error);
523  return r;
524  case READ_STATUS_EOF:
525  return r;
526  case READ_STATUS_OK:
527  break;
528  default:
529  _dbus_assert_not_reached ("invalid ReadStatus");
530  break;
531  }
532 
533  sitter->grandchild_pid = pid;
534 
535  _dbus_verbose ("recorded grandchild pid %d\n", sitter->grandchild_pid);
536  }
537  break;
538  default:
539  _dbus_warn ("Unknown message received from babysitter process");
540  break;
541  }
542  }
543 
544  return r;
545 }
546 
547 static void
548 close_socket_to_babysitter (DBusBabysitter *sitter)
549 {
550  _dbus_verbose ("Closing babysitter\n");
551 
552  if (sitter->sitter_watch != NULL)
553  {
554  _dbus_assert (sitter->watches != NULL);
558  sitter->sitter_watch = NULL;
559  }
560 
561  if (sitter->socket_to_babysitter.fd >= 0)
562  {
564  sitter->socket_to_babysitter.fd = -1;
565  }
566 }
567 
568 static void
569 close_error_pipe_from_child (DBusBabysitter *sitter)
570 {
571  _dbus_verbose ("Closing child error\n");
572 
573  if (sitter->error_watch != NULL)
574  {
575  _dbus_assert (sitter->watches != NULL);
578  _dbus_watch_unref (sitter->error_watch);
579  sitter->error_watch = NULL;
580  }
581 
582  if (sitter->error_pipe_from_child >= 0)
583  {
585  sitter->error_pipe_from_child = -1;
586  }
587 }
588 
589 static void
590 handle_babysitter_socket (DBusBabysitter *sitter,
591  int revents)
592 {
593  /* Even if we have POLLHUP, we want to keep reading
594  * data until POLLIN goes away; so this function only
595  * looks at HUP/ERR if no IN is set.
596  */
597  if (revents & _DBUS_POLLIN)
598  {
599  _dbus_verbose ("Reading data from babysitter\n");
600  if (read_data (sitter, sitter->socket_to_babysitter.fd) != READ_STATUS_OK)
601  close_socket_to_babysitter (sitter);
602  }
603  else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
604  {
605  close_socket_to_babysitter (sitter);
606  }
607 }
608 
609 static void
610 handle_error_pipe (DBusBabysitter *sitter,
611  int revents)
612 {
613  if (revents & _DBUS_POLLIN)
614  {
615  _dbus_verbose ("Reading data from child error\n");
616  if (read_data (sitter, sitter->error_pipe_from_child) != READ_STATUS_OK)
617  close_error_pipe_from_child (sitter);
618  }
619  else if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
620  {
621  close_error_pipe_from_child (sitter);
622  }
623 }
624 
625 /* returns whether there were any poll events handled */
626 static dbus_bool_t
627 babysitter_iteration (DBusBabysitter *sitter,
628  dbus_bool_t block)
629 {
630  DBusPollFD fds[2];
631  int i;
632  dbus_bool_t descriptors_ready;
633 
634  descriptors_ready = FALSE;
635 
636  i = 0;
637 
638  if (sitter->error_pipe_from_child >= 0)
639  {
640  fds[i].fd = sitter->error_pipe_from_child;
641  fds[i].events = _DBUS_POLLIN;
642  fds[i].revents = 0;
643  ++i;
644  }
645 
646  if (sitter->socket_to_babysitter.fd >= 0)
647  {
648  fds[i].fd = sitter->socket_to_babysitter.fd;
649  fds[i].events = _DBUS_POLLIN;
650  fds[i].revents = 0;
651  ++i;
652  }
653 
654  if (i > 0)
655  {
656  int ret;
657 
658  do
659  {
660  ret = _dbus_poll (fds, i, 0);
661  }
662  while (ret < 0 && errno == EINTR);
663 
664  if (ret == 0 && block)
665  {
666  do
667  {
668  ret = _dbus_poll (fds, i, -1);
669  }
670  while (ret < 0 && errno == EINTR);
671  }
672 
673  if (ret > 0)
674  {
675  descriptors_ready = TRUE;
676 
677  while (i > 0)
678  {
679  --i;
680  if (fds[i].fd == sitter->error_pipe_from_child)
681  handle_error_pipe (sitter, fds[i].revents);
682  else if (fds[i].fd == sitter->socket_to_babysitter.fd)
683  handle_babysitter_socket (sitter, fds[i].revents);
684  }
685  }
686  }
687 
688  return descriptors_ready;
689 }
690 
695 #define LIVE_CHILDREN(sitter) ((sitter)->socket_to_babysitter.fd >= 0 || (sitter)->error_pipe_from_child >= 0)
696 
703 void
705 {
706  /* be sure we have the PID of the child */
707  while (LIVE_CHILDREN (sitter) &&
708  sitter->grandchild_pid == -1)
709  babysitter_iteration (sitter, TRUE);
710 
711  _dbus_verbose ("Got child PID %ld for killing\n",
712  (long) sitter->grandchild_pid);
713 
714  if (sitter->grandchild_pid == -1)
715  return; /* child is already dead, or we're so hosed we'll never recover */
716 
717  kill (sitter->grandchild_pid, SIGKILL);
718 }
719 
727 {
728 
729  /* Be sure we're up-to-date */
730  while (LIVE_CHILDREN (sitter) &&
731  babysitter_iteration (sitter, FALSE))
732  ;
733 
734  /* We will have exited the babysitter when the child has exited */
735  return sitter->socket_to_babysitter.fd < 0;
736 }
737 
752  int *status)
753 {
754  if (!_dbus_babysitter_get_child_exited (sitter))
755  _dbus_assert_not_reached ("Child has not exited");
756 
757  if (!sitter->have_child_status ||
758  !(WIFEXITED (sitter->status)))
759  return FALSE;
760 
761  *status = WEXITSTATUS (sitter->status);
762  return TRUE;
763 }
764 
774 void
776  DBusError *error)
777 {
778  if (!_dbus_babysitter_get_child_exited (sitter))
779  return;
780 
781  /* Note that if exec fails, we will also get a child status
782  * from the babysitter saying the child exited,
783  * so we need to give priority to the exec error
784  */
785  if (sitter->have_exec_errnum)
786  {
788  "Failed to execute program %s: %s",
789  sitter->log_name, _dbus_strerror (sitter->errnum));
790  }
791  else if (sitter->have_fork_errnum)
792  {
794  "Failed to fork a new process %s: %s",
795  sitter->log_name, _dbus_strerror (sitter->errnum));
796  }
797  else if (sitter->have_child_status)
798  {
799  if (WIFEXITED (sitter->status))
801  "Process %s exited with status %d",
802  sitter->log_name, WEXITSTATUS (sitter->status));
803  else if (WIFSIGNALED (sitter->status))
805  "Process %s received signal %d",
806  sitter->log_name, WTERMSIG (sitter->status));
807  else
809  "Process %s exited abnormally",
810  sitter->log_name);
811  }
812  else
813  {
815  "Process %s exited, reason unknown",
816  sitter->log_name);
817  }
818 }
819 
834  DBusAddWatchFunction add_function,
835  DBusRemoveWatchFunction remove_function,
836  DBusWatchToggledFunction toggled_function,
837  void *data,
838  DBusFreeFunction free_data_function)
839 {
840  return _dbus_watch_list_set_functions (sitter->watches,
841  add_function,
842  remove_function,
843  toggled_function,
844  data,
845  free_data_function);
846 }
847 
848 static dbus_bool_t
849 handle_watch (DBusWatch *watch,
850  unsigned int condition,
851  void *data)
852 {
853  DBusBabysitter *sitter = _dbus_babysitter_ref (data);
854  int revents;
855  int fd;
856 
857  revents = 0;
858  if (condition & DBUS_WATCH_READABLE)
859  revents |= _DBUS_POLLIN;
860  if (condition & DBUS_WATCH_ERROR)
861  revents |= _DBUS_POLLERR;
862  if (condition & DBUS_WATCH_HANGUP)
863  revents |= _DBUS_POLLHUP;
864 
865  fd = dbus_watch_get_socket (watch);
866 
867  if (fd == sitter->error_pipe_from_child)
868  handle_error_pipe (sitter, revents);
869  else if (fd == sitter->socket_to_babysitter.fd)
870  handle_babysitter_socket (sitter, revents);
871 
872  while (LIVE_CHILDREN (sitter) &&
873  babysitter_iteration (sitter, FALSE))
874  ;
875 
876  /* fd.o #32992: if the handle_* methods closed their sockets, they previously
877  * didn't always remove the watches. Check that we don't regress. */
878  _dbus_assert (sitter->socket_to_babysitter.fd != -1 || sitter->sitter_watch == NULL);
879  _dbus_assert (sitter->error_pipe_from_child != -1 || sitter->error_watch == NULL);
880 
881  if (_dbus_babysitter_get_child_exited (sitter) &&
882  sitter->finished_cb != NULL)
883  {
884  sitter->finished_cb (sitter, sitter->finished_data);
885  sitter->finished_cb = NULL;
886  }
887 
888  _dbus_babysitter_unref (sitter);
889  return TRUE;
890 }
891 
893 #define READ_END 0
894 
895 #define WRITE_END 1
896 
897 
898 /* Avoids a danger in re-entrant situations (calling close()
899  * on a file descriptor twice, and another module has
900  * re-opened it since the first close).
901  *
902  * This previously claimed to be relevant for threaded situations, but by
903  * trivial inspection, it is not thread-safe. It doesn't actually
904  * matter, since this module is only used in the -util variant of the
905  * library, which is only used in single-threaded situations.
906  */
907 static int
908 close_and_invalidate (int *fd)
909 {
910  int ret;
911 
912  if (*fd < 0)
913  return -1;
914  else
915  {
916  ret = _dbus_close (*fd, NULL);
917  *fd = -1;
918  }
919 
920  return ret;
921 }
922 
923 static dbus_bool_t
924 make_pipe (int p[2],
925  DBusError *error)
926 {
927  int retval;
928 
929 #ifdef HAVE_PIPE2
930  dbus_bool_t cloexec_done;
931 
932  retval = pipe2 (p, O_CLOEXEC);
933  cloexec_done = retval >= 0;
934 
935  /* Check if kernel seems to be too old to know pipe2(). We assume
936  that if pipe2 is available, O_CLOEXEC is too. */
937  if (retval < 0 && errno == ENOSYS)
938 #endif
939  {
940  retval = pipe(p);
941  }
942 
943  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
944 
945  if (retval < 0)
946  {
947  dbus_set_error (error,
949  "Failed to create pipe for communicating with child process (%s)",
950  _dbus_strerror (errno));
951  return FALSE;
952  }
953 
954 #ifdef HAVE_PIPE2
955  if (!cloexec_done)
956 #endif
957  {
960  }
961 
962  return TRUE;
963 }
964 
965 static void
966 do_write (int fd, const void *buf, size_t count)
967 {
968  size_t bytes_written;
969  int ret;
970 
971  bytes_written = 0;
972 
973  again:
974 
975  ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written);
976 
977  if (ret < 0)
978  {
979  if (errno == EINTR)
980  goto again;
981  else
982  {
983  _dbus_warn ("Failed to write data to pipe!");
984  exit (1); /* give up, we suck */
985  }
986  }
987  else
988  bytes_written += ret;
989 
990  if (bytes_written < count)
991  goto again;
992 }
993 
994 static void write_err_and_exit (int fd, int msg) _DBUS_GNUC_NORETURN;
995 
996 static void
997 write_err_and_exit (int fd, int msg)
998 {
999  int en = errno;
1000 
1001  do_write (fd, &msg, sizeof (msg));
1002  do_write (fd, &en, sizeof (en));
1003 
1004  exit (1);
1005 }
1006 
1007 static void
1008 write_pid (int fd, pid_t pid)
1009 {
1010  int msg = CHILD_PID;
1011 
1012  do_write (fd, &msg, sizeof (msg));
1013  do_write (fd, &pid, sizeof (pid));
1014 }
1015 
1016 static void write_status_and_exit (int fd, int status) _DBUS_GNUC_NORETURN;
1017 
1018 static void
1019 write_status_and_exit (int fd, int status)
1020 {
1021  int msg = CHILD_EXITED;
1022 
1023  do_write (fd, &msg, sizeof (msg));
1024  do_write (fd, &status, sizeof (status));
1025 
1026  exit (0);
1027 }
1028 
1029 static void do_exec (int child_err_report_fd,
1030  char * const *argv,
1031  char * const *envp,
1032  DBusSpawnChildSetupFunc child_setup,
1033  void *user_data) _DBUS_GNUC_NORETURN;
1034 
1035 static void
1036 do_exec (int child_err_report_fd,
1037  char * const *argv,
1038  char * const *envp,
1039  DBusSpawnChildSetupFunc child_setup,
1040  void *user_data)
1041 {
1042 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1043  int i, max_open;
1044 #endif
1045 
1046  _dbus_verbose_reset ();
1047  _dbus_verbose ("Child process has PID " DBUS_PID_FORMAT "\n",
1048  _dbus_getpid ());
1049 
1050  if (child_setup)
1051  (* child_setup) (user_data);
1052 
1053 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1054  max_open = sysconf (_SC_OPEN_MAX);
1055 
1056  for (i = 3; i < max_open; i++)
1057  {
1058  int retval;
1059 
1060  if (i == child_err_report_fd)
1061  continue;
1062 
1063  retval = fcntl (i, F_GETFD);
1064 
1065  if (retval != -1 && !(retval & FD_CLOEXEC))
1066  {
1067  char description[256] = { 0 };
1068  char proc_self_fd[256] = { 0 };
1069  size_t description_length = sizeof (description) - 1;
1070 
1071  snprintf (proc_self_fd, sizeof (proc_self_fd) - 1,
1072  "/proc/self/fd/%d", i);
1073  proc_self_fd[sizeof (proc_self_fd) - 1] = '\0';
1074 
1075  if (readlink (proc_self_fd, description, description_length) <= 0)
1076  snprintf (description, sizeof (description) - 1, "(unknown)");
1077 
1078  description[sizeof (description) - 1] = '\0';
1079  _dbus_warn ("Fd %d \"%s\" did not have the close-on-exec flag set!",
1080  i, description);
1081  }
1082  }
1083 #endif
1084 
1085  if (envp == NULL)
1086  {
1087  _dbus_assert (environ != NULL);
1088 
1089  envp = environ;
1090  }
1091 
1092  execve (argv[0], argv, envp);
1093 
1094  /* Exec failed */
1095  write_err_and_exit (child_err_report_fd,
1096  CHILD_EXEC_FAILED);
1097 }
1098 
1099 static void
1100 check_babysit_events (pid_t grandchild_pid,
1101  int parent_pipe,
1102  int revents)
1103 {
1104  pid_t ret;
1105  int status;
1106 
1107  do
1108  {
1109  ret = waitpid (grandchild_pid, &status, WNOHANG);
1110  /* The man page says EINTR can't happen with WNOHANG,
1111  * but there are reports of it (maybe only with valgrind?)
1112  */
1113  }
1114  while (ret < 0 && errno == EINTR);
1115 
1116  if (ret == 0)
1117  {
1118  _dbus_verbose ("no child exited\n");
1119 
1120  ; /* no child exited */
1121  }
1122  else if (ret < 0)
1123  {
1124  /* This isn't supposed to happen. */
1125  _dbus_warn ("unexpected waitpid() failure in check_babysit_events(): %s",
1126  _dbus_strerror (errno));
1127  exit (1);
1128  }
1129  else if (ret == grandchild_pid)
1130  {
1131  /* Child exited */
1132  _dbus_verbose ("reaped child pid %ld\n", (long) ret);
1133 
1134  write_status_and_exit (parent_pipe, status);
1135  }
1136  else
1137  {
1138  _dbus_warn ("waitpid() reaped pid %d that we've never heard of",
1139  (int) ret);
1140  exit (1);
1141  }
1142 
1143  if (revents & _DBUS_POLLIN)
1144  {
1145  _dbus_verbose ("babysitter got POLLIN from parent pipe\n");
1146  }
1147 
1148  if (revents & (_DBUS_POLLERR | _DBUS_POLLHUP))
1149  {
1150  /* Parent is gone, so we just exit */
1151  _dbus_verbose ("babysitter got POLLERR or POLLHUP from parent\n");
1152  exit (0);
1153  }
1154 }
1155 
1156 static int babysit_sigchld_pipe = -1;
1157 
1158 static void
1159 babysit_signal_handler (int signo)
1160 {
1161  /* Signal handlers that might set errno must save and restore the errno
1162  * that the interrupted function might have been relying on. */
1163  int saved_errno = errno;
1164  char b = '\0';
1165 
1166  again:
1167  if (write (babysit_sigchld_pipe, &b, 1) <= 0)
1168  if (errno == EINTR)
1169  goto again;
1170 
1171  errno = saved_errno;
1172 }
1173 
1174 static void babysit (pid_t grandchild_pid,
1175  int parent_pipe) _DBUS_GNUC_NORETURN;
1176 
1177 static void
1178 babysit (pid_t grandchild_pid,
1179  int parent_pipe)
1180 {
1181  int sigchld_pipe[2];
1182 
1183  /* We don't exec, so we keep parent state, such as the pid that
1184  * _dbus_verbose() uses. Reset the pid here.
1185  */
1186  _dbus_verbose_reset ();
1187 
1188  /* I thought SIGCHLD would just wake up the poll, but
1189  * that didn't seem to work, so added this pipe.
1190  * Probably the pipe is more likely to work on busted
1191  * operating systems anyhow.
1192  */
1193  if (pipe (sigchld_pipe) < 0)
1194  {
1195  _dbus_warn ("Not enough file descriptors to create pipe in babysitter process");
1196  exit (1);
1197  }
1198 
1199  babysit_sigchld_pipe = sigchld_pipe[WRITE_END];
1200 
1201  _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler);
1202 
1203  write_pid (parent_pipe, grandchild_pid);
1204 
1205  check_babysit_events (grandchild_pid, parent_pipe, 0);
1206 
1207  while (TRUE)
1208  {
1209  DBusPollFD pfds[2];
1210 
1211  pfds[0].fd = parent_pipe;
1212  pfds[0].events = _DBUS_POLLIN;
1213  pfds[0].revents = 0;
1214 
1215  pfds[1].fd = sigchld_pipe[READ_END];
1216  pfds[1].events = _DBUS_POLLIN;
1217  pfds[1].revents = 0;
1218 
1219  if (_dbus_poll (pfds, _DBUS_N_ELEMENTS (pfds), -1) < 0 && errno != EINTR)
1220  {
1221  _dbus_warn ("_dbus_poll() error: %s", strerror (errno));
1222  exit (1);
1223  }
1224 
1225  if (pfds[0].revents != 0)
1226  {
1227  check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents);
1228  }
1229  else if (pfds[1].revents & _DBUS_POLLIN)
1230  {
1231  char b;
1232  if (read (sigchld_pipe[READ_END], &b, 1) == -1)
1233  {
1234  /* ignore */
1235  }
1236  /* do waitpid check */
1237  check_babysit_events (grandchild_pid, parent_pipe, 0);
1238  }
1239  }
1240 
1241  exit (1);
1242 }
1243 
1270  const char *log_name,
1271  char * const *argv,
1272  char **env,
1273  DBusSpawnFlags flags,
1274  DBusSpawnChildSetupFunc child_setup,
1275  void *user_data,
1276  DBusError *error)
1277 {
1278  DBusBabysitter *sitter;
1279  int child_err_report_pipe[2] = { -1, -1 };
1280  DBusSocket babysitter_pipe[2] = { DBUS_SOCKET_INIT, DBUS_SOCKET_INIT };
1281  pid_t pid;
1282  int fd_out = -1;
1283  int fd_err = -1;
1284 
1285  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1286  _dbus_assert (argv[0] != NULL);
1287 
1288  if (sitter_p != NULL)
1289  *sitter_p = NULL;
1290 
1291  sitter = NULL;
1292 
1293  sitter = _dbus_babysitter_new ();
1294  if (sitter == NULL)
1295  {
1297  return FALSE;
1298  }
1299 
1300  sitter->log_name = _dbus_strdup (log_name);
1301  if (sitter->log_name == NULL && log_name != NULL)
1302  {
1304  goto cleanup_and_fail;
1305  }
1306 
1307  if (sitter->log_name == NULL)
1308  sitter->log_name = _dbus_strdup (argv[0]);
1309 
1310  if (sitter->log_name == NULL)
1311  {
1313  goto cleanup_and_fail;
1314  }
1315 
1316  if (!make_pipe (child_err_report_pipe, error))
1317  goto cleanup_and_fail;
1318 
1319  if (!_dbus_socketpair (&babysitter_pipe[0], &babysitter_pipe[1], TRUE, error))
1320  goto cleanup_and_fail;
1321 
1322  /* Setting up the babysitter is only useful in the parent,
1323  * but we don't want to run out of memory and fail
1324  * after we've already forked, since then we'd leak
1325  * child processes everywhere.
1326  */
1327  sitter->error_watch = _dbus_watch_new (child_err_report_pipe[READ_END],
1329  TRUE, handle_watch, sitter, NULL);
1330  if (sitter->error_watch == NULL)
1331  {
1333  goto cleanup_and_fail;
1334  }
1335 
1336  if (!_dbus_watch_list_add_watch (sitter->watches, sitter->error_watch))
1337  {
1338  /* we need to free it early so the destructor won't try to remove it
1339  * without it having been added, which DBusLoop doesn't allow */
1341  _dbus_watch_unref (sitter->error_watch);
1342  sitter->error_watch = NULL;
1343 
1345  goto cleanup_and_fail;
1346  }
1347 
1348  sitter->sitter_watch = _dbus_watch_new (babysitter_pipe[0].fd,
1350  TRUE, handle_watch, sitter, NULL);
1351  if (sitter->sitter_watch == NULL)
1352  {
1354  goto cleanup_and_fail;
1355  }
1356 
1357  if (!_dbus_watch_list_add_watch (sitter->watches, sitter->sitter_watch))
1358  {
1359  /* we need to free it early so the destructor won't try to remove it
1360  * without it having been added, which DBusLoop doesn't allow */
1362  _dbus_watch_unref (sitter->sitter_watch);
1363  sitter->sitter_watch = NULL;
1364 
1366  goto cleanup_and_fail;
1367  }
1368 
1369  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1370 
1371  if (flags & DBUS_SPAWN_SILENCE_OUTPUT)
1372  {
1373  fd_out = open ("/dev/null", O_RDONLY);
1374 
1375  if (fd_out < 0)
1376  {
1377  dbus_set_error (error, _dbus_error_from_errno (errno),
1378  "Failed to open /dev/null: %s",
1379  _dbus_strerror (errno));
1380  goto cleanup_and_fail;
1381  }
1382 
1383  _dbus_fd_set_close_on_exec (fd_out);
1384 
1385  fd_err = _dbus_dup (fd_out, error);
1386 
1387  if (fd_err < 0)
1388  goto cleanup_and_fail;
1389  }
1390 #ifdef HAVE_SYSTEMD
1391  else if (flags & DBUS_SPAWN_REDIRECT_OUTPUT)
1392  {
1393  /* This may fail, but it's not critical.
1394  * In particular, if we were compiled with journald support but are now
1395  * running on a non-systemd system, this is going to fail, so we
1396  * have to cope gracefully. */
1397  fd_out = sd_journal_stream_fd (sitter->log_name, LOG_INFO, FALSE);
1398  fd_err = sd_journal_stream_fd (sitter->log_name, LOG_WARNING, FALSE);
1399  }
1400 #endif
1401 
1402  /* Make sure our output buffers aren't redundantly printed by both the
1403  * parent and the child */
1404  fflush (stdout);
1405  fflush (stderr);
1406 
1407  pid = fork ();
1408 
1409  if (pid < 0)
1410  {
1411  dbus_set_error (error,
1413  "Failed to fork (%s)",
1414  _dbus_strerror (errno));
1415  goto cleanup_and_fail;
1416  }
1417  else if (pid == 0)
1418  {
1419  /* Immediate child, this is the babysitter process. */
1420  int grandchild_pid;
1421 
1422  /* Be sure we crash if the parent exits
1423  * and we write to the err_report_pipe
1424  */
1425  signal (SIGPIPE, SIG_DFL);
1426 
1427  /* Close the parent's end of the pipes. */
1428  close_and_invalidate (&child_err_report_pipe[READ_END]);
1429  close_and_invalidate (&babysitter_pipe[0].fd);
1430 
1431  fflush (stdout);
1432  fflush (stderr);
1433 
1434  /* Create the child that will exec () */
1435  grandchild_pid = fork ();
1436 
1437  if (grandchild_pid < 0)
1438  {
1439  write_err_and_exit (babysitter_pipe[1].fd,
1440  CHILD_FORK_FAILED);
1441  _dbus_assert_not_reached ("Got to code after write_err_and_exit()");
1442  }
1443  else if (grandchild_pid == 0)
1444  {
1445 #ifdef __linux__
1446  int fd = -1;
1447 
1448 #ifdef O_CLOEXEC
1449  fd = open ("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
1450 #endif
1451 
1452  if (fd < 0)
1453  {
1454  fd = open ("/proc/self/oom_score_adj", O_WRONLY);
1456  }
1457 
1458  if (fd >= 0)
1459  {
1460  if (write (fd, "0", sizeof (char)) < 0)
1461  _dbus_warn ("writing oom_score_adj error: %s", strerror (errno));
1462  _dbus_close (fd, NULL);
1463  }
1464 #endif
1465  /* Go back to ignoring SIGPIPE, since it's evil
1466  */
1467  signal (SIGPIPE, SIG_IGN);
1468 
1469  close_and_invalidate (&babysitter_pipe[1].fd);
1470 
1471  /* Redirect stdout, stderr to systemd Journal or /dev/null
1472  * as requested, if possible */
1473  if (fd_out >= 0)
1474  dup2 (fd_out, STDOUT_FILENO);
1475  if (fd_err >= 0)
1476  dup2 (fd_err, STDERR_FILENO);
1477  close_and_invalidate (&fd_out);
1478  close_and_invalidate (&fd_err);
1479 
1480  do_exec (child_err_report_pipe[WRITE_END],
1481  argv,
1482  env,
1483  child_setup, user_data);
1484  _dbus_assert_not_reached ("Got to code after exec() - should have exited on error");
1485  }
1486  else
1487  {
1488  close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1489  close_and_invalidate (&fd_out);
1490  close_and_invalidate (&fd_err);
1491  babysit (grandchild_pid, babysitter_pipe[1].fd);
1492  _dbus_assert_not_reached ("Got to code after babysit()");
1493  }
1494  }
1495  else
1496  {
1497  /* Close the uncared-about ends of the pipes */
1498  close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1499  close_and_invalidate (&babysitter_pipe[1].fd);
1500  close_and_invalidate (&fd_out);
1501  close_and_invalidate (&fd_err);
1502 
1503  sitter->socket_to_babysitter = babysitter_pipe[0];
1504  babysitter_pipe[0].fd = -1;
1505 
1506  sitter->error_pipe_from_child = child_err_report_pipe[READ_END];
1507  child_err_report_pipe[READ_END] = -1;
1508 
1509  sitter->sitter_pid = pid;
1510 
1511  if (sitter_p != NULL)
1512  *sitter_p = sitter;
1513  else
1514  _dbus_babysitter_unref (sitter);
1515 
1516  dbus_free_string_array (env);
1517 
1518  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1519 
1520  return TRUE;
1521  }
1522 
1523  cleanup_and_fail:
1524 
1525  _DBUS_ASSERT_ERROR_IS_SET (error);
1526 
1527  close_and_invalidate (&child_err_report_pipe[READ_END]);
1528  close_and_invalidate (&child_err_report_pipe[WRITE_END]);
1529  close_and_invalidate (&babysitter_pipe[0].fd);
1530  close_and_invalidate (&babysitter_pipe[1].fd);
1531  close_and_invalidate (&fd_out);
1532  close_and_invalidate (&fd_err);
1533 
1534  if (sitter != NULL)
1535  _dbus_babysitter_unref (sitter);
1536 
1537  return FALSE;
1538 }
1539 
1540 void
1541 _dbus_babysitter_set_result_function (DBusBabysitter *sitter,
1542  DBusBabysitterFinishedFunc finished,
1543  void *user_data)
1544 {
1545  sitter->finished_cb = finished;
1546  sitter->finished_data = user_data;
1547 }
1548 
1551 void
1552 _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter)
1553 {
1554  while (LIVE_CHILDREN (sitter))
1555  babysitter_iteration (sitter, TRUE);
1556 }
const char * message
public error message field
Definition: dbus-errors.h:51
#define DBUS_ERROR_SPAWN_FAILED
While starting a new process, something went wrong.
DBusWatch * _dbus_watch_new(DBusPollable fd, unsigned int flags, dbus_bool_t enabled, DBusWatchHandler handler, void *data, DBusFreeFunction free_data_function)
Creates a new DBusWatch.
Definition: dbus-watch.c:88
Implementation of DBusWatch.
Definition: dbus-watch.c:40
#define NULL
A null pointer, defined appropriately for C or C++.
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
void(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
Definition: dbus-memory.h:63
#define LIVE_CHILDREN(sitter)
Macro returns TRUE if the babysitter still has live sockets open to the babysitter child or the grand...
#define _DBUS_POLLHUP
Hung up.
Definition: dbus-sysdeps.h:430
unsigned int have_exec_errnum
True if we have an error code from exec()
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:703
DBusWatch * error_watch
Error pipe watch.
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:146
void(* DBusWatchToggledFunction)(DBusWatch *watch, void *data)
Called when dbus_watch_get_enabled() may return a different value than it did before.
#define DBUS_ERROR_SPAWN_CHILD_EXITED
While starting a new process, the child exited with a status code.
int status
Exit status code.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
void _dbus_watch_list_free(DBusWatchList *watch_list)
Frees a DBusWatchList.
Definition: dbus-watch.c:249
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:422
Read succeeded.
DBusWatchList * _dbus_watch_list_new(void)
Creates a new watch list.
Definition: dbus-watch.c:232
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
short events
Events to poll for.
Definition: dbus-sysdeps.h:417
dbus_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a socket.
dbus_bool_t _dbus_babysitter_get_child_exited(DBusBabysitter *sitter)
Checks whether the child has exited, without blocking.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:599
dbus_bool_t _dbus_watch_list_set_functions(DBusWatchList *watch_list, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, DBusWatchToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function)
Sets the watch functions.
Definition: dbus-watch.c:295
void _dbus_set_signal_handler(int sig, DBusSignalHandler handler)
Installs a UNIX signal handler.
Socket interface.
Definition: dbus-sysdeps.h:178
DBusWatchList * watches
Watches.
#define DBUS_ERROR_SPAWN_CHILD_SIGNALED
While starting a new process, the child exited on a signal.
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:58
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
DBusWatch * sitter_watch
Sitter pipe watch.
DBUS_EXPORT int dbus_watch_get_socket(DBusWatch *watch)
Returns a socket to be watched, on UNIX this will return -1 if our transport is not socket-based so d...
Definition: dbus-watch.c:593
dbus_bool_t _dbus_babysitter_get_child_exit_status(DBusBabysitter *sitter, int *status)
Gets the exit status of the child.
void _dbus_babysitter_kill_child(DBusBabysitter *sitter)
Blocks until the babysitter process gives us the PID of the spawned grandchild, then kills the spawne...
Babysitter implementation details.
ReadStatus
Enumeration for status of a read()
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
pid_t sitter_pid
PID Of the babysitter.
dbus_bool_t _dbus_spawn_async_with_babysitter(DBusBabysitter **sitter_p, const char *log_name, char *const *argv, char **env, DBusSpawnFlags flags, DBusSpawnChildSetupFunc child_setup, void *user_data, DBusError *error)
Spawns a new process.
EOF returned.
void _dbus_watch_invalidate(DBusWatch *watch)
Clears the file descriptor from a now-invalid watch object so that no one tries to use it...
Definition: dbus-watch.c:169
dbus_bool_t _dbus_babysitter_set_watch_functions(DBusBabysitter *sitter, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, DBusWatchToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function)
Sets watch functions to notify us when the babysitter object needs to read/write file descriptors...
Object representing an exception.
Definition: dbus-errors.h:48
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
pid_t grandchild_pid
PID of the grandchild.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
int refcount
Reference count.
unsigned int have_child_status
True if child status has been reaped.
As in POLLERR (can&#39;t watch for this, but can be present in current state passed to dbus_watch_handle(...
#define TRUE
Expands to "1".
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:416
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
As in POLLHUP (can&#39;t watch for it, but can be present in current state passed to dbus_watch_handle())...
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
dbus_bool_t _dbus_watch_list_add_watch(DBusWatchList *watch_list, DBusWatch *watch)
Adds a new watch to the watch list, invoking the application DBusAddWatchFunction if appropriate...
Definition: dbus-watch.c:381
dbus_bool_t(* DBusAddWatchFunction)(DBusWatch *watch, void *data)
Called when libdbus needs a new watch to be monitored by the main loop.
#define READ_END
Helps remember which end of the pipe is which.
void(* DBusRemoveWatchFunction)(DBusWatch *watch, void *data)
Called when libdbus no longer needs a watch to be monitored by the main loop.
DBusWatchList implementation details.
Definition: dbus-watch.c:214
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
void _dbus_watch_list_remove_watch(DBusWatchList *watch_list, DBusWatch *watch)
Removes a watch from the watch list, invoking the application&#39;s DBusRemoveWatchFunction if appropriat...
Definition: dbus-watch.c:414
void _dbus_babysitter_unref(DBusBabysitter *sitter)
Decrement the reference count on the babysitter object.
#define DBUS_ERROR_SPAWN_FORK_FAILED
While starting a new process, the fork() call failed.
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:751
char * log_name
the name under which to log messages about this process being spawned
void _dbus_watch_unref(DBusWatch *watch)
Decrements the reference count of a DBusWatch object and finalizes the object if the count reaches ze...
Definition: dbus-watch.c:138
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
unsigned int have_fork_errnum
True if we have an error code from fork()
#define FALSE
Expands to "0".
int error_pipe_from_child
Connection to the process that does the exec()
As in POLLIN.
DBusSocket socket_to_babysitter
Connection to the babysitter process.
#define WRITE_END
Helps remember which end of the pipe is which.
char * _dbus_strdup(const char *str)
Duplicates a string.
int errnum
Error number.
void _dbus_babysitter_set_child_exit_error(DBusBabysitter *sitter, DBusError *error)
Sets the DBusError with an explanation of why the spawned child process exited (on a signal...
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
short revents
Events that occurred.
Definition: dbus-sysdeps.h:418
Some kind of error.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:428
DBusBabysitter * _dbus_babysitter_ref(DBusBabysitter *sitter)
Increment the reference count on the babysitter object.