[glib] Make setting DISPLAY work



commit d3d81f74c5c227fb17494c0388ede1e83557a7e1
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jun 10 16:20:51 2009 -0400

    Make setting DISPLAY work
    
    And remove a bunch of grotty code to manipulate an environment
    array at the same time. Instead, simply call setenv in the child_setup
    function.
---
 gio/gdesktopappinfo.c |  232 ++++++++++--------------------------------------
 1 files changed, 49 insertions(+), 183 deletions(-)

diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index fea0761..e2f4d7f 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -823,125 +823,6 @@ prepend_terminal_to_vector (int    *argc,
 #endif /* G_OS_WIN32 */
 }
 
-/* '=' is the new '\0'.
- * DO NOT CALL unless at least one string ends with '='
- */
-static gboolean
-is_env (const char *a,
-	const char *b)
-{
-  while (*a == *b)
-  {
-    if (*a == 0 || *b == 0)
-      return FALSE;
-    
-    if (*a == '=')
-      return TRUE;
-
-    a++;
-    b++;
-  }
-
-  return FALSE;
-}
-
-/* free with g_strfreev */
-static char **
-replace_env_var (char       **old_environ,
-		 const char  *env_var,
-		 const char  *new_value)
-{
-  int length, new_length;
-  int index, new_index;
-  char **new_environ;
-  int i, new_i;
-
-  /* do two things at once:
-   *  - discover the length of the environment ('length')
-   *  - find the location (if any) of the env var ('index')
-   */
-  index = -1;
-  for (length = 0; old_environ[length]; length++)
-    {
-      /* if we already have it in our environment, replace */
-      if (is_env (old_environ[length], env_var))
-	index = length;
-    }
-
-  
-  /* no current env var, no desired env value.
-   * this is easy :)
-   */
-  if (new_value == NULL && index == -1)
-    return old_environ;
-
-  /* in all cases now, we will be using a modified environment.
-   * determine its length and allocated it.
-   * 
-   * after this block:
-   *   new_index   = location to insert, if any
-   *   new_length  = length of the new array
-   *   new_environ = the pointer array for the new environment
-   */
-  
-  if (new_value == NULL && index >= 0)
-    {
-      /* in this case, we will be removing an entry */
-      new_length = length - 1;
-      new_index = -1;
-    }
-  else if (new_value != NULL && index < 0)
-    {
-      /* in this case, we will be adding an entry to the end */
-      new_length = length + 1;
-      new_index = length;
-    }
-  else
-    /* in this case, we will be replacing the existing entry */
-    {
-      new_length = length;
-      new_index = index;
-    }
-
-  new_environ = g_malloc (sizeof (char *) * (new_length + 1));
-  new_environ[new_length] = NULL;
-
-  /* now we do the copying.
-   * for each entry in the new environment, we decide what to do
-   */
-  
-  i = 0;
-  for (new_i = 0; new_i < new_length; new_i++)
-    {
-      if (new_i == new_index)
-	{
-	  /* insert our new item */
-	  new_environ[new_i] = g_strconcat (env_var,
-					    "=",
-					    new_value,
-					    NULL);
-	  
-	  /* if we had an old entry, skip it now */
-	  if (index >= 0)
-	    i++;
-	}
-      else
-	{
-	  /* if this is the old DESKTOP_STARTUP_ID, skip it */
-	  if (i == index)
-	    i++;
-	  
-	  /* copy an old item */
-	  new_environ[new_i] = g_strdup (old_environ[i]);
-	  i++;
-	}
-    }
-
-  g_strfreev (old_environ);
-  
-  return new_environ;
-}
-
 static GList *
 uri_list_segment_to_files (GList *start,
 			   GList *end)
@@ -960,15 +841,27 @@ uri_list_segment_to_files (GList *start,
   return g_list_reverse (res);
 }
 
-#ifdef HAVE__NSGETENVIRON
-#define environ (*_NSGetEnviron())
-#elif !defined(G_OS_WIN32)
+typedef struct
+{
+  const char *display;
+  const char *sn_id;
+} ChildSetupData;
 
