mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 11:12:11 +01:00
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.
This commit is contained in:
parent
0981552099
commit
12c411a98e
@ -823,125 +823,6 @@ prepend_terminal_to_vector (int *argc,
|
|||||||
#endif /* G_OS_WIN32 */
|
#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 *
|
static GList *
|
||||||
uri_list_segment_to_files (GList *start,
|
uri_list_segment_to_files (GList *start,
|
||||||
GList *end)
|
GList *end)
|
||||||
@ -960,15 +841,27 @@ uri_list_segment_to_files (GList *start,
|
|||||||
return g_list_reverse (res);
|
return g_list_reverse (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE__NSGETENVIRON
|
typedef struct
|
||||||
#define environ (*_NSGetEnviron())
|
{
|
||||||
#elif !defined(G_OS_WIN32)
|
const char *display;
|
||||||
|
const char *sn_id;
|
||||||
|
} ChildSetupData;
|
||||||
|
|
||||||
/* According to the Single Unix Specification, environ is not in
|
static void
|
||||||
* * any system header, although unistd.h often declares it.
|
child_setup (gpointer user_data)
|
||||||
* */
|
{
|
||||||
extern char **environ;
|
ChildSetupData *data = user_data;
|
||||||
#endif
|
|
||||||
|
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
|
static gboolean
|
||||||
g_desktop_app_info_launch_uris (GAppInfo *appinfo,
|
g_desktop_app_info_launch_uris (GAppInfo *appinfo,
|
||||||
@ -980,16 +873,13 @@ g_desktop_app_info_launch_uris (GAppInfo *appinfo,
|
|||||||
gboolean completed = FALSE;
|
gboolean completed = FALSE;
|
||||||
GList *old_uris;
|
GList *old_uris;
|
||||||
GList *launched_files;
|
GList *launched_files;
|
||||||
char **envp;
|
|
||||||
char **argv;
|
char **argv;
|
||||||
int argc;
|
int argc;
|
||||||
char *display;
|
ChildSetupData data;
|
||||||
char *sn_id;
|
|
||||||
|
|
||||||
g_return_val_if_fail (appinfo != NULL, FALSE);
|
g_return_val_if_fail (appinfo != NULL, FALSE);
|
||||||
|
|
||||||
argv = NULL;
|
argv = NULL;
|
||||||
envp = NULL;
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -1005,70 +895,47 @@ g_desktop_app_info_launch_uris (GAppInfo *appinfo,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sn_id = NULL;
|
data.display = NULL;
|
||||||
|
data.sn_id = NULL;
|
||||||
|
|
||||||
if (launch_context)
|
if (launch_context)
|
||||||
{
|
{
|
||||||
launched_files = uri_list_segment_to_files (old_uris, uris);
|
launched_files = uri_list_segment_to_files (old_uris, uris);
|
||||||
|
|
||||||
display = g_app_launch_context_get_display (launch_context,
|
data.display = g_app_launch_context_get_display (launch_context,
|
||||||
appinfo,
|
appinfo,
|
||||||
launched_files);
|
launched_files);
|
||||||
|
|
||||||
sn_id = NULL;
|
|
||||||
if (info->startup_notify)
|
if (info->startup_notify)
|
||||||
sn_id = g_app_launch_context_get_startup_notify_id (launch_context,
|
data.sn_id = g_app_launch_context_get_startup_notify_id (launch_context,
|
||||||
appinfo,
|
appinfo,
|
||||||
launched_files);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (display);
|
|
||||||
|
|
||||||
g_list_foreach (launched_files, (GFunc)g_object_unref, NULL);
|
g_list_foreach (launched_files, (GFunc)g_object_unref, NULL);
|
||||||
g_list_free (launched_files);
|
g_list_free (launched_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_spawn_async (info->path, /* working directory */
|
if (!g_spawn_async (info->path,
|
||||||
argv,
|
argv,
|
||||||
envp,
|
NULL,
|
||||||
G_SPAWN_SEARCH_PATH /* flags */,
|
G_SPAWN_SEARCH_PATH,
|
||||||
NULL /* child_setup */,
|
child_setup,
|
||||||
NULL /* data */,
|
&data,
|
||||||
NULL /* child_pid */,
|
NULL,
|
||||||
error))
|
error))
|
||||||
{
|
{
|
||||||
if (sn_id)
|
if (data.sn_id)
|
||||||
{
|
g_app_launch_context_launch_failed (launch_context, data.sn_id);
|
||||||
g_app_launch_context_launch_failed (launch_context, sn_id);
|
|
||||||
g_free (sn_id);
|
g_free (data.sn_id);
|
||||||
}
|
g_free (data.display);
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (data.sn_id);
|
||||||
|
g_free (data.display);
|
||||||
|
|
||||||
g_free (sn_id);
|
|
||||||
|
|
||||||
g_strfreev (envp);
|
|
||||||
g_strfreev (argv);
|
g_strfreev (argv);
|
||||||
envp = NULL;
|
|
||||||
argv = NULL;
|
argv = NULL;
|
||||||
}
|
}
|
||||||
while (uris != NULL);
|
while (uris != NULL);
|
||||||
@ -1077,7 +944,6 @@ g_desktop_app_info_launch_uris (GAppInfo *appinfo,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
g_strfreev (argv);
|
g_strfreev (argv);
|
||||||
g_strfreev (envp);
|
|
||||||
|
|
||||||
return completed;
|
return completed;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user