* Copyright (C) 2006-2007 Red Hat, Inc.
* Copyright © 2007 Ryan Lortie
*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
#include "gfileicon.h"
#include <glib/gstdio.h>
#include "glibintl.h"
+#include "glib-private.h"
#include "giomodule-priv.h"
#include "gappinfo.h"
#include "gappinfoprivate.h"
static DesktopFileDir *desktop_file_dir_user_config = NULL; /* (owned) */
static DesktopFileDir *desktop_file_dir_user_data = NULL; /* (owned) */
static GMutex desktop_file_dir_lock;
+static const gchar *gio_launch_desktop_path = NULL;
/* Monitor 'changed' signal handler {{{2 */
static void desktop_file_dir_reset (DesktopFileDir *dir);
char *sn_id = NULL;
char **wrapped_argv;
int i;
- gsize j;
- const gchar * const wrapper_argv[] =
- {
- "/bin/sh",
- "-e",
- "-u",
- "-c", "export GIO_LAUNCHED_DESKTOP_FILE_PID=$$; exec \"$@\"",
- "sh", /* argv[0] for sh */
- };
old_uris = dup_uris;
if (!expand_application_parameters (info, exec_line, &dup_uris, &argc, &argv, error))
emit_launch_started (launch_context, info, sn_id);
}
- /* Wrap the @argv in a command which will set the
- * `GIO_LAUNCHED_DESKTOP_FILE_PID` environment variable. We can’t set this
- * in @envp along with `GIO_LAUNCHED_DESKTOP_FILE` because we need to know
- * the PID of the new forked process. We can’t use setenv() between fork()
- * and exec() because we’d rather use posix_spawn() for speed.
- *
- * `sh` should be available on all the platforms that `GDesktopAppInfo`
- * currently supports (since they are all POSIX). If additional platforms
- * need to be supported in future, it will probably have to be replaced
- * with a wrapper program (grep the GLib git history for
- * `gio-launch-desktop` for an example of this which could be
- * resurrected). */
- wrapped_argv = g_new (char *, argc + G_N_ELEMENTS (wrapper_argv) + 1);
-
- for (j = 0; j < G_N_ELEMENTS (wrapper_argv); j++)
- wrapped_argv[j] = g_strdup (wrapper_argv[j]);
+ if (g_once_init_enter (&gio_launch_desktop_path))
+ {
+ const gchar *tmp = NULL;
+ gboolean is_setuid = GLIB_PRIVATE_CALL (g_check_setuid) ();
+
+ /* Allow test suite to specify path to gio-launch-desktop */
+ if (!is_setuid)
+ tmp = g_getenv ("GIO_LAUNCH_DESKTOP");
+
+ /* Allow build system to specify path to gio-launch-desktop */
+ if (tmp == NULL && g_file_test (GIO_LAUNCH_DESKTOP, G_FILE_TEST_IS_EXECUTABLE))
+ tmp = GIO_LAUNCH_DESKTOP;
+
+ /* Fall back on usual searching in $PATH */
+ if (tmp == NULL)
+ tmp = "gio-launch-desktop";
+ g_once_init_leave (&gio_launch_desktop_path, tmp);
+ }
+
+ wrapped_argv = g_new (char *, argc + 2);
+ wrapped_argv[0] = g_strdup (gio_launch_desktop_path);
+
for (i = 0; i < argc; i++)
- wrapped_argv[i + G_N_ELEMENTS (wrapper_argv)] = g_steal_pointer (&argv[i]);
+ wrapped_argv[i + 1] = g_steal_pointer (&argv[i]);
- wrapped_argv[i + G_N_ELEMENTS (wrapper_argv)] = NULL;
+ wrapped_argv[i + 1] = NULL;
g_free (argv);
argv = NULL;
g_task_return_error (task, g_steal_pointer (&error));
g_object_unref (task);
}
- else
+ else if (session_bus)
g_dbus_connection_flush (session_bus,
cancellable,
launch_uris_flush_cb,
g_steal_pointer (&task));
+ else
+ {
+ g_task_return_boolean (task, TRUE);
+ g_clear_object (&task);
+ }
}
g_clear_object (&session_bus);
GAppInfo *app_info;
char *content_type, *scheme_down;
+ g_return_val_if_fail (uri_scheme != NULL && *uri_scheme != '\0', NULL);
+
scheme_down = g_ascii_strdown (uri_scheme, -1);
content_type = g_strdup_printf ("x-scheme-handler/%s", scheme_down);
g_free (scheme_down);