X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tools%2Fdbus-launch.c;h=2a2abbbf8572c5b0ddd5b586303515b9ff6d096e;hb=16ed767007722d7450e6f5a4e23fff0166f466dc;hp=ec4c9a5ac171b1c17c6b99a2e40f5944d7123701;hpb=dbecdeabb20e0ce11121819c63373f0afba57c58;p=platform%2Fupstream%2Fdbus.git diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c index ec4c9a5..2a2abbb 100644 --- a/tools/dbus-launch.c +++ b/tools/dbus-launch.c @@ -43,6 +43,47 @@ extern Display *xdisplay; #endif +/* PROCESSES + * + * If you are in a shell and run "dbus-launch myapp", here is what happens: + * + * shell [*] + * \- main() --exec--> myapp[*] + * \- "intermediate parent" + * \- bus-runner --exec--> dbus-daemon --fork + * \- babysitter[*] \- final dbus-daemon[*] + * + * Processes marked [*] survive the initial flurry of activity. + * + * If you run "dbus-launch --sh-syntax" then the diagram is the same, except + * that main() prints variables and exits 0 instead of exec'ing myapp. + * + * PIPES + * + * dbus-daemon --print-pid -> bus_pid_to_launcher_pipe -> main + * dbus-daemon --print-address -> bus_address_to_launcher_pipe -> main + * main -> bus_pid_to_babysitter_pipe -> babysitter + * + * The intermediate parent looks pretty useless at first glance. Its purpose + * is to avoid the bus-runner becoming a zombie: when the intermediate parent + * terminates, the bus-runner and babysitter are reparented to init, which + * reaps them if they have finished. We can't rely on main() to reap arbitrary + * children because it might exec myapp, after which it can't be relied on to + * reap its children. We *can* rely on main() to reap the intermediate parent, + * because that happens before it execs myapp. + * + * It's unclear why dbus-daemon needs to fork, but we explicitly tell it to + * for some reason, then wait for it. If we left it undefined, a forking + * dbus-daemon would get the parent process reparented to init and reaped + * when the intermediate parent terminated, and a non-forking dbus-daemon + * would get reparented to init and carry on there. + * + * myapp is exec'd by the process that initially ran main() so that it's + * the shell's child, so the shell knows how to do job control and stuff. + * This is desirable for the "dbus-launch an application" use-case, less so + * for the "dbus-launch a test suite in an isolated session" use-case. + */ + static char* machine_uuid = NULL; const char* @@ -64,6 +105,7 @@ save_machine_uuid (const char *uuid_arg) machine_uuid = xstrdup (uuid_arg); } +#ifdef DBUS_BUILD_X11 #define UUID_MAXLEN 40 /* Read the machine uuid from file if needed. Returns TRUE if machine_uuid is * set after this function */ @@ -105,12 +147,13 @@ out: fclose(f); return ret; } - +#endif /* DBUS_BUILD_X11 */ void verbose (const char *format, ...) { +#ifdef DBUS_ENABLE_VERBOSE_MODE va_list args; static int verbose = TRUE; static int verbose_initted = FALSE; @@ -135,12 +178,16 @@ verbose (const char *format, va_start (args, format); vfprintf (stderr, format, args); va_end (args); +#endif /* DBUS_ENABLE_VERBOSE_MODE */ } static void usage (int ecode) { - fprintf (stderr, "dbus-launch [--version] [--help] [--sh-syntax] [--csh-syntax] [--auto-syntax] [--exit-with-session]\n"); + fprintf (stderr, "dbus-launch [--version] [--help] [--sh-syntax]" + " [--csh-syntax] [--auto-syntax] [--binary-syntax] [--close-stderr]" + " [--exit-with-session] [--autolaunch=MACHINEID]" + " [--config-file=FILENAME] [PROGRAM] [ARGS...]\n"); exit (ecode); } @@ -365,9 +412,9 @@ print_variables (const char *bus_address, pid_t bus_pid, long bus_wid, { if (binary_syntax) { - write (1, bus_address, strlen (bus_address) + 1); - write (1, &bus_pid, sizeof bus_pid); - write (1, &bus_wid, sizeof bus_wid); + do_write (1, bus_address, strlen (bus_address) + 1); + do_write (1, &bus_pid, sizeof bus_pid); + do_write (1, &bus_wid, sizeof bus_wid); return; } else if (c_shell_syntax) @@ -451,11 +498,20 @@ kill_bus_when_session_ends (void) else tty_fd = -1; - if (tty_fd >= 0) - verbose ("stdin isatty(), monitoring it\n"); + if (x_fd >= 0) + { + verbose ("session lifetime is defined by X, not monitoring stdin\n"); + tty_fd = -1; + } + else if (tty_fd >= 0) + { + verbose ("stdin isatty(), monitoring it\n"); + } else - verbose ("stdin was not a TTY, not monitoring it\n"); - + { + verbose ("stdin was not a TTY, not monitoring it\n"); + } + if (tty_fd < 0 && x_fd < 0) { fprintf (stderr, "No terminal on standard input and no X display; cannot attach message bus to session lifetime\n"); @@ -583,6 +639,7 @@ babysit (int exit_with_session, s = getenv ("DBUS_DEBUG_OUTPUT"); if (s == NULL || *s == '\0') dup2 (dev_null_fd, 2); + close (dev_null_fd); } else { @@ -690,10 +747,11 @@ pass_info (const char *runprog, const char *bus_address, pid_t bus_pid, int binary_syntax, int argc, char **argv, int remaining_args) { + char *envvar = NULL; + char **args = NULL; + if (runprog) { - char *envvar; - char **args; int i; envvar = malloc (strlen ("DBUS_SESSION_BUS_ADDRESS=") + @@ -703,31 +761,31 @@ pass_info (const char *runprog, const char *bus_address, pid_t bus_pid, if (envvar == NULL || args == NULL) goto oom; - args[0] = xstrdup (runprog); + args[0] = xstrdup (runprog); if (!args[0]) goto oom; - for (i = 1; i <= (argc-remaining_args); i++) - { - size_t len = strlen (argv[remaining_args+i-1])+1; - args[i] = malloc (len); - if (!args[i]) - goto oom; - strncpy (args[i], argv[remaining_args+i-1], len); - } - args[i] = NULL; + for (i = 1; i <= (argc-remaining_args); i++) + { + size_t len = strlen (argv[remaining_args+i-1])+1; + args[i] = malloc (len); + if (!args[i]) + goto oom; + strncpy (args[i], argv[remaining_args+i-1], len); + } + args[i] = NULL; - strcpy (envvar, "DBUS_SESSION_BUS_ADDRESS="); - strcat (envvar, bus_address); - putenv (envvar); + strcpy (envvar, "DBUS_SESSION_BUS_ADDRESS="); + strcat (envvar, bus_address); + putenv (envvar); - execvp (runprog, args); - fprintf (stderr, "Couldn't exec %s: %s\n", runprog, strerror (errno)); - exit (1); + execvp (runprog, args); + fprintf (stderr, "Couldn't exec %s: %s\n", runprog, strerror (errno)); + exit (1); } else { print_variables (bus_address, bus_pid, bus_wid, c_shell_syntax, - bourne_shell_syntax, binary_syntax); + bourne_shell_syntax, binary_syntax); } verbose ("dbus-launch exiting\n"); @@ -737,6 +795,12 @@ pass_info (const char *runprog, const char *bus_address, pid_t bus_pid, close (2); exit (0); oom: + if (envvar) + free (envvar); + + if (args) + free (args); + fprintf (stderr, "Out of memory!"); exit (1); } @@ -759,6 +823,7 @@ main (int argc, char **argv) int autolaunch = FALSE; int requires_arg = FALSE; int close_stderr = FALSE; + int kdbus = FALSE; int i; int ret; int bus_pid_to_launcher_pipe[2]; @@ -795,6 +860,8 @@ main (int argc, char **argv) exit_with_session = TRUE; else if (strcmp (arg, "--close-stderr") == 0) close_stderr = TRUE; + else if (strcmp (arg, "--kdbus") == 0) + kdbus = TRUE; else if (strstr (arg, "--autolaunch=") == arg) { const char *s; @@ -910,7 +977,11 @@ main (int argc, char **argv) fprintf (stderr, "Autolaunch requested, but X11 support not compiled in.\n" "Cannot continue.\n"); exit (1); -#else +#else /* DBUS_BUILD_X11 */ +#ifndef DBUS_ENABLE_X11_AUTOLAUNCH + fprintf (stderr, "X11 autolaunch support disabled at compile time.\n"); + exit (1); +#else /* DBUS_ENABLE_X11_AUTOLAUNCH */ char *address; pid_t pid; long wid; @@ -947,11 +1018,12 @@ main (int argc, char **argv) bourne_shell_syntax, binary_syntax, argc, argv, remaining_args); exit (0); } +#endif /* DBUS_ENABLE_X11_AUTOLAUNCH */ } - else if (read_machine_uuid_if_needed()) + else if (read_machine_uuid_if_needed()) { x11_init(); -#endif +#endif /* DBUS_BUILD_X11 */ } @@ -1037,7 +1109,7 @@ main (int argc, char **argv) verbose ("Calling exec()\n"); -#ifdef DBUS_BUILD_TESTS +#ifdef DBUS_ENABLE_EMBEDDED_TESTS /* exec from testdir */ if (getenv("DBUS_USE_TEST_BINARY") != NULL) { @@ -1054,16 +1126,32 @@ main (int argc, char **argv) "Failed to execute test message bus daemon %s: %s. Will try again with the system path.\n", TEST_BUS_BINARY, strerror (errno)); } - #endif /* DBUS_BUILD_TESTS */ + #endif /* DBUS_ENABLE_EMBEDDED_TESTS */ - execl (DBUS_DAEMONDIR"/dbus-daemon", + if (kdbus) + { + execl (DBUS_DAEMONDIR"/dbus-daemon", DBUS_DAEMONDIR"/dbus-daemon", "--fork", "--print-pid", write_pid_fd_as_string, "--print-address", write_address_fd_as_string, + "--address=kdbus:", config_file ? "--config-file" : "--session", config_file, /* has to be last in this varargs list */ NULL); + } + else + { + execl (DBUS_DAEMONDIR"/dbus-daemon", + DBUS_DAEMONDIR"/dbus-daemon", + "--fork", + "--print-pid", write_pid_fd_as_string, + "--print-address", write_address_fd_as_string, + config_file ? "--config-file" : "--session", + config_file, /* has to be last in this varargs list */ + NULL); + } + fprintf (stderr, "Failed to execute message bus daemon %s: %s. Will try again without full path.\n", @@ -1075,7 +1163,21 @@ main (int argc, char **argv) * file and the dbus-daemon will not be in the install location during * build time. */ - execlp ("dbus-daemon", + if (kdbus) + { + execlp ("dbus-daemon", + "dbus-daemon", + "--fork", + "--print-pid", write_pid_fd_as_string, + "--print-address", write_address_fd_as_string, + "--address=kdbus:", + config_file ? "--config-file" : "--session", + config_file, /* has to be last in this varargs list */ + NULL); + } + else + { + execlp ("dbus-daemon", "dbus-daemon", "--fork", "--print-pid", write_pid_fd_as_string, @@ -1083,6 +1185,7 @@ main (int argc, char **argv) config_file ? "--config-file" : "--session", config_file, /* has to be last in this varargs list */ NULL); + } fprintf (stderr, "Failed to execute message bus daemon: %s\n", @@ -1099,7 +1202,6 @@ main (int argc, char **argv) char *end; long wid = 0; long val; - int ret2; verbose ("=== Parent dbus-launch continues\n"); @@ -1170,9 +1272,11 @@ main (int argc, char **argv) close (bus_pid_to_launcher_pipe[READ_END]); -#ifdef DBUS_BUILD_X11 +#ifdef DBUS_ENABLE_X11_AUTOLAUNCH if (xdisplay != NULL) { + int ret2; + verbose("Saving x11 address\n"); ret2 = x11_save_address (bus_address, bus_pid, &wid); /* Only get an existing dbus session when autolaunching */