X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tools%2Fdbus-launch.c;h=bbaac2c3a8907db15db3fb093cb29182879bbc9a;hb=2460ddfdb2c1980226593e1af42117b38d5be7dc;hp=80d885f44e3bceba84aedb700f4f65ae5fd6ef72;hpb=7d9d3fc031244bee29b5ac25e07f3e8e5b5dd97b;p=platform%2Fupstream%2Fdbus.git diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c index 80d885f..bbaac2c 100644 --- a/tools/dbus-launch.c +++ b/tools/dbus-launch.c @@ -18,11 +18,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ + +#include #include "dbus-launch.h" #include +#include #include #include #include @@ -61,6 +64,49 @@ save_machine_uuid (const char *uuid_arg) machine_uuid = xstrdup (uuid_arg); } +#define UUID_MAXLEN 40 +/* Read the machine uuid from file if needed. Returns TRUE if machine_uuid is + * set after this function */ +static int +read_machine_uuid_if_needed (void) +{ + FILE *f; + char uuid[UUID_MAXLEN]; + size_t len; + int ret = FALSE; + + if (machine_uuid != NULL) + return TRUE; + + f = fopen (DBUS_MACHINE_UUID_FILE, "r"); + if (f == NULL) + return FALSE; + + if (fgets (uuid, UUID_MAXLEN, f) == NULL) + goto out; + + len = strlen (uuid); + if (len < 32) + goto out; + + /* rstrip the read uuid */ + while (len > 31 && isspace(uuid[len - 1])) + len--; + + if (len != 32) + goto out; + + uuid[len] = '\0'; + machine_uuid = xstrdup (uuid); + verbose ("UID: %s\n", machine_uuid); + ret = TRUE; + +out: + fclose(f); + return ret; +} + + void verbose (const char *format, ...) @@ -290,19 +336,24 @@ do_waitpid (pid_t pid) static pid_t bus_pid_to_kill = -1; +static void +kill_bus(void) +{ + verbose ("Killing message bus and exiting babysitter\n"); + kill (bus_pid_to_kill, SIGTERM); + sleep (3); + kill (bus_pid_to_kill, SIGKILL); +} + void kill_bus_and_exit (int exitcode) { - verbose ("Killing message bus and exiting babysitter\n"); - /* in case these point to any NFS mounts, get rid of them immediately */ close (0); close (1); close (2); - kill (bus_pid_to_kill, SIGTERM); - sleep (3); - kill (bus_pid_to_kill, SIGKILL); + kill_bus(); exit (exitcode); } @@ -314,9 +365,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) @@ -353,7 +404,10 @@ signal_handler (int sig) { switch (sig) { +#ifdef SIGHUP case SIGHUP: +#endif + case SIGINT: case SIGTERM: got_sighup = TRUE; break; @@ -378,6 +432,7 @@ kill_bus_when_session_ends (void) act.sa_flags = 0; sigaction (SIGHUP, &act, NULL); sigaction (SIGTERM, &act, NULL); + sigaction (SIGINT, &act, NULL); #ifdef DBUS_BUILD_X11 x11_init(); @@ -409,6 +464,17 @@ kill_bus_when_session_ends (void) while (TRUE) { +#ifdef DBUS_BUILD_X11 + /* Dump events on the floor, and let + * IO error handler run if we lose + * the X connection. It's important to + * run this before going into select() since + * we might have queued outgoing messages or + * events. + */ + x11_handle_event (); +#endif + FD_ZERO (&read_set); FD_ZERO (&err_set); @@ -423,7 +489,7 @@ kill_bus_when_session_ends (void) FD_SET (x_fd, &read_set); FD_SET (x_fd, &err_set); } - + select (MAX (tty_fd, x_fd) + 1, &read_set, NULL, &err_set, NULL); @@ -434,15 +500,12 @@ kill_bus_when_session_ends (void) } #ifdef DBUS_BUILD_X11 - /* Dump events on the floor, and let - * IO error handler run if we lose - * the X connection + /* Events will be processed before we select again */ if (x_fd >= 0) verbose ("X fd condition reading = %d error = %d\n", FD_ISSET (x_fd, &read_set), FD_ISSET (x_fd, &err_set)); - x11_handle_event (); #endif if (tty_fd >= 0) @@ -614,11 +677,77 @@ do_close_stderr (void) close (2); if (dup2 (fd, 2) == -1) - // error; we can't report an error anymore... - exit (1); + { + /* error; we can't report an error anymore... */ + exit (1); + } close (fd); } +static void +pass_info (const char *runprog, const char *bus_address, pid_t bus_pid, + long bus_wid, int c_shell_syntax, int bourne_shell_syntax, + int binary_syntax, + int argc, char **argv, int remaining_args) +{ + char *envvar = NULL; + char **args = NULL; + + if (runprog) + { + int i; + + envvar = malloc (strlen ("DBUS_SESSION_BUS_ADDRESS=") + + strlen (bus_address) + 1); + args = malloc (sizeof (char *) * ((argc-remaining_args)+2)); + + if (envvar == NULL || args == NULL) + goto oom; + + 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; + + 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); + } + else + { + print_variables (bus_address, bus_pid, bus_wid, c_shell_syntax, + bourne_shell_syntax, binary_syntax); + } + verbose ("dbus-launch exiting\n"); + + fflush (stdout); + fflush (stderr); + close (1); + close (2); + exit (0); +oom: + if (envvar) + free (envvar); + + if (args) + free (args); + + fprintf (stderr, "Out of memory!"); + exit (1); +} + #define READ_END 0 #define WRITE_END 1 @@ -788,7 +917,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; @@ -799,16 +932,6 @@ main (int argc, char **argv) exit (1); } - /* FIXME right now autolaunch always does print_variables(), but it should really - * exec the child program instead if a child program was specified. For now - * we just exit if this conflict arises. - */ - if (runprog) - { - fprintf (stderr, "Currently --autolaunch does not support running a program\n"); - exit (1); - } - verbose ("Autolaunch enabled (using X11).\n"); if (!exit_with_session) { @@ -829,15 +952,21 @@ main (int argc, char **argv) } if (address != NULL) - { + { verbose ("dbus-daemon is already running. Returning existing parameters.\n"); - print_variables (address, pid, wid, c_shell_syntax, - bourne_shell_syntax, binary_syntax); + pass_info (runprog, address, pid, wid, c_shell_syntax, + bourne_shell_syntax, binary_syntax, argc, argv, remaining_args); exit (0); } -#endif +#endif /* DBUS_ENABLE_X11_AUTOLAUNCH */ + } + else if (read_machine_uuid_if_needed()) + { + x11_init(); +#endif /* DBUS_BUILD_X11 */ } + if (pipe (bus_pid_to_launcher_pipe) < 0 || pipe (bus_address_to_launcher_pipe) < 0 || pipe (bus_pid_to_babysitter_pipe) < 0) @@ -863,6 +992,10 @@ main (int argc, char **argv) char write_pid_fd_as_string[MAX_FD_LEN]; char write_address_fd_as_string[MAX_FD_LEN]; +#ifdef DBUS_BUILD_X11 + xdisplay = NULL; +#endif + if (close_stderr) do_close_stderr (); @@ -1049,38 +1182,36 @@ main (int argc, char **argv) close (bus_pid_to_launcher_pipe[READ_END]); -#ifdef DBUS_BUILD_X11 - /* FIXME the runprog == NULL is broken - we need to launch the runprog with the existing bus, - * instead of just doing print_variables() if there's an existing bus. - */ - if (xdisplay != NULL && runprog == NULL) +#ifdef DBUS_ENABLE_X11_AUTOLAUNCH + if (xdisplay != NULL) { + verbose("Saving x11 address\n"); ret2 = x11_save_address (bus_address, bus_pid, &wid); - if (ret2 == 0) + /* Only get an existing dbus session when autolaunching */ + if (autolaunch) { - /* another window got added. Return its address */ - char *address; - pid_t pid; - long wid; - - if (x11_get_address (&address, &pid, &wid) && address != NULL) + if (ret2 == 0) { - verbose ("dbus-daemon is already running. Returning existing parameters.\n"); - print_variables (address, pid, wid, c_shell_syntax, - bourne_shell_syntax, binary_syntax); - free (address); - + char *address = NULL; + /* another window got added. Return its address */ bus_pid_to_kill = bus_pid; - kill_bus_and_exit (0); + if (x11_get_address (&address, &bus_pid, &wid) + && address != NULL) + { + verbose ("dbus-daemon is already running. Returning existing parameters.\n"); + /* Kill the old bus */ + kill_bus(); + pass_info (runprog, address, bus_pid, wid, + c_shell_syntax, bourne_shell_syntax, binary_syntax, + argc, argv, remaining_args); + } + } + if (ret2 < 0) + { + fprintf (stderr, "Error saving bus information.\n"); + bus_pid_to_kill = bus_pid; + kill_bus_and_exit (1); } - - /* if failed, fall through */ - } - if (ret2 <= 0) - { - fprintf (stderr, "Error saving bus information.\n"); - bus_pid_to_kill = bus_pid; - kill_bus_and_exit (1); } } #endif @@ -1089,56 +1220,9 @@ main (int argc, char **argv) write_pid (bus_pid_to_babysitter_pipe[WRITE_END], bus_pid); close (bus_pid_to_babysitter_pipe[WRITE_END]); - if (runprog) - { - char *envvar; - char **args; - - envvar = malloc (strlen ("DBUS_SESSION_BUS_ADDRESS=") + strlen (bus_address) + 1); - args = malloc (sizeof (char *) * ((argc-remaining_args)+2)); - - if (envvar == NULL || args == NULL) - goto oom; - - 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; - - 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); - } - else - { - print_variables (bus_address, bus_pid, wid, c_shell_syntax, - bourne_shell_syntax, binary_syntax); - } - - verbose ("dbus-launch exiting\n"); + pass_info (runprog, bus_address, bus_pid, wid, c_shell_syntax, + bourne_shell_syntax, binary_syntax, argc, argv, remaining_args); + } - fflush (stdout); - fflush (stderr); - close (1); - close (2); - - exit (0); - } - return 0; - oom: - fprintf (stderr, "Out of memory!"); - exit (1); }