summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2009-07-13 13:02:21 -0400
committerColin Walters <walters@verbum.org>2009-07-14 15:41:48 -0400
commit96e785bb0614dc9ebbf6aebe12797d93a1b76b14 (patch)
tree44e831922333827d2630e54c04fbeda3f5791d0d
parent44062b35af52e60b8e302488c556af0ad4443970 (diff)
Bug 14259 - Refactor _dbus_get_autolaunch_address
Split out the process-launching code, which can be reused for other applications; in particular, a forthcoming patch to parse output from launchd for MacOS X. (cherry picked from commit 6b163e95e7a2318a98c16c0d0944337e38e62efa)
-rw-r--r--dbus/dbus-sysdeps-unix.c184
1 files changed, 114 insertions, 70 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 6396378c..a26f02d6 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -2863,23 +2863,30 @@ _dbus_get_tmpdir(void)
}
/**
- * Determines the address of the session bus by querying a
- * platform-specific method.
+ * Execute a subprocess, returning up to 1024 bytes of output
+ * into @p result.
*
- * If successful, returns #TRUE and appends the address to @p
- * address. If a failure happens, returns #FALSE and
+ * If successful, returns #TRUE and appends the output to @p
+ * result. If a failure happens, returns #FALSE and
* sets an error in @p error.
*
- * @param address a DBusString where the address can be stored
+ * @note It's not an error if the subprocess terminates normally
+ * without writing any data to stdout. Verify the @p result length
+ * before and after this function call to cover this case.
+ *
+ * @param progname initial path to exec
+ * @param argv NULL-terminated list of arguments
+ * @param result a DBusString where the output can be append
* @param error a DBusError to store the error in case of failure
* @returns #TRUE on success, #FALSE if an error happened
*/
-dbus_bool_t
-_dbus_get_autolaunch_address (DBusString *address,
- DBusError *error)
+static dbus_bool_t
+_read_subprocess_line_argv (const char *progpath,
+ char * const *argv,
+ DBusString *result,
+ DBusError *error)
{
- static char *argv[6];
- int address_pipe[2] = { -1, -1 };
+ int result_pipe[2] = { -1, -1 };
int errors_pipe[2] = { -1, -1 };
pid_t pid;
int ret;
@@ -2907,48 +2914,26 @@ _dbus_get_autolaunch_address (DBusString *address,
sigaddset (&new_set, SIGCHLD);
sigprocmask (SIG_BLOCK, &new_set, &old_set);
- if (!_dbus_get_local_machine_uuid_encoded (&uuid))
- {
- _DBUS_SET_OOM (error);
- goto out;
- }
-
- i = 0;
- argv[i] = "dbus-launch";
- ++i;
- argv[i] = "--autolaunch";
- ++i;
- argv[i] = _dbus_string_get_data (&uuid);
- ++i;
- argv[i] = "--binary-syntax";
- ++i;
- argv[i] = "--close-stderr";
- ++i;
- argv[i] = NULL;
- ++i;
-
- _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
-
- orig_len = _dbus_string_get_length (address);
+ orig_len = _dbus_string_get_length (result);
#define READ_END 0
#define WRITE_END 1
- if (pipe (address_pipe) < 0)
+ if (pipe (result_pipe) < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
- "Failed to create a pipe: %s",
- _dbus_strerror (errno));
- _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
- _dbus_strerror (errno));
+ "Failed to create a pipe to call %s: %s",
+ progpath, _dbus_strerror (errno));
+ _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
+ progpath, _dbus_strerror (errno));
goto out;
}
if (pipe (errors_pipe) < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
- "Failed to create a pipe: %s",
- _dbus_strerror (errno));
- _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
- _dbus_strerror (errno));
+ "Failed to create a pipe to call %s: %s",
+ progpath, _dbus_strerror (errno));
+ _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
+ progpath, _dbus_strerror (errno));
goto out;
}
@@ -2956,10 +2941,10 @@ _dbus_get_autolaunch_address (DBusString *address,
if (pid < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
- "Failed to fork(): %s",
- _dbus_strerror (errno));
- _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
- _dbus_strerror (errno));
+ "Failed to fork() to call %s: %s",
+ progpath, _dbus_strerror (errno));
+ _dbus_verbose ("Failed to fork() to call %s: %s\n",
+ progpath, _dbus_strerror (errno));
goto out;
}
@@ -2977,7 +2962,7 @@ _dbus_get_autolaunch_address (DBusString *address,
_dbus_verbose ("/dev/null fd %d opened\n", fd);
/* set-up stdXXX */
- close (address_pipe[READ_END]);
+ close (result_pipe[READ_END]);
close (errors_pipe[READ_END]);
close (0); /* close stdin */
close (1); /* close stdout */
@@ -2985,7 +2970,7 @@ _dbus_get_autolaunch_address (DBusString *address,
if (dup2 (fd, 0) == -1)
_exit (1);
- if (dup2 (address_pipe[WRITE_END], 1) == -1)
+ if (dup2 (result_pipe[WRITE_END], 1) == -1)
_exit (1);
if (dup2 (errors_pipe[WRITE_END], 2) == -1)
_exit (1);
@@ -3002,25 +2987,26 @@ _dbus_get_autolaunch_address (DBusString *address,
sigprocmask(SIG_SETMASK, &old_set, NULL);
- execv (DBUS_BINDIR "/dbus-launch", argv);
-
- /* failed, try searching PATH */
- execvp ("dbus-launch", argv);
+ /* If it looks fully-qualified, try execv first */
+ if (progpath[0] == '/')
+ execv (progpath, argv);
+ else
+ execvp (progpath, argv);
/* still nothing, we failed */
_exit (1);
}
/* parent process */
- close (address_pipe[WRITE_END]);
+ close (result_pipe[WRITE_END]);
close (errors_pipe[WRITE_END]);
- address_pipe[WRITE_END] = -1;
+ result_pipe[WRITE_END] = -1;
errors_pipe[WRITE_END] = -1;
ret = 0;
do
{
- ret = _dbus_read (address_pipe[READ_END], address, 1024);
+ ret = _dbus_read (result_pipe[READ_END], result, 1024);
}
while (ret > 0);
@@ -3033,27 +3019,27 @@ _dbus_get_autolaunch_address (DBusString *address,
/* We succeeded if the process exited with status 0 and
anything was read */
- if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
- _dbus_string_get_length (address) == orig_len)
+ if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
{
/* The process ended with error */
DBusString error_message;
_dbus_string_init (&error_message);
ret = 0;
do
- {
- ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
- }
+ {
+ ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
+ }
while (ret > 0);
- _dbus_string_set_length (address, orig_len);
+ _dbus_string_set_length (result, orig_len);
if (_dbus_string_get_length (&error_message) > 0)
- dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
- "dbus-launch failed to autolaunch D-Bus session: %s",
- _dbus_string_get_data (&error_message));
+ dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
+ "%s terminated abnormally with the following error: %s",
+ progpath, _dbus_string_get_data (&error_message));
else
- dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
- "Failed to execute dbus-launch to autolaunch D-Bus session");
+ dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
+ "%s terminated abnormally without any error message",
+ progpath);
goto out;
}
@@ -3067,15 +3053,73 @@ _dbus_get_autolaunch_address (DBusString *address,
else
_DBUS_ASSERT_ERROR_IS_SET (error);
- if (address_pipe[0] != -1)
- close (address_pipe[0]);
- if (address_pipe[1] != -1)
- close (address_pipe[1]);
+ if (result_pipe[0] != -1)
+ close (result_pipe[0]);
+ if (result_pipe[1] != -1)
+ close (result_pipe[1]);
if (errors_pipe[0] != -1)
close (errors_pipe[0]);
if (errors_pipe[1] != -1)
close (errors_pipe[1]);
+ return retval;
+}
+
+/**
+ * Returns the address of a new session bus.
+ *
+ * If successful, returns #TRUE and appends the address to @p
+ * address. If a failure happens, returns #FALSE and
+ * sets an error in @p error.
+ *
+ * @param address a DBusString where the address can be stored
+ * @param error a DBusError to store the error in case of failure
+ * @returns #TRUE on success, #FALSE if an error happened
+ */
+dbus_bool_t
+_dbus_get_autolaunch_address (DBusString *address,
+ DBusError *error)
+{
+ static char *argv[6];
+ int i;
+ DBusString uuid;
+ dbus_bool_t retval;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ retval = FALSE;
+
+ if (!_dbus_string_init (&uuid))
+ {
+ _DBUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ if (!_dbus_get_local_machine_uuid_encoded (&uuid))
+ {
+ _DBUS_SET_OOM (error);
+ goto out;
+ }
+
+ i = 0;
+ argv[i] = "dbus-launch";
+ ++i;
+ argv[i] = "--autolaunch";
+ ++i;
+ argv[i] = _dbus_string_get_data (&uuid);
+ ++i;
+ argv[i] = "--binary-syntax";
+ ++i;
+ argv[i] = "--close-stderr";
+ ++i;
+ argv[i] = NULL;
+ ++i;
+
+ _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
+
+ retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
+ argv, address, error);
+
+ out:
_dbus_string_free (&uuid);
return retval;
}