-/* According to the Single Unix Specification, environ is not in 
- *  * any system header, although unistd.h often declares it.
- *   */
-extern char **environ;
-#endif
+static void
+child_setup (gpointer user_data)
+{
+  ChildSetupData *data = user_data;
+
+  if (data->display)
+    g_setenv ("DISPLAY", data->display, TRUE);
+  else
+    g_unsetenv ("DISPLAY");
+
+  if (data->sn_id)
+    g_setenv ("DESKTOP_STARTUP_ID", data->sn_id, TRUE);
+  else
+    g_unsetenv ("DESKTOP_STARTUP_ID");
+}
 
 static gboolean
 g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
@@ -980,18 +873,15 @@ g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
   gboolean completed = FALSE;
   GList *old_uris;
   GList *launched_files;
-  char **envp;
   char **argv;
   int argc;
-  char *display;
-  char *sn_id;
+  ChildSetupData data;
 
   g_return_val_if_fail (appinfo != NULL, FALSE);
 
   argv = NULL;
-  envp = NULL;
-      
-  do 
+
+  do
     {
       old_uris = uris;
       if (!expand_application_parameters (info, &uris,
@@ -1005,70 +895,47 @@ g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
 	  goto out;
 	}
 
-      sn_id = NULL;
+      data.display = NULL;
+      data.sn_id = NULL;
+
       if (launch_context)
 	{
 	  launched_files = uri_list_segment_to_files (old_uris, uris);
-	  
-	  display = g_app_launch_context_get_display (launch_context,
-						      appinfo,
-						      launched_files);
 
-	  sn_id = NULL;
-	  if (info->startup_notify)
-	    sn_id = g_app_launch_context_get_startup_notify_id (launch_context,
-								appinfo,
-								launched_files);
-	  
-	  if (display || sn_id)
-	    {
-#ifdef G_OS_WIN32
-	      /* FIXME */
-	      envp = g_new0 (char *, 1);
-#else
-	      envp = g_strdupv (environ);
-#endif
-	      
-	      if (display)
-		envp = replace_env_var (envp,
-					"DISPLAY",
-					display);
-	      
-	      if (sn_id)
-		envp = replace_env_var (envp,
-					"DESKTOP_STARTUP_ID",
-					sn_id);
-	    }
+	  data.display = g_app_launch_context_get_display (launch_context,
+						           appinfo,
+						           launched_files);
 
-	  g_free (display);
-	  
+	  if (info->startup_notify)
+	    data.sn_id = g_app_launch_context_get_startup_notify_id (launch_context,
+								     appinfo,
+								     launched_files);
 	  g_list_foreach (launched_files, (GFunc)g_object_unref, NULL);
 	  g_list_free (launched_files);
 	}
-      
-      if (!g_spawn_async (info->path,  /* working directory */
+
+      if (!g_spawn_async (info->path,
 			  argv,
-			  envp,
-			  G_SPAWN_SEARCH_PATH /* flags */,
-			  NULL /* child_setup */,
-			  NULL /* data */,
-			  NULL /* child_pid */,
+			  NULL,
+			  G_SPAWN_SEARCH_PATH,
+			  child_setup,
+			  &data,
+			  NULL,
 			  error))
 	{
-	  if (sn_id)
-	    {
-	      g_app_launch_context_launch_failed (launch_context, sn_id);
-	      g_free (sn_id);
-	    }
+	  if (data.sn_id)
+	    g_app_launch_context_launch_failed (launch_context, data.sn_id);
+
+	  g_free (data.sn_id);
+	  g_free (data.display);
+
 	  goto out;
 	}
 
-      
-      g_free (sn_id);
-      
-      g_strfreev (envp);
+      g_free (data.sn_id);
+      g_free (data.display);
+
       g_strfreev (argv);
-      envp = NULL;
       argv = NULL;
     }
   while (uris != NULL);
@@ -1077,7 +944,6 @@ g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
 
  out:
   g_strfreev (argv);
-  g_strfreev (envp);
 
   return completed;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]