mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 11:26:16 +01:00
desktop-app-info: Use launch context PATH and desktop Path to find terminals
We used to launch applications with terminals using the normal program finder logic that did not consider the context path nor the desktop file working dir. Switch to g_find_program_for_path() to find terminals so we can ensure that both conditions are true. Update tests to consider this case too.
This commit is contained in:
parent
e41e3dc601
commit
da8aa0b66d
@ -1864,6 +1864,7 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
|
||||
if (try_exec && try_exec[0] != '\0')
|
||||
{
|
||||
char *t;
|
||||
/* Use the desktop file path (if any) as working dir to search program */
|
||||
t = g_find_program_for_path (try_exec, NULL, path);
|
||||
if (t == NULL)
|
||||
{
|
||||
@ -1896,6 +1897,7 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
|
||||
/* Since @exec is not an empty string, there must be at least one
|
||||
* argument, so dereferencing argv[0] should return non-NULL. */
|
||||
g_assert (argc > 0);
|
||||
/* Use the desktop file path (if any) as working dir to search program */
|
||||
t = g_find_program_for_path (argv[0], NULL, path);
|
||||
g_strfreev (argv);
|
||||
|
||||
@ -2631,8 +2633,10 @@ expand_application_parameters (GDesktopAppInfo *info,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
prepend_terminal_to_vector (int *argc,
|
||||
char ***argv)
|
||||
prepend_terminal_to_vector (int *argc,
|
||||
char ***argv,
|
||||
const char *path,
|
||||
const char *working_dir)
|
||||
{
|
||||
#ifndef G_OS_WIN32
|
||||
char **real_argv;
|
||||
@ -2678,7 +2682,8 @@ prepend_terminal_to_vector (int *argc,
|
||||
|
||||
for (i = 0, found_terminal = NULL; i < G_N_ELEMENTS (known_terminals); i++)
|
||||
{
|
||||
found_terminal = g_find_program_in_path (known_terminals[i].exec);
|
||||
found_terminal = g_find_program_for_path (known_terminals[i].exec,
|
||||
path, working_dir);
|
||||
if (found_terminal != NULL)
|
||||
{
|
||||
term_arg = known_terminals[i].exec_arg;
|
||||
@ -2880,7 +2885,9 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
|
||||
launched_uris = g_list_prepend (launched_uris, iter->data);
|
||||
launched_uris = g_list_reverse (launched_uris);
|
||||
|
||||
if (info->terminal && !prepend_terminal_to_vector (&argc, &argv))
|
||||
if (info->terminal && !prepend_terminal_to_vector (&argc, &argv,
|
||||
g_environ_getenv (envp, "PATH"),
|
||||
info->path))
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
_("Unable to find terminal required for application"));
|
||||
|
@ -1369,6 +1369,17 @@ get_terminal_divider (const char *terminal_name)
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
TERMINAL_LAUNCH_TYPE_COMMAND_LINE_WITH_PATH_OVERRIDE,
|
||||
TERMINAL_LAUNCH_TYPE_COMMAND_LINE_WITH_CONTEXT,
|
||||
TERMINAL_LAUNCH_TYPE_KEY_FILE_WITH_PATH,
|
||||
} TerminalLaunchType;
|
||||
|
||||
typedef struct {
|
||||
const char *exec;
|
||||
TerminalLaunchType type;
|
||||
} TerminalLaunchData;
|
||||
|
||||
static void
|
||||
test_launch_uris_with_terminal (gconstpointer data)
|
||||
{
|
||||
@ -1376,8 +1387,9 @@ test_launch_uris_with_terminal (gconstpointer data)
|
||||
int ret;
|
||||
int flags;
|
||||
int terminal_divider_arg_length;
|
||||
const char *terminal_exec = data;
|
||||
char *old_path;
|
||||
const TerminalLaunchData *launch_data = data;
|
||||
const char *terminal_exec = launch_data->exec;
|
||||
char *old_path = NULL;
|
||||
char *command_line;
|
||||
char *bin_path;
|
||||
char *terminal_path;
|
||||
@ -1392,6 +1404,7 @@ test_launch_uris_with_terminal (gconstpointer data)
|
||||
GError *error = NULL;
|
||||
GInputStream *input_stream;
|
||||
GDataInputStream *data_input_stream;
|
||||
GAppLaunchContext *launch_context;
|
||||
|
||||
sh = g_find_program_in_path ("sh");
|
||||
g_assert_nonnull (sh);
|
||||
@ -1399,26 +1412,40 @@ test_launch_uris_with_terminal (gconstpointer data)
|
||||
bin_path = g_dir_make_tmp ("bin-path-XXXXXX", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
old_path = g_strdup (g_getenv ("PATH"));
|
||||
g_assert_true (g_setenv ("PATH", bin_path, TRUE));
|
||||
launch_context = g_object_new (test_launch_context_get_type (), NULL);
|
||||
|
||||
switch (launch_data->type)
|
||||
{
|
||||
case TERMINAL_LAUNCH_TYPE_COMMAND_LINE_WITH_PATH_OVERRIDE:
|
||||
old_path = g_strdup (g_getenv ("PATH"));
|
||||
g_assert_true (g_setenv ("PATH", bin_path, TRUE));
|
||||
break;
|
||||
|
||||
case TERMINAL_LAUNCH_TYPE_COMMAND_LINE_WITH_CONTEXT:
|
||||
g_app_launch_context_setenv (launch_context, "PATH", bin_path);
|
||||
break;
|
||||
|
||||
case TERMINAL_LAUNCH_TYPE_KEY_FILE_WITH_PATH:
|
||||
g_app_launch_context_setenv (launch_context, "PATH", "/not/valid");
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
terminal_path = g_build_filename (bin_path, terminal_exec, NULL);
|
||||
output_fd_path = g_build_filename (bin_path, "fifo", NULL);
|
||||
|
||||
ret = mkfifo (output_fd_path, 0600);
|
||||
|
||||
g_assert_cmpint (ret, ==, 0);
|
||||
|
||||
fd = g_open (output_fd_path, O_RDONLY | O_CLOEXEC | O_NONBLOCK, 0);
|
||||
|
||||
g_assert_cmpint (fd, >=, 0);
|
||||
|
||||
flags = fcntl (fd, F_GETFL);
|
||||
|
||||
g_assert_cmpint (flags, >=, 0);
|
||||
|
||||
ret = fcntl (fd, F_SETFL, flags & ~O_NONBLOCK);
|
||||
|
||||
g_assert_cmpint (ret, ==, 0);
|
||||
|
||||
input_stream = g_unix_input_stream_new (fd, TRUE);
|
||||
@ -1435,12 +1462,43 @@ test_launch_uris_with_terminal (gconstpointer data)
|
||||
g_test_message ("Fake '%s' terminal created as: %s", terminal_exec, terminal_path);
|
||||
|
||||
command_line = g_strdup_printf ("true %s-argument", terminal_exec);
|
||||
app_info = g_app_info_create_from_commandline (command_line,
|
||||
"Test App on Terminal",
|
||||
G_APP_INFO_CREATE_NEEDS_TERMINAL |
|
||||
G_APP_INFO_CREATE_SUPPORTS_URIS,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
if (launch_data->type == TERMINAL_LAUNCH_TYPE_KEY_FILE_WITH_PATH)
|
||||
{
|
||||
GKeyFile *key_file;
|
||||
char *key_file_contents;
|
||||
const char base_file[] =
|
||||
"[Desktop Entry]\n"
|
||||
"Type=Application\n"
|
||||
"Name=terminal launched app\n"
|
||||
"Terminal=true\n"
|
||||
"Path=%s\n"
|
||||
"Exec=%s\n";
|
||||
|
||||
key_file = g_key_file_new ();
|
||||
key_file_contents = g_strdup_printf (base_file, bin_path, command_line);
|
||||
|
||||
g_assert_true (
|
||||
g_key_file_load_from_data (key_file, key_file_contents, -1,
|
||||
G_KEY_FILE_NONE, NULL));
|
||||
|
||||
app_info = (GAppInfo*) g_desktop_app_info_new_from_keyfile (key_file);
|
||||
g_assert_true (G_IS_DESKTOP_APP_INFO (app_info));
|
||||
g_assert_true (
|
||||
g_desktop_app_info_get_boolean (G_DESKTOP_APP_INFO (app_info), "Terminal"));
|
||||
|
||||
g_key_file_unref (key_file);
|
||||
g_free (key_file_contents);
|
||||
}
|
||||
else
|
||||
{
|
||||
app_info = g_app_info_create_from_commandline (command_line,
|
||||
"Test App on Terminal",
|
||||
G_APP_INFO_CREATE_NEEDS_TERMINAL |
|
||||
G_APP_INFO_CREATE_SUPPORTS_URIS,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
}
|
||||
|
||||
paths = g_list_prepend (NULL, bin_path);
|
||||
uris = g_list_prepend (NULL, g_filename_to_uri (bin_path, NULL, &error));
|
||||
@ -1451,7 +1509,7 @@ test_launch_uris_with_terminal (gconstpointer data)
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_cmpint (g_list_length (paths), ==, 2);
|
||||
g_app_info_launch_uris (app_info, uris, NULL, &error);
|
||||
g_app_info_launch_uris (app_info, uris, launch_context, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
while (output_contents == NULL)
|
||||
@ -1523,7 +1581,9 @@ test_launch_uris_with_terminal (gconstpointer data)
|
||||
g_clear_pointer (&output_args, g_strfreev);
|
||||
|
||||
g_assert_null (paths);
|
||||
g_assert_true (g_setenv ("PATH", old_path, TRUE));
|
||||
|
||||
if (launch_data->type == TERMINAL_LAUNCH_TYPE_COMMAND_LINE_WITH_PATH_OVERRIDE)
|
||||
g_assert_true (g_setenv ("PATH", old_path, TRUE));
|
||||
|
||||
g_close (fd, &error);
|
||||
g_assert_no_error (error);
|
||||
@ -1540,6 +1600,7 @@ test_launch_uris_with_terminal (gconstpointer data)
|
||||
g_clear_object (&data_input_stream);
|
||||
g_clear_object (&input_stream);
|
||||
g_clear_object (&app_info);
|
||||
g_clear_object (&launch_context);
|
||||
g_clear_error (&error);
|
||||
g_clear_list (&paths, NULL);
|
||||
g_clear_list (&uris, g_free);
|
||||
@ -1685,12 +1746,30 @@ main (int argc,
|
||||
{
|
||||
char *path;
|
||||
|
||||
path = g_strdup_printf ("/desktop-app-info/launch-uris-with-terminal/%s",
|
||||
path = g_strdup_printf ("/desktop-app-info/launch-uris-with-terminal/with-path/%s",
|
||||
supported_terminals[i]);
|
||||
g_test_add_data_func (path, supported_terminals[i],
|
||||
test_launch_uris_with_terminal);
|
||||
g_test_add_data_func (path, &(TerminalLaunchData) {
|
||||
.exec = supported_terminals[i],
|
||||
.type = TERMINAL_LAUNCH_TYPE_COMMAND_LINE_WITH_PATH_OVERRIDE,
|
||||
}, test_launch_uris_with_terminal);
|
||||
|
||||
g_free (path);
|
||||
|
||||
path = g_strdup_printf ("/desktop-app-info/launch-uris-with-terminal/with-context/%s",
|
||||
supported_terminals[i]);
|
||||
g_test_add_data_func (path, &(TerminalLaunchData) {
|
||||
.exec = supported_terminals[i],
|
||||
.type = TERMINAL_LAUNCH_TYPE_COMMAND_LINE_WITH_CONTEXT,
|
||||
}, test_launch_uris_with_terminal);
|
||||
g_clear_pointer (&path, g_free);
|
||||
|
||||
path = g_strdup_printf ("/desktop-app-info/launch-uris-with-terminal/with-desktop-path/%s",
|
||||
supported_terminals[i]);
|
||||
g_test_add_data_func (path, &(TerminalLaunchData) {
|
||||
.exec = supported_terminals[i],
|
||||
.type = TERMINAL_LAUNCH_TYPE_KEY_FILE_WITH_PATH,
|
||||
}, test_launch_uris_with_terminal);
|
||||
g_clear_pointer (&path, g_free);
|
||||
}
|
||||
|
||||
g_test_add_func ("/desktop-app-info/launch-uris-with-terminal/invalid-glib-terminal",
|
||||
|
Loading…
Reference in New Issue
Block a user