diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index 0b94bd5a0..71422276e 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -77,6 +77,7 @@ GFileReadMoreCallback g_file_new_for_path g_file_new_for_uri g_file_new_for_commandline_arg +g_file_new_for_commandline_arg_and_cwd g_file_new_tmp g_file_parse_name g_file_dup @@ -2962,6 +2963,7 @@ GApplicationCommandLineClass g_application_command_line_get_arguments g_application_command_line_get_cwd g_application_command_line_get_environ +g_application_command_line_create_file_for_arg g_application_command_line_getenv g_application_command_line_get_is_remote g_application_command_line_get_platform_data diff --git a/gio/gapplicationcommandline.c b/gio/gapplicationcommandline.c index f8206cfe1..9b8485444 100644 --- a/gio/gapplicationcommandline.c +++ b/gio/gapplicationcommandline.c @@ -24,6 +24,7 @@ #include "gapplicationcommandline.h" #include "glibintl.h" +#include "gfile.h" #include #include @@ -619,3 +620,34 @@ g_application_command_line_get_platform_data (GApplicationCommandLine *cmdline) else return NULL; } + +/** + * g_application_command_line_create_file_for_arg: + * @cmdline: a #GApplicationCommandLine + * @arg: an argument from @cmdline + * + * Creates a #GFile corresponding to a filename that was given as part + * of the invocation of @cmdline. + * + * This differs from g_file_new_for_commandline_arg() in that it + * resolves relative pathnames using the current working directory of + * the invoking process rather than the local process. + * + * Returns: (transfer full): a new #GFile + * + * Since: 2.36 + **/ +GFile * +g_application_command_line_create_file_for_arg (GApplicationCommandLine *cmdline, + const gchar *arg) +{ + g_return_val_if_fail (arg != NULL, NULL); + + if (cmdline->priv->cwd) + return g_file_new_for_commandline_arg_and_cwd (arg, cmdline->priv->cwd); + + g_warning ("Requested creation of GFile for commandline invocation that did not send cwd. " + "Using cwd of local process to resolve relative path names."); + + return g_file_new_for_commandline_arg (arg); +} diff --git a/gio/gapplicationcommandline.h b/gio/gapplicationcommandline.h index 25def211a..8b6b094ba 100644 --- a/gio/gapplicationcommandline.h +++ b/gio/gapplicationcommandline.h @@ -97,6 +97,10 @@ void g_application_command_line_set_exit_status (GApplic GVariant * g_application_command_line_get_platform_data (GApplicationCommandLine *cmdline); +GLIB_AVAILABLE_IN_2_36 +GFile * g_application_command_line_create_file_for_arg (GApplicationCommandLine *cmdline, + const gchar *arg); + G_END_DECLS #endif /* __G_APPLICATION_COMMAND_LINE_H__ */ diff --git a/gio/gfile.c b/gio/gfile.c index 18be0965c..9130800d3 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -6196,6 +6196,36 @@ has_valid_scheme (const char *uri) return *p == ':'; } +static GFile * +new_for_cmdline_arg (const gchar *arg, + const gchar *cwd) +{ + GFile *file; + char *filename; + + if (g_path_is_absolute (arg)) + return g_file_new_for_path (arg); + + if (has_valid_scheme (arg)) + return g_file_new_for_uri (arg); + + if (cwd == NULL) + { + char *current_dir; + + current_dir = g_get_current_dir (); + filename = g_build_filename (current_dir, arg, NULL); + g_free (current_dir); + } + else + filename = g_build_filename (cwd, arg, NULL); + + file = g_file_new_for_path (filename); + g_free (filename); + + return file; +} + /** * g_file_new_for_commandline_arg: * @arg: a command line string @@ -6212,26 +6242,40 @@ has_valid_scheme (const char *uri) GFile * g_file_new_for_commandline_arg (const char *arg) { - GFile *file; - char *filename; - char *current_dir; - g_return_val_if_fail (arg != NULL, NULL); - if (g_path_is_absolute (arg)) - return g_file_new_for_path (arg); + return new_for_cmdline_arg (arg, NULL); +} - if (has_valid_scheme (arg)) - return g_file_new_for_uri (arg); +/** + * g_file_new_for_commandline_arg_and_cwd: + * @arg: a command line string + * @cwd: the current working directory of the commandline + * + * Creates a #GFile with the given argument from the command line. + * + * This function is similar to g_file_new_for_commandline_arg() except + * that it allows for passing the current working directory as an + * argument instead of using the current working directory of the + * process. + * + * This is useful if the commandline argument was given in a context + * other than the invocation of the current process. + * + * See also g_application_command_line_create_file_for_arg(). + * + * Returns: (transfer full): a new #GFile + * + * Since: 2.36 + **/ +GFile * +g_file_new_for_commandline_arg_and_cwd (const gchar *arg, + const gchar *cwd) +{ + g_return_val_if_fail (arg != NULL, NULL); + g_return_val_if_fail (cwd != NULL, NULL); - current_dir = g_get_current_dir (); - filename = g_build_filename (current_dir, arg, NULL); - g_free (current_dir); - - file = g_file_new_for_path (filename); - g_free (filename); - - return file; + return new_for_cmdline_arg (arg, cwd); } /** diff --git a/gio/gfile.h b/gio/gfile.h index 1a724db6e..8e8b9a311 100644 --- a/gio/gfile.h +++ b/gio/gfile.h @@ -556,6 +556,9 @@ GType g_file_get_type (void) G_GNUC_CONST; GFile * g_file_new_for_path (const char *path); GFile * g_file_new_for_uri (const char *uri); GFile * g_file_new_for_commandline_arg (const char *arg); +GLIB_AVAILABLE_IN_2_36 +GFile * g_file_new_for_commandline_arg_and_cwd (const gchar *arg, + const gchar *cwd); GLIB_AVAILABLE_IN_2_32 GFile * g_file_new_tmp (const char *tmpl, GFileIOStream **iostream, diff --git a/gio/gio.symbols b/gio/gio.symbols index 806f70cb0..d214cd1b3 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -34,6 +34,7 @@ g_application_set_default g_application_set_flags g_application_set_inactivity_timeout g_application_quit +g_application_command_line_create_file_for_arg g_application_command_line_get_arguments g_application_command_line_get_cwd g_application_command_line_get_environ @@ -262,6 +263,7 @@ g_file_get_type g_file_new_for_path g_file_new_for_uri g_file_new_for_commandline_arg +g_file_new_for_commandline_arg_and_cwd g_file_new_tmp g_file_parse_name g_file_dup