1d012387afef0ba02185ebe27bc6bb15551912e92Havoc Pennington/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington/* dbus-launch.c  dbus-launch utility
3c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington *
410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * Copyright (C) 2003, 2006 Red Hat, Inc.
510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * Copyright (C) 2006 Thiago Macieira <thiago@kde.org>
6c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington *
743605a6f4e78a8c28afb4b1e924dff0301e0e95cHavoc Pennington * Licensed under the Academic Free License version 2.1
8c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington *
9c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * This program is free software; you can redistribute it and/or modify
10c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * it under the terms of the GNU General Public License as published by
11c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * the Free Software Foundation; either version 2 of the License, or
12c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * (at your option) any later version.
13c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington *
14c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * This program is distributed in the hope that it will be useful,
15c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of
16c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * GNU General Public License for more details.
18c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington *
19c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * You should have received a copy of the GNU General Public License
20c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington * along with this program; if not, write to the Free Software
21dc33f4f7749ed303374ebdf00e48ea8a471afd25Tobias Mueller * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington *
23c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington */
24dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann
25dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann#include <config.h>
26f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include "dbus-launch.h"
27c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#include <stdlib.h>
28ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons#include <ctype.h>
29c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#include <unistd.h>
30c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#include <fcntl.h>
31c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#include <signal.h>
32c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#include <sys/wait.h>
33c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#include <errno.h>
34c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#include <stdio.h>
35c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#include <string.h>
36df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#include <signal.h>
37df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#include <stdarg.h>
389f92ac0ef5ae8ab5a325b15d0b3109143fe51f8cColin Walters#include <sys/select.h>
39f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <time.h>
40f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
41c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#ifdef DBUS_BUILD_X11
42c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#include <X11/Xlib.h>
43f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiraextern Display *xdisplay;
44c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington#endif
45c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington
4610fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonstatic char* machine_uuid = NULL;
4710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
4810fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonconst char*
4910fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonget_machine_uuid (void)
5010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington{
5110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington  return machine_uuid;
5210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington}
5310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
5410fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonstatic void
5510fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonsave_machine_uuid (const char *uuid_arg)
5610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington{
5710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington  if (strlen (uuid_arg) != 32)
5810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington    {
5910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      fprintf (stderr, "machine ID '%s' looks like it's the wrong length, should be 32 hex digits",
6010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington               uuid_arg);
6110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      exit (1);
6210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington    }
6310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
6410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington  machine_uuid = xstrdup (uuid_arg);
6510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington}
6610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
67ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons#define UUID_MAXLEN 40
68ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons/* Read the machine uuid from file if needed. Returns TRUE if machine_uuid is
69ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons * set after this function */
70ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simonsstatic int
71ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simonsread_machine_uuid_if_needed (void)
72ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons{
73ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  FILE *f;
74ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  char uuid[UUID_MAXLEN];
75ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  size_t len;
76ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  int ret = FALSE;
77ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
78ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  if (machine_uuid != NULL)
79ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    return TRUE;
80ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
81ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  f = fopen (DBUS_MACHINE_UUID_FILE, "r");
82ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  if (f == NULL)
83ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    return FALSE;
84ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
85ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  if (fgets (uuid, UUID_MAXLEN, f) == NULL)
86ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    goto out;
87ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
88ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  len = strlen (uuid);
89ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  if (len < 32)
90ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    goto out;
91ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
92ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  /* rstrip the read uuid */
93ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  while (len > 31 && isspace(uuid[len - 1]))
94ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    len--;
95ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
96ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  if (len != 32)
97ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    goto out;
98ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
99ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  uuid[len] = '\0';
100ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  machine_uuid = xstrdup (uuid);
101ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  verbose ("UID: %s\n", machine_uuid);
102ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  ret = TRUE;
103ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
104ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simonsout:
105ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  fclose(f);
106ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  return ret;
107ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons}
108ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
109ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
110f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiravoid
111df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonverbose (const char *format,
112df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington         ...)
113df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
114df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  va_list args;
115df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  static int verbose = TRUE;
116df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  static int verbose_initted = FALSE;
117df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
118df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  /* things are written a bit oddly here so that
119df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington   * in the non-verbose case we just have the one
120df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington   * conditional and return immediately.
121df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington   */
122df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (!verbose)
123df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    return;
124df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
125df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (!verbose_initted)
126df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
127df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose = getenv ("DBUS_VERBOSE") != NULL;
128df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose_initted = TRUE;
129df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (!verbose)
130df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        return;
131df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
132df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
133df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  fprintf (stderr, "%lu: ", (unsigned long) getpid ());
134df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
135df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  va_start (args, format);
136df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  vfprintf (stderr, format, args);
137df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  va_end (args);
138df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
139df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
140c0158234d046381a6bc8c004c82577576977d0d7Havoc Penningtonstatic void
141fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Waltersusage (int ecode)
142c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington{
143fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  fprintf (stderr, "dbus-launch [--version] [--help] [--sh-syntax] [--csh-syntax] [--auto-syntax] [--exit-with-session]\n");
144fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  exit (ecode);
145c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington}
146c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington
147c0158234d046381a6bc8c004c82577576977d0d7Havoc Penningtonstatic void
148c0158234d046381a6bc8c004c82577576977d0d7Havoc Penningtonversion (void)
149c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington{
1507652304bff969afb3969603149bb385efe861fe8John (J  printf ("D-Bus Message Bus Launcher %s\n"
151c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington          "Copyright (C) 2003 Red Hat, Inc.\n"
152c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington          "This is free software; see the source for copying conditions.\n"
153c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington          "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
154c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington          VERSION);
155c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington  exit (0);
156c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington}
157c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington
158f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirachar *
159fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Waltersxstrdup (const char *str)
160fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters{
161fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  int len;
162fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  char *copy;
163fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters
164fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  if (str == NULL)
165fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters    return NULL;
166fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters
167fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  len = strlen (str);
168fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters
169fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  copy = malloc (len + 1);
170fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  if (copy == NULL)
171fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters    return NULL;
172fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters
173fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  memcpy (copy, str, len + 1);
174fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters
175fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  return copy;
176fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters}
177fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters
178df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtontypedef enum
179df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
180df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  READ_STATUS_OK,    /**< Read succeeded */
181df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  READ_STATUS_ERROR, /**< Some kind of error */
182df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  READ_STATUS_EOF    /**< EOF returned */
183df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington} ReadStatus;
184df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
185df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic ReadStatus
186df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonread_line (int        fd,
187df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington           char      *buf,
188df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington           size_t     maxlen)
189df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
190df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  size_t bytes = 0;
191df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  ReadStatus retval;
192df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
193df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  memset (buf, '\0', maxlen);
194df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  maxlen -= 1; /* ensure nul term */
195df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
196df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  retval = READ_STATUS_OK;
197df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
198df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  while (TRUE)
199df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
2000ca96ec548a6e4a1e39429f3c0480adfe7e2eab8John (J      ssize_t chunk;
201df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      size_t to_read;
202df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
203df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    again:
204df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      to_read = maxlen - bytes;
205df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
206df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (to_read == 0)
207df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        break;
208df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
209df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      chunk = read (fd,
210df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                    buf + bytes,
211df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                    to_read);
212df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (chunk < 0 && errno == EINTR)
213df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        goto again;
214df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
215df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (chunk < 0)
216df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
217df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          retval = READ_STATUS_ERROR;
218df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          break;
219df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
220df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      else if (chunk == 0)
221df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
222df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          retval = READ_STATUS_EOF;
223df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          break; /* EOF */
224df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
225df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      else /* chunk > 0 */
226df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington	bytes += chunk;
227df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
228df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
229df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (retval == READ_STATUS_EOF &&
230df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      bytes > 0)
231df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    retval = READ_STATUS_OK;
232df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
233df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  /* whack newline */
234df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (retval != READ_STATUS_ERROR &&
235df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      bytes > 0 &&
236df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      buf[bytes-1] == '\n')
237df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    buf[bytes-1] = '\0';
238df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
239df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  return retval;
240df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
241df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
242df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic ReadStatus
243df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonread_pid (int        fd,
244df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          pid_t     *buf)
245df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
246df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  size_t bytes = 0;
247df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  ReadStatus retval;
248df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
249df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  retval = READ_STATUS_OK;
250df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
251df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  while (TRUE)
252df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
2530ca96ec548a6e4a1e39429f3c0480adfe7e2eab8John (J      ssize_t chunk;
254df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      size_t to_read;
255df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
256df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    again:
257df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      to_read = sizeof (pid_t) - bytes;
258df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
259df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (to_read == 0)
260df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        break;
261df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
262df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      chunk = read (fd,
263df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                    ((char*)buf) + bytes,
264df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                    to_read);
265df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (chunk < 0 && errno == EINTR)
266df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        goto again;
267df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
268df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (chunk < 0)
269df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
270df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          retval = READ_STATUS_ERROR;
271df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          break;
272df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
273df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      else if (chunk == 0)
274df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
275df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          retval = READ_STATUS_EOF;
276df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          break; /* EOF */
277df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
278df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      else /* chunk > 0 */
279df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington	bytes += chunk;
280df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
281df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
282df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  return retval;
283df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
284df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
285df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic void
286df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtondo_write (int fd, const void *buf, size_t count)
287df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
288df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  size_t bytes_written;
289df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int ret;
290df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
291df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  bytes_written = 0;
292df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
293df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington again:
294df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
295df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written);
296df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
297df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (ret < 0)
298df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
299df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (errno == EINTR)
300df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        goto again;
301df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      else
302df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
303d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington          fprintf (stderr, "Failed to write data to pipe! %s\n",
304d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington                   strerror (errno));
305df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          exit (1); /* give up, we suck */
306df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
307df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
308df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  else
309df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    bytes_written += ret;
310df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
311df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (bytes_written < count)
312df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    goto again;
313df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
314df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
315df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic void
316df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonwrite_pid (int   fd,
317df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington           pid_t pid)
318df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
319df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  do_write (fd, &pid, sizeof (pid));
320df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
321df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
322df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic int
323df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtondo_waitpid (pid_t pid)
324df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
325df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int ret;
326df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
327df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington again:
328df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  ret = waitpid (pid, NULL, 0);
329df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
330df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (ret < 0 &&
331df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      errno == EINTR)
332df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    goto again;
333df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
334df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  return ret;
335df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
336df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
337df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic pid_t bus_pid_to_kill = -1;
338df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
339ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simonsstatic void
340eb3b99e7c610988823804f5e6c92aa13459605c7Kjartan Maraaskill_bus(void)
341ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons{
342ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  verbose ("Killing message bus and exiting babysitter\n");
343ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  kill (bus_pid_to_kill, SIGTERM);
344ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  sleep (3);
345ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  kill (bus_pid_to_kill, SIGKILL);
346ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons}
347ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
348f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiravoid
349f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirakill_bus_and_exit (int exitcode)
350df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
351df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  /* in case these point to any NFS mounts, get rid of them immediately */
352df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  close (0);
353df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  close (1);
354df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  close (2);
355df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
356ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  kill_bus();
357df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
358f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  exit (exitcode);
359df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
360df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
361f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic void
362f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiraprint_variables (const char *bus_address, pid_t bus_pid, long bus_wid,
363f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira		 int c_shell_syntax, int bourne_shell_syntax,
364f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira		 int binary_syntax)
365df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
366f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  if (binary_syntax)
367f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira    {
368ade5c7ad33484a8b8f7c11591d4e80a83e7ff369Havoc Pennington      do_write (1, bus_address, strlen (bus_address) + 1);
369ade5c7ad33484a8b8f7c11591d4e80a83e7ff369Havoc Pennington      do_write (1, &bus_pid, sizeof bus_pid);
370ade5c7ad33484a8b8f7c11591d4e80a83e7ff369Havoc Pennington      do_write (1, &bus_wid, sizeof bus_wid);
371f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      return;
372f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira    }
373f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  else if (c_shell_syntax)
374f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira    {
375f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      printf ("setenv DBUS_SESSION_BUS_ADDRESS '%s';\n", bus_address);
376f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      printf ("set DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
377f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      if (bus_wid)
3787d9d3fc031244bee29b5ac25e07f3e8e5b5dd97bJohn (J        printf ("set DBUS_SESSION_BUS_WINDOWID=%ld;\n", (long) bus_wid);
37910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      fflush (stdout);
380f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira    }
38110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington  else if (bourne_shell_syntax)
382f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira    {
383f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      printf ("DBUS_SESSION_BUS_ADDRESS='%s';\n", bus_address);
3847d9d3fc031244bee29b5ac25e07f3e8e5b5dd97bJohn (J      printf ("export DBUS_SESSION_BUS_ADDRESS;\n");
385f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      printf ("DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
386f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      if (bus_wid)
3877d9d3fc031244bee29b5ac25e07f3e8e5b5dd97bJohn (J        printf ("DBUS_SESSION_BUS_WINDOWID=%ld;\n", (long) bus_wid);
38810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      fflush (stdout);
38910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington    }
39010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington  else
39110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington    {
39210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      printf ("DBUS_SESSION_BUS_ADDRESS=%s\n", bus_address);
39310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      printf ("DBUS_SESSION_BUS_PID=%ld\n", (long) bus_pid);
39410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      if (bus_wid)
39510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington	printf ("DBUS_SESSION_BUS_WINDOWID=%ld\n", (long) bus_wid);
39610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      fflush (stdout);
397f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira    }
398df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
399df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
400df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic int got_sighup = FALSE;
401df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
402df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic void
403df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonsignal_handler (int sig)
404df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
405df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  switch (sig)
406df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
407100027007254aaec3ba0388bd0f42e29e512a678Tor Lillqvist#ifdef SIGHUP
408df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    case SIGHUP:
409100027007254aaec3ba0388bd0f42e29e512a678Tor Lillqvist#endif
4109b2c196ef36260ef455f0746f003aec6ffe6ff4cSascha Silbe    case SIGINT:
411ee6964d6a0e4fe82f838d8d352d3c57aea773047John (J    case SIGTERM:
412df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      got_sighup = TRUE;
413df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      break;
414df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
415df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
416df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
417df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic void
418df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonkill_bus_when_session_ends (void)
419df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
420df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int tty_fd;
421df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int x_fd;
422df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  fd_set read_set;
423df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  fd_set err_set;
424df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  struct sigaction act;
425df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  sigset_t empty_mask;
426df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
427df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  /* install SIGHUP handler */
428df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  got_sighup = FALSE;
429df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  sigemptyset (&empty_mask);
430df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  act.sa_handler = signal_handler;
431df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  act.sa_mask    = empty_mask;
432df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  act.sa_flags   = 0;
4330ca96ec548a6e4a1e39429f3c0480adfe7e2eab8John (J  sigaction (SIGHUP,  &act, NULL);
434ee6964d6a0e4fe82f838d8d352d3c57aea773047John (J  sigaction (SIGTERM,  &act, NULL);
4359b2c196ef36260ef455f0746f003aec6ffe6ff4cSascha Silbe  sigaction (SIGINT,  &act, NULL);
436df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
437df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#ifdef DBUS_BUILD_X11
438f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  x11_init();
439df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (xdisplay != NULL)
440df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
441df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      x_fd = ConnectionNumber (xdisplay);
442df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
443df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  else
444df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    x_fd = -1;
445df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#else
446df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  x_fd = -1;
447df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#endif
448df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
449df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (isatty (0))
450df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    tty_fd = 0;
451df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  else
452df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    tty_fd = -1;
453df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
454df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (tty_fd >= 0)
455df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    verbose ("stdin isatty(), monitoring it\n");
456df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  else
457df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    verbose ("stdin was not a TTY, not monitoring it\n");
458df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
459df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (tty_fd < 0 && x_fd < 0)
460df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
461df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      fprintf (stderr, "No terminal on standard input and no X display; cannot attach message bus to session lifetime\n");
462df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      exit (1);
463df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
464df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
465df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  while (TRUE)
466df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
4670bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters#ifdef DBUS_BUILD_X11
4680bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters      /* Dump events on the floor, and let
4690bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters       * IO error handler run if we lose
4700bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters       * the X connection. It's important to
4710bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters       * run this before going into select() since
4720bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters       * we might have queued outgoing messages or
4730bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters       * events.
4740bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters       */
4750bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters      x11_handle_event ();
4760bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters#endif
4770bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters
478df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      FD_ZERO (&read_set);
479df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      FD_ZERO (&err_set);
480df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
481df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (tty_fd >= 0)
482df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
483df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          FD_SET (tty_fd, &read_set);
484df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          FD_SET (tty_fd, &err_set);
485df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
486df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
487df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (x_fd >= 0)
488df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
489df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          FD_SET (x_fd, &read_set);
490df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          FD_SET (x_fd, &err_set);
491df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
4920bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters
4930ca96ec548a6e4a1e39429f3c0480adfe7e2eab8John (J      select (MAX (tty_fd, x_fd) + 1,
4940ca96ec548a6e4a1e39429f3c0480adfe7e2eab8John (J              &read_set, NULL, &err_set, NULL);
495df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
496df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (got_sighup)
497df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
498df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          verbose ("Got SIGHUP, exiting\n");
499f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira          kill_bus_and_exit (0);
500df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
501df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
502df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#ifdef DBUS_BUILD_X11
5030bfc5e8d23a5ae56eee5ef2073911cddcbd0c4b0Colin Walters      /* Events will be processed before we select again
504df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington       */
505df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (x_fd >= 0)
506df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        verbose ("X fd condition reading = %d error = %d\n",
507df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                 FD_ISSET (x_fd, &read_set),
508df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                 FD_ISSET (x_fd, &err_set));
509df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#endif
510df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
511df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (tty_fd >= 0)
512df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
513df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          if (FD_ISSET (tty_fd, &read_set))
514df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington            {
515df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              int bytes_read;
516df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              char discard[512];
517df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
518df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              verbose ("TTY ready for reading\n");
519df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
520df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              bytes_read = read (tty_fd, discard, sizeof (discard));
521df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
522df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              verbose ("Read %d bytes from TTY errno = %d\n",
523df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                       bytes_read, errno);
524df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
525df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              if (bytes_read == 0)
526f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira                kill_bus_and_exit (0); /* EOF */
527df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              else if (bytes_read < 0 && errno != EINTR)
528df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                {
529df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                  /* This shouldn't happen I don't think; to avoid
530df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                   * spinning on the fd forever we exit.
531df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                   */
532df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                  fprintf (stderr, "dbus-launch: error reading from stdin: %s\n",
533df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                           strerror (errno));
534f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira                  kill_bus_and_exit (0);
535df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                }
536df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington            }
537df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          else if (FD_ISSET (tty_fd, &err_set))
538df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington            {
539df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              verbose ("TTY has error condition\n");
540df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
541f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira              kill_bus_and_exit (0);
542df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington            }
543df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
544df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
545df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
546df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
547df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonstatic void
548df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Penningtonbabysit (int   exit_with_session,
549df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington         pid_t child_pid,
550f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira         int   read_bus_pid_fd)  /* read pid from here */
551df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington{
552df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int ret;
5532ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington  int dev_null_fd;
554d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington  const char *s;
555d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington
556f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  verbose ("babysitting, exit_with_session = %d, child_pid = %ld, read_bus_pid_fd = %d\n",
557f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira           exit_with_session, (long) child_pid, read_bus_pid_fd);
558df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
559df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  /* We chdir ("/") since we are persistent and daemon-like, and fork
560df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington   * again so dbus-launch can reap the parent.  However, we don't
5612ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington   * setsid() or close fd 0 because the idea is to remain attached
562df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington   * to the tty and the X server in order to kill the message bus
563df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington   * when the session ends.
564df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington   */
565df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
566df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (chdir ("/") < 0)
567df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
568df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      fprintf (stderr, "Could not change to root directory: %s\n",
569df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington               strerror (errno));
570df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      exit (1);
5712ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington    }
572df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
573d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington  /* Close stdout/stderr so we don't block an "eval" or otherwise
574d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington   * lock up. stdout is still chaining through to dbus-launch
575d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington   * and in turn to the parent shell.
5762ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington   */
5772ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington  dev_null_fd = open ("/dev/null", O_RDWR);
5782ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington  if (dev_null_fd >= 0)
5792ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington    {
580d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington      if (!exit_with_session)
581d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington        dup2 (dev_null_fd, 0);
5822ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington      dup2 (dev_null_fd, 1);
583d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington      s = getenv ("DBUS_DEBUG_OUTPUT");
584d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington      if (s == NULL || *s == '\0')
585d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington        dup2 (dev_null_fd, 2);
5862ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington    }
5872ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington  else
5882ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington    {
5892ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington      fprintf (stderr, "Failed to open /dev/null: %s\n",
5902ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington               strerror (errno));
5912ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington      /* continue, why not */
5922ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington    }
5932ad05d5ce45b05b399bcdfc5c04c95b1627c90f3Havoc Pennington
594df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  ret = fork ();
595df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
596df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (ret < 0)
597df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
598df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      fprintf (stderr, "fork() failed in babysitter: %s\n",
599df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington               strerror (errno));
600df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      exit (1);
601df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
602df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
603df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (ret > 0)
604df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
605df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      /* Parent reaps pre-fork part of bus daemon, then exits and is
606df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington       * reaped so the babysitter isn't a zombie
607df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington       */
608df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
609df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose ("=== Babysitter's intermediate parent continues again\n");
610df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
611df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (do_waitpid (child_pid) < 0)
612df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
613df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          /* shouldn't happen */
614df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          fprintf (stderr, "Failed waitpid() waiting for bus daemon's parent\n");
615df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          exit (1);
616df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
617df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
618df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose ("Babysitter's intermediate parent exiting\n");
619df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
620df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      exit (0);
621df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
622df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
623df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  /* Child continues */
624df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  verbose ("=== Babysitter process created\n");
625df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
626f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  verbose ("Reading PID from bus\n");
627f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
628f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  switch (read_pid (read_bus_pid_fd, &bus_pid_to_kill))
629df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
630df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    case READ_STATUS_OK:
631df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      break;
632df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    case READ_STATUS_EOF:
633f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      fprintf (stderr, "EOF in dbus-launch reading PID from bus daemon\n");
634df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      exit (1);
635df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      break;
636df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    case READ_STATUS_ERROR:
637f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      fprintf (stderr, "Error in dbus-launch reading PID from bus daemon: %s\n",
638f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	       strerror (errno));
639df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      exit (1);
640df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      break;
641df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
642df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
643df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  verbose ("Got PID %ld from daemon\n",
644df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington           (long) bus_pid_to_kill);
645df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
646df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (exit_with_session)
647df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
648df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      /* Bus is now started and launcher has needed info;
649df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington       * we connect to X display and tty and wait to
650df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington       * kill bus if requested.
651df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington       */
652df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
653df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      kill_bus_when_session_ends ();
654df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
655df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
656df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  verbose ("Babysitter exiting\n");
657df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
658df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  exit (0);
659df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington}
660df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
6619362aac398e3f2ec680e30c61ebfcb1e407eff72Havoc Penningtonstatic void
6629362aac398e3f2ec680e30c61ebfcb1e407eff72Havoc Penningtondo_close_stderr (void)
6634ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira{
6649362aac398e3f2ec680e30c61ebfcb1e407eff72Havoc Pennington  int fd;
6659362aac398e3f2ec680e30c61ebfcb1e407eff72Havoc Pennington
6664ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira  fflush (stderr);
6674ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira
6684ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira  /* dbus-launch is a Unix-only program, so we can rely on /dev/null being there.
6694ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira   * We're including unistd.h and we're dealing with sh/csh launch sequences...
6704ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira   */
6719362aac398e3f2ec680e30c61ebfcb1e407eff72Havoc Pennington  fd = open ("/dev/null", O_RDWR);
6724ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira  if (fd == -1)
6734ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira    {
6744ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira      fprintf (stderr, "Internal error: cannot open /dev/null: %s", strerror (errno));
6754ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira      exit (1);
6764ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira    }
6774ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira
6784ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira  close (2);
6794ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira  if (dup2 (fd, 2) == -1)
68035b00e3ab25d43c0b513e21a993ce063ea19cc18Simon McVittie    {
68135b00e3ab25d43c0b513e21a993ce063ea19cc18Simon McVittie      /* error; we can't report an error anymore... */
68235b00e3ab25d43c0b513e21a993ce063ea19cc18Simon McVittie      exit (1);
68335b00e3ab25d43c0b513e21a993ce063ea19cc18Simon McVittie    }
6844ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira  close (fd);
6854ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira}
6864ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira
687ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simonsstatic void
688ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simonspass_info (const char *runprog, const char *bus_address, pid_t bus_pid,
689ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons           long bus_wid, int c_shell_syntax, int bourne_shell_syntax,
690ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons           int binary_syntax,
691ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons           int argc, char **argv, int remaining_args)
692ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons{
693ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  if (runprog)
694ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    {
695ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      char *envvar;
696ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      char **args;
697ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      int i;
698ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
699ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      envvar = malloc (strlen ("DBUS_SESSION_BUS_ADDRESS=") +
700ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons          strlen (bus_address) + 1);
701ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      args = malloc (sizeof (char *) * ((argc-remaining_args)+2));
702ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
703ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      if (envvar == NULL || args == NULL)
704ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons        goto oom;
705ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
706ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons     args[0] = xstrdup (runprog);
707ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      if (!args[0])
708ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons        goto oom;
709ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons     for (i = 1; i <= (argc-remaining_args); i++)
710ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      {
711ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons        size_t len = strlen (argv[remaining_args+i-1])+1;
712ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons        args[i] = malloc (len);
713ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons        if (!args[i])
714ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons          goto oom;
715ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons        strncpy (args[i], argv[remaining_args+i-1], len);
716ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons       }
717ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons     args[i] = NULL;
718ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
719ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons     strcpy (envvar, "DBUS_SESSION_BUS_ADDRESS=");
720ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons     strcat (envvar, bus_address);
721ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons     putenv (envvar);
722ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
723ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons     execvp (runprog, args);
724ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons     fprintf (stderr, "Couldn't exec %s: %s\n", runprog, strerror (errno));
725ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons     exit (1);
726ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    }
727ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons   else
728ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    {
729ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      print_variables (bus_address, bus_pid, bus_wid, c_shell_syntax,
730ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons         bourne_shell_syntax, binary_syntax);
731ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    }
732ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  verbose ("dbus-launch exiting\n");
733ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
734ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  fflush (stdout);
735ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  fflush (stderr);
736ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  close (1);
737ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  close (2);
738ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  exit (0);
739ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simonsoom:
740ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  fprintf (stderr, "Out of memory!");
741ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons  exit (1);
742ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons}
743ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
744df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#define READ_END  0
745df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#define WRITE_END 1
746df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
747c0158234d046381a6bc8c004c82577576977d0d7Havoc Penningtonint
748c0158234d046381a6bc8c004c82577576977d0d7Havoc Penningtonmain (int argc, char **argv)
749c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington{
750c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington  const char *prev_arg;
751fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  const char *shname;
752fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  const char *runprog = NULL;
753fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  int remaining_args = 0;
754df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int exit_with_session;
755f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  int binary_syntax = FALSE;
756fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  int c_shell_syntax = FALSE;
757fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  int bourne_shell_syntax = FALSE;
758fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  int auto_shell_syntax = FALSE;
759f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  int autolaunch = FALSE;
760c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira  int requires_arg = FALSE;
7614ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira  int close_stderr = FALSE;
7624ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira  int i;
763df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int ret;
764df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int bus_pid_to_launcher_pipe[2];
765df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int bus_pid_to_babysitter_pipe[2];
766df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  int bus_address_to_launcher_pipe[2];
7674097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington  char *config_file;
768df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
769c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington  exit_with_session = FALSE;
7704097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington  config_file = NULL;
771c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington
772c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington  prev_arg = NULL;
773c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington  i = 1;
774c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington  while (i < argc)
775c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington    {
776c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington      const char *arg = argv[i];
777c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira
778c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington      if (strcmp (arg, "--help") == 0 ||
779c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington          strcmp (arg, "-h") == 0 ||
780c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington          strcmp (arg, "-?") == 0)
781fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters        usage (0);
782fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters      else if (strcmp (arg, "--auto-syntax") == 0)
783fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters        auto_shell_syntax = TRUE;
784fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters      else if (strcmp (arg, "-c") == 0 ||
785c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira               strcmp (arg, "--csh-syntax") == 0)
786fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters        c_shell_syntax = TRUE;
787fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters      else if (strcmp (arg, "-s") == 0 ||
788c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira               strcmp (arg, "--sh-syntax") == 0)
789fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters        bourne_shell_syntax = TRUE;
790f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      else if (strcmp (arg, "--binary-syntax") == 0)
791c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira        binary_syntax = TRUE;
792c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington      else if (strcmp (arg, "--version") == 0)
793c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington        version ();
794c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington      else if (strcmp (arg, "--exit-with-session") == 0)
795c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington        exit_with_session = TRUE;
7964ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira      else if (strcmp (arg, "--close-stderr") == 0)
7974ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira        close_stderr = TRUE;
79810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      else if (strstr (arg, "--autolaunch=") == arg)
79910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington        {
80010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          const char *s;
80110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
80210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          if (autolaunch)
80310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington            {
80410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington              fprintf (stderr, "--autolaunch given twice\n");
80510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington              exit (1);
80610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington            }
80710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
80810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          autolaunch = TRUE;
80910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
81010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          s = strchr (arg, '=');
81110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          ++s;
81210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
81310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          save_machine_uuid (s);
81410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington        }
81510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      else if (prev_arg &&
81610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington               strcmp (prev_arg, "--autolaunch") == 0)
81710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington        {
81810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          if (autolaunch)
81910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington            {
82010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington              fprintf (stderr, "--autolaunch given twice\n");
82110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington              exit (1);
82210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington            }
82310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
82410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          autolaunch = TRUE;
82510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
82610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          save_machine_uuid (arg);
827c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira	  requires_arg = FALSE;
82810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington        }
829f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      else if (strcmp (arg, "--autolaunch") == 0)
830c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira	requires_arg = TRUE;
8314097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington      else if (strstr (arg, "--config-file=") == arg)
8324097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington        {
8334097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington          const char *file;
8344097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington
8354097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington          if (config_file != NULL)
8364097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington            {
8374097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington              fprintf (stderr, "--config-file given twice\n");
8384097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington              exit (1);
8394097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington            }
8404097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington
8414097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington          file = strchr (arg, '=');
8424097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington          ++file;
8434097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington
8444097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington          config_file = xstrdup (file);
8454097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington        }
8464097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington      else if (prev_arg &&
8474097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington               strcmp (prev_arg, "--config-file") == 0)
8484097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington        {
8494097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington          if (config_file != NULL)
8504097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington            {
8514097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington              fprintf (stderr, "--config-file given twice\n");
8524097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington              exit (1);
8534097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington            }
8544097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington
8554097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington          config_file = xstrdup (arg);
856c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira	  requires_arg = FALSE;
8574097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington        }
8584097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington      else if (strcmp (arg, "--config-file") == 0)
859c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira	requires_arg = TRUE;
860c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira      else if (arg[0] == '-')
861c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira        {
862c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira          if (strcmp (arg, "--") != 0)
863c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira            {
864c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira              fprintf (stderr, "Option `%s' is unknown.\n", arg);
865c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira              exit (1);
866c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira            }
867c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira          else
868c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira            {
869c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira              runprog = argv[i+1];
870c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira              remaining_args = i+2;
871c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira              break;
872c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira            }
873c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira        }
874c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington      else
875fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters	{
876fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters	  runprog = arg;
877fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters	  remaining_args = i+1;
878fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters	  break;
879fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters	}
880c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington
881c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington      prev_arg = arg;
882c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington
883c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington      ++i;
884c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington    }
885c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira  if (requires_arg)
886c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira    {
887c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira      fprintf (stderr, "Option `%s' requires an argument.\n", prev_arg);
888c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira      exit (1);
889c6e066ff8213589624507668e7dc2756dc0f59dbThiago Macieira    }
890df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
891fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters  if (auto_shell_syntax)
892fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters    {
893fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters      if ((shname = getenv ("SHELL")) != NULL)
894fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters       {
895fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters         if (!strncmp (shname + strlen (shname) - 3, "csh", 3))
896fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters           c_shell_syntax = TRUE;
897fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters         else
898fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters           bourne_shell_syntax = TRUE;
899fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters       }
900fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters      else
901fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters       bourne_shell_syntax = TRUE;
902fc5e3a06cf4876fb10d0205a626e51109f29eb82Colin Walters    }
903df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
904f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  if (exit_with_session)
905f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira    verbose ("--exit-with-session enabled\n");
906f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
907f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira  if (autolaunch)
90810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington    {
909f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#ifndef DBUS_BUILD_X11
910f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      fprintf (stderr, "Autolaunch requested, but X11 support not compiled in.\n"
911f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	       "Cannot continue.\n");
912f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      exit (1);
913f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#else
914f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      char *address;
915f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      pid_t pid;
916f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      long wid;
91710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington
91810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington      if (get_machine_uuid () == NULL)
91910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington        {
92010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          fprintf (stderr, "Machine UUID not provided as arg to --autolaunch\n");
92110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington          exit (1);
92210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington        }
923f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
924f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      verbose ("Autolaunch enabled (using X11).\n");
925f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      if (!exit_with_session)
926f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	{
927f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  verbose ("--exit-with-session automatically enabled\n");
928f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  exit_with_session = TRUE;
929f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	}
930f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
931f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      if (!x11_init ())
932f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	{
933f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  fprintf (stderr, "Autolaunch error: X11 initialization failed.\n");
934f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  exit (1);
935f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	}
936f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
937f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      if (!x11_get_address (&address, &pid, &wid))
938f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	{
939f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  fprintf (stderr, "Autolaunch error: X11 communication error.\n");
940f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  exit (1);
941f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	}
942f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
943f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      if (address != NULL)
944ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons	{
945f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  verbose ("dbus-daemon is already running. Returning existing parameters.\n");
946ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons	  pass_info (runprog, address, pid, wid, c_shell_syntax,
947ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons			   bourne_shell_syntax, binary_syntax, argc, argv, remaining_args);
948f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  exit (0);
949f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	}
950ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    }
951ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons   else if (read_machine_uuid_if_needed())
952ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    {
953ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      x11_init();
954f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#endif
955f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira    }
956f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
957ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons
958df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (pipe (bus_pid_to_launcher_pipe) < 0 ||
959f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      pipe (bus_address_to_launcher_pipe) < 0 ||
960f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      pipe (bus_pid_to_babysitter_pipe) < 0)
961df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
962df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      fprintf (stderr,
963df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington               "Failed to create pipe: %s\n",
964df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington               strerror (errno));
965df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      exit (1);
966df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
967df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
968df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  ret = fork ();
969df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (ret < 0)
970df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
971df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      fprintf (stderr, "Failed to fork: %s\n",
972df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington               strerror (errno));
973df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      exit (1);
974df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
975df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
976df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  if (ret == 0)
977df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
978df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      /* Child */
979df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington#define MAX_FD_LEN 64
980df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      char write_pid_fd_as_string[MAX_FD_LEN];
981df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      char write_address_fd_as_string[MAX_FD_LEN];
982df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
98346b48ac65414181b60085534475006de42b018cdJohn (J#ifdef DBUS_BUILD_X11
9847d409700c354e7a35989053ba037750d320a308aJohn (J      xdisplay = NULL;
98546b48ac65414181b60085534475006de42b018cdJohn (J#endif
9867d409700c354e7a35989053ba037750d320a308aJohn (J
9874ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira      if (close_stderr)
9884ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira	do_close_stderr ();
9894ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira
990df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose ("=== Babysitter's intermediate parent created\n");
991f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
992df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      /* Fork once more to create babysitter */
993df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
994df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      ret = fork ();
995df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (ret < 0)
996df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
997df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          fprintf (stderr, "Failed to fork: %s\n",
998df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                   strerror (errno));
999df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          exit (1);
1000df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
1001df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1002df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (ret > 0)
1003df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
1004df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          /* In babysitter */
1005df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          verbose ("=== Babysitter's intermediate parent continues\n");
1006df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1007df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          close (bus_pid_to_launcher_pipe[READ_END]);
1008f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  close (bus_pid_to_launcher_pipe[WRITE_END]);
1009df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          close (bus_address_to_launcher_pipe[READ_END]);
1010df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          close (bus_address_to_launcher_pipe[WRITE_END]);
1011df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          close (bus_pid_to_babysitter_pipe[WRITE_END]);
10124ceb86d29a68ebe52b20c8c090bc90c68a58f8c8Thiago Macieira
1013df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          /* babysit() will fork *again*
1014df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington           * and will also reap the pre-forked bus
1015df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington           * daemon
1016df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington           */
1017df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          babysit (exit_with_session, ret,
1018f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira                   bus_pid_to_babysitter_pipe[READ_END]);
1019df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          exit (0);
1020df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
1021df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1022df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose ("=== Bus exec process created\n");
1023df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1024df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      /* Now we are the bus process (well, almost;
10252abdb13ebe737e39653b79fecd93477e156b9db1Havoc Pennington       * dbus-daemon itself forks again)
1026df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington       */
1027df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      close (bus_pid_to_launcher_pipe[READ_END]);
1028df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      close (bus_address_to_launcher_pipe[READ_END]);
1029df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      close (bus_pid_to_babysitter_pipe[READ_END]);
1030f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      close (bus_pid_to_babysitter_pipe[WRITE_END]);
1031df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1032df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      sprintf (write_pid_fd_as_string,
1033f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira               "%d", bus_pid_to_launcher_pipe[WRITE_END]);
1034df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1035df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      sprintf (write_address_fd_as_string,
1036df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington               "%d", bus_address_to_launcher_pipe[WRITE_END]);
1037df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1038df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose ("Calling exec()\n");
1039a107da84891f941d591bcaa99641f4058f089c7dJohn (J
1040a107da84891f941d591bcaa99641f4058f089c7dJohn (J#ifdef DBUS_BUILD_TESTS
1041a107da84891f941d591bcaa99641f4058f089c7dJohn (J      /* exec from testdir */
1042a107da84891f941d591bcaa99641f4058f089c7dJohn (J      if (getenv("DBUS_USE_TEST_BINARY") != NULL)
1043a107da84891f941d591bcaa99641f4058f089c7dJohn (J        {
1044a107da84891f941d591bcaa99641f4058f089c7dJohn (J          execl (TEST_BUS_BINARY,
1045a107da84891f941d591bcaa99641f4058f089c7dJohn (J                 TEST_BUS_BINARY,
1046a107da84891f941d591bcaa99641f4058f089c7dJohn (J                 "--fork",
1047a107da84891f941d591bcaa99641f4058f089c7dJohn (J                 "--print-pid", write_pid_fd_as_string,
1048a107da84891f941d591bcaa99641f4058f089c7dJohn (J                 "--print-address", write_address_fd_as_string,
1049a107da84891f941d591bcaa99641f4058f089c7dJohn (J                 config_file ? "--config-file" : "--session",
1050a107da84891f941d591bcaa99641f4058f089c7dJohn (J                 config_file, /* has to be last in this varargs list */
1051a107da84891f941d591bcaa99641f4058f089c7dJohn (J                 NULL);
1052a107da84891f941d591bcaa99641f4058f089c7dJohn (J
1053a107da84891f941d591bcaa99641f4058f089c7dJohn (J          fprintf (stderr,
1054a107da84891f941d591bcaa99641f4058f089c7dJohn (J                   "Failed to execute test message bus daemon %s: %s. Will try again with the system path.\n",
1055a107da84891f941d591bcaa99641f4058f089c7dJohn (J                   TEST_BUS_BINARY, strerror (errno));
1056a107da84891f941d591bcaa99641f4058f089c7dJohn (J        }
1057a107da84891f941d591bcaa99641f4058f089c7dJohn (J #endif /* DBUS_BUILD_TESTS */
1058a107da84891f941d591bcaa99641f4058f089c7dJohn (J
1059aaa432b0644199418eb2ce506c87397cd379df4fJohn (J      execl (DBUS_DAEMONDIR"/dbus-daemon",
1060aaa432b0644199418eb2ce506c87397cd379df4fJohn (J             DBUS_DAEMONDIR"/dbus-daemon",
1061aaa432b0644199418eb2ce506c87397cd379df4fJohn (J             "--fork",
1062aaa432b0644199418eb2ce506c87397cd379df4fJohn (J             "--print-pid", write_pid_fd_as_string,
1063aaa432b0644199418eb2ce506c87397cd379df4fJohn (J             "--print-address", write_address_fd_as_string,
1064aaa432b0644199418eb2ce506c87397cd379df4fJohn (J             config_file ? "--config-file" : "--session",
1065aaa432b0644199418eb2ce506c87397cd379df4fJohn (J             config_file, /* has to be last in this varargs list */
1066aaa432b0644199418eb2ce506c87397cd379df4fJohn (J             NULL);
1067aaa432b0644199418eb2ce506c87397cd379df4fJohn (J
1068aaa432b0644199418eb2ce506c87397cd379df4fJohn (J      fprintf (stderr,
1069aaa432b0644199418eb2ce506c87397cd379df4fJohn (J               "Failed to execute message bus daemon %s: %s.  Will try again without full path.\n",
1070aaa432b0644199418eb2ce506c87397cd379df4fJohn (J               DBUS_DAEMONDIR"/dbus-daemon", strerror (errno));
1071d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
1072aaa432b0644199418eb2ce506c87397cd379df4fJohn (J      /*
1073aaa432b0644199418eb2ce506c87397cd379df4fJohn (J       * If it failed, try running without full PATH.  Note this is needed
1074aaa432b0644199418eb2ce506c87397cd379df4fJohn (J       * because the build process builds the run-with-tmp-session-bus.conf
1075aaa432b0644199418eb2ce506c87397cd379df4fJohn (J       * file and the dbus-daemon will not be in the install location during
1076aaa432b0644199418eb2ce506c87397cd379df4fJohn (J       * build time.
1077aaa432b0644199418eb2ce506c87397cd379df4fJohn (J       */
10782abdb13ebe737e39653b79fecd93477e156b9db1Havoc Pennington      execlp ("dbus-daemon",
10792abdb13ebe737e39653b79fecd93477e156b9db1Havoc Pennington              "dbus-daemon",
1080df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              "--fork",
1081df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              "--print-pid", write_pid_fd_as_string,
1082df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              "--print-address", write_address_fd_as_string,
10834097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington              config_file ? "--config-file" : "--session",
10844097e94af3d2fb1eb865343e3f76ca3949e7c69bHavoc Pennington              config_file, /* has to be last in this varargs list */
1085df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington              NULL);
1086df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1087df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      fprintf (stderr,
1088df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington               "Failed to execute message bus daemon: %s\n",
1089df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington               strerror (errno));
1090df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      exit (1);
1091df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    }
1092df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington  else
1093df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington    {
1094df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      /* Parent */
1095f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#define MAX_PID_LEN 64
1096df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      pid_t bus_pid;
1097df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      char bus_address[MAX_ADDR_LEN];
1098f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      char buf[MAX_PID_LEN];
1099f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      char *end;
1100f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      long wid = 0;
1101f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      long val;
1102f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      int ret2;
1103df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1104df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose ("=== Parent dbus-launch continues\n");
1105df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1106df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      close (bus_pid_to_launcher_pipe[WRITE_END]);
1107df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      close (bus_address_to_launcher_pipe[WRITE_END]);
1108f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      close (bus_pid_to_babysitter_pipe[READ_END]);
1109df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1110df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose ("Waiting for babysitter's intermediate parent\n");
1111df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1112df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      /* Immediately reap parent of babysitter
1113df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington       * (which was created just for us to reap)
1114df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington       */
1115df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      if (do_waitpid (ret) < 0)
1116df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
1117df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          fprintf (stderr, "Failed to waitpid() for babysitter intermediate process: %s\n",
1118df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                   strerror (errno));
1119df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          exit (1);
1120df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
1121df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1122df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      verbose ("Reading address from bus\n");
1123df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1124df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      /* Read the pipe data, print, and exit */
1125df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      switch (read_line (bus_address_to_launcher_pipe[READ_END],
1126df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                         bus_address, MAX_ADDR_LEN))
1127df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        {
1128df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        case READ_STATUS_OK:
1129df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          break;
1130df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        case READ_STATUS_EOF:
1131df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          fprintf (stderr, "EOF in dbus-launch reading address from bus daemon\n");
1132df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          exit (1);
1133df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          break;
1134df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        case READ_STATUS_ERROR:
1135df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          fprintf (stderr, "Error in dbus-launch reading address from bus daemon: %s\n",
1136df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington                   strerror (errno));
1137df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          exit (1);
1138df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington          break;
1139df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington        }
1140df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1141df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      close (bus_address_to_launcher_pipe[READ_END]);
1142df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1143f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      verbose ("Reading PID from daemon\n");
1144f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      /* Now read data */
1145f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      switch (read_line (bus_pid_to_launcher_pipe[READ_END], buf, MAX_PID_LEN))
1146f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	{
1147f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	case READ_STATUS_OK:
1148f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  break;
1149f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	case READ_STATUS_EOF:
1150f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  fprintf (stderr, "EOF reading PID from bus daemon\n");
1151f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  exit (1);
1152f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  break;
1153f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	case READ_STATUS_ERROR:
1154f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  fprintf (stderr, "Error reading PID from bus daemon: %s\n",
1155f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira		   strerror (errno));
1156f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  exit (1);
1157f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  break;
1158f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	}
1159f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
1160f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      end = NULL;
1161f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      val = strtol (buf, &end, 0);
1162f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      if (buf == end || end == NULL)
1163f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	{
1164f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  fprintf (stderr, "Failed to parse bus PID \"%s\": %s\n",
1165f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira		   buf, strerror (errno));
1166f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	  exit (1);
1167f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira	}
1168f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
1169f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      bus_pid = val;
1170df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington
1171df01c98cc7e83f3336e501fcf2eeee52c95464fbHavoc Pennington      close (bus_pid_to_launcher_pipe[READ_END]);
1172f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
1173f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#ifdef DBUS_BUILD_X11
1174ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons      if (xdisplay != NULL)
1175d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington        {
1176ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons          verbose("Saving x11 address\n");
1177d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington          ret2 = x11_save_address (bus_address, bus_pid, &wid);
1178ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons          /* Only get an existing dbus session when autolaunching */
1179ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons          if (autolaunch)
1180d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington            {
1181ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons              if (ret2 == 0)
1182d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                {
1183ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                  char *address = NULL;
1184ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                  /* another window got added. Return its address */
1185d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                  bus_pid_to_kill = bus_pid;
1186ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                  if (x11_get_address (&address, &bus_pid, &wid)
1187ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                       && address != NULL)
1188ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                    {
1189ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                      verbose ("dbus-daemon is already running. Returning existing parameters.\n");
1190ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                      /* Kill the old bus */
1191ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                      kill_bus();
1192ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                      pass_info (runprog, address, bus_pid, wid,
1193ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                         c_shell_syntax, bourne_shell_syntax, binary_syntax,
1194ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                         argc, argv, remaining_args);
1195ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                    }
1196ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                  }
1197ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons              if (ret2 < 0)
1198ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                {
1199ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                  fprintf (stderr, "Error saving bus information.\n");
1200ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                  bus_pid_to_kill = bus_pid;
1201ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons                  kill_bus_and_exit (1);
1202d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                }
1203d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington            }
1204d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington        }
1205f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#endif
1206f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
1207f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      /* Forward the pid to the babysitter */
1208f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      write_pid (bus_pid_to_babysitter_pipe[WRITE_END], bus_pid);
1209f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira      close (bus_pid_to_babysitter_pipe[WRITE_END]);
1210f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira
1211ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons       pass_info (runprog, bus_address, bus_pid, wid, c_shell_syntax,
1212ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons              bourne_shell_syntax, binary_syntax, argc, argv, remaining_args);
1213ed47b4502b4b6bc1cabd99be3c3b63859be72a7cSjoerd Simons    }
1214d6e1b2adb3d8e51ce1bb47295cef12d9fe1a15a8Havoc Pennington
1215c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington  return 0;
1216c0158234d046381a6bc8c004c82577576977d0d7Havoc Pennington}
1217