[Xfce4-commits] <xfce-utils:master> Send the caller environ over dbus (bug #6927).

Nick Schermer noreply at xfce.org
Thu Dec 9 19:44:01 CET 2010


Updating branch refs/heads/master
         to 32f1bfe2576a2101551d767325e1a1c8f56f1a32 (commit)
       from fbe7802440b70f0513d238a850799f3a94dda3db (commit)

commit 32f1bfe2576a2101551d767325e1a1c8f56f1a32
Author: Nick Schermer <nick at xfce.org>
Date:   Thu Dec 9 19:40:11 2010 +0100

    Send the caller environ over dbus (bug #6927).
    
    The daemon lacks a complete environment because it runs under
    dbus, which is started before the reset of the desktop. So
    send the environment of the caller over dbus and use it for
    spawning the command.

 configure.in.in      |    5 +++--
 xfrun/xfrun-dbus.c   |   20 ++++++++++++++++++++
 xfrun/xfrun-dialog.c |   14 +++++++++++++-
 xfrun/xfrun-dialog.h |    3 +++
 4 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/configure.in.in b/configure.in.in
index 2597284..a349451 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -44,8 +44,9 @@ AC_C_INLINE
 
 dnl Check for standard header files
 AC_HEADER_STDC
-AC_CHECK_HEADERS([errno.h unistd.h string.h stdlib.h])
-AC_CHECK_FUNCS([daemon setsid])
+AC_CHECK_HEADERS([errno.h unistd.h string.h stdlib.h crt_externs.h])
+AC_CHECK_FUNCS([daemon setsid _NSGetEnviron])
+AC_CHECK_DECLS([environ])
 
 dnl Check for X11 installed
 XDT_CHECK_LIBX11_REQUIRE
diff --git a/xfrun/xfrun-dbus.c b/xfrun/xfrun-dbus.c
index 2aa751c..06ee12d 100644
--- a/xfrun/xfrun-dbus.c
+++ b/xfrun/xfrun-dbus.c
@@ -35,6 +35,9 @@
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
+#ifdef HAVE_CRT_EXTERNS_H
+#include <crt_externs.h> /* for _NSGetEnviron */
+#endif
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -51,6 +54,14 @@
 
 #include "xfrun-dialog.h"
 
+#ifdef HAVE__NSGETENVIRON
+/* for support under apple/darwin */
+#define environ (*_NSGetEnviron())
+#elif !HAVE_DECL_ENVIRON
+/* try extern if environ is not defined in unistd.h */
+extern gchar **environ;
+#endif
+
 /**
  * method: org.xfce.RunDialog.OpenDialog
  * param:  display_name (DBUS_TYPE_STRING)
@@ -123,12 +134,15 @@ xfrun_handle_dbus_message(DBusConnection *connection,
         DBusMessage *reply = NULL;
         DBusError derror;
         gchar *display_name = NULL, *cwd = NULL;
+        gchar **envp = NULL;
+        gint n_envp;
 
         dbus_error_init(&derror);
 
         if(!dbus_message_get_args(message, &derror,
                                   DBUS_TYPE_STRING, &display_name,
                                   DBUS_TYPE_STRING, &cwd,
+                                  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &envp, &n_envp,
                                   DBUS_TYPE_INVALID))
         {
             reply = dbus_message_new_error(message, RUNDIALOG_DBUS_ERROR_GENERAL,
@@ -154,10 +168,13 @@ xfrun_handle_dbus_message(DBusConnection *connection,
                                                       TRUE);
                     xfrun_dialog_set_working_directory(XFRUN_DIALOG(dialog),
                                                        cwd);
+                    xfrun_dialog_set_environment(XFRUN_DIALOG(dialog), envp);
                 } else {
                     dialog = static_dialog;
                     xfrun_dialog_set_working_directory(XFRUN_DIALOG(dialog),
                                                        cwd);
+                    xfrun_dialog_set_environment(XFRUN_DIALOG(dialog), envp);
+
                     if(GTK_WIDGET_REALIZED(dialog)) {
                         gdk_x11_window_set_user_time(dialog->window,
                                                      gdk_x11_get_server_time(dialog->window));
@@ -243,6 +260,7 @@ xfrun_show_dialog(void)
     DBusMessage *result;
     DBusError derror;
     gchar *cwd, *display_name;
+    gchar **envp = (gchar **) environ;
 
     dbus_error_init(&derror);
     connection = dbus_bus_get(DBUS_BUS_SESSION, &derror);
@@ -263,6 +281,8 @@ xfrun_show_dialog(void)
     dbus_message_append_args(method,
                              DBUS_TYPE_STRING, &display_name,
                              DBUS_TYPE_STRING, &cwd,
+                             DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &envp,
+                                 envp ? g_strv_length(envp) : 0,
                              DBUS_TYPE_INVALID);
 
     g_free(display_name);
diff --git a/xfrun/xfrun-dialog.c b/xfrun/xfrun-dialog.c
index 30af751..9818286 100644
--- a/xfrun/xfrun-dialog.c
+++ b/xfrun/xfrun-dialog.c
@@ -53,6 +53,7 @@ struct _XfrunDialogPrivate
 
     gboolean destroy_on_close;
     gchar *working_directory;
+    gchar **envp;
 
     gchar *entry_val_tmp;
 };
@@ -257,6 +258,7 @@ xfrun_dialog_finalize(GObject *object)
 
     g_free(dialog->priv->working_directory);
     g_free(dialog->priv->entry_val_tmp);
+    g_strfreev(dialog->priv->envp);
 
     if(dialog->priv->completion_model)
         g_object_unref(G_OBJECT(dialog->priv->completion_model));
@@ -524,7 +526,7 @@ xfrun_run_clicked(GtkWidget *widget,
 
     result = (argv && gdk_spawn_on_screen(gscreen,
                                           dialog->priv->working_directory,
-                                          argv, NULL, G_SPAWN_SEARCH_PATH,
+                                          argv, dialog->priv->envp, G_SPAWN_SEARCH_PATH,
                                           xfrun_spawn_child_setup, NULL, NULL,
                                           &error));
 
@@ -690,6 +692,16 @@ xfrun_dialog_get_working_directory(XfrunDialog *dialog)
 }
 
 void
+xfrun_dialog_set_environment(XfrunDialog *dialog,
+                             gchar **envp)
+{
+    g_return_if_fail(XFRUN_IS_DIALOG(dialog));
+
+    g_strfreev(dialog->priv->envp);
+    dialog->priv->envp = g_strdupv(envp);
+}
+
+void
 xfrun_dialog_select_text(XfrunDialog *dialog)
 {
     gtk_editable_select_region(GTK_EDITABLE(XFRUN_DIALOG(dialog)->priv->entry),
diff --git a/xfrun/xfrun-dialog.h b/xfrun/xfrun-dialog.h
index 160234c..bfb4fa4 100644
--- a/xfrun/xfrun-dialog.h
+++ b/xfrun/xfrun-dialog.h
@@ -62,6 +62,9 @@ gboolean xfrun_dialog_get_destroy_on_close         (XfrunDialog *dialog);
 void xfrun_dialog_set_working_directory            (XfrunDialog *dialog,
                                                     const gchar *working_directory);
 
+void xfrun_dialog_set_environment                  (XfrunDialog *dialog,
+                                                    gchar **envp);
+
 void xfrun_dialog_select_text                      (XfrunDialog *dialog);
 
 G_CONST_RETURN gchar *xfrun_dialog_get_working_directory



More information about the Xfce4-commits mailing list