Convert external links to markdown syntax
[platform/upstream/glib.git] / gio / gapplicationcommandline.c
1 /*
2  * Copyright © 2010 Codethink Limited
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * licence or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  *
17  * Authors: Ryan Lortie <desrt@desrt.ca>
18  */
19
20 #include "config.h"
21
22 #include "gapplicationcommandline.h"
23
24 #include "glibintl.h"
25 #include "gfile.h"
26
27 #include <string.h>
28 #include <stdio.h>
29
30 #ifdef G_OS_UNIX
31 #include "gunixinputstream.h"
32 #endif
33
34 #ifdef G_OS_WIN32
35 #include <windows.h>
36 #undef environ
37 #include "gwin32inputstream.h"
38 #endif
39
40 /**
41  * SECTION:gapplicationcommandline
42  * @title: GApplicationCommandLine
43  * @short_description: A command-line invocation of an application
44  * @include: gio/gio.h
45  * @see_also: #GApplication
46  *
47  * #GApplicationCommandLine represents a command-line invocation of
48  * an application.  It is created by #GApplication and emitted
49  * in the #GApplication::command-line signal and virtual function.
50  *
51  * The class contains the list of arguments that the program was invoked
52  * with.  It is also possible to query if the commandline invocation was
53  * local (ie: the current process is running in direct response to the
54  * invocation) or remote (ie: some other process forwarded the
55  * commandline to this process).
56  *
57  * The GApplicationCommandLine object can provide the @argc and @argv
58  * parameters for use with the #GOptionContext command-line parsing API,
59  * with the g_application_command_line_get_arguments() function. See
60  * <xref linkend="gapplication-example-cmdline3"/> for an example.
61  *
62  * The exit status of the originally-invoked process may be set and
63  * messages can be printed to stdout or stderr of that process.  The
64  * lifecycle of the originally-invoked process is tied to the lifecycle
65  * of this object (ie: the process exits when the last reference is
66  * dropped).
67  *
68  * The main use for #GApplicationCommandLine (and the
69  * #GApplication::command-line signal) is 'Emacs server' like use cases:
70  * You can set the `EDITOR` environment variable to have e.g. git use
71  * your favourite editor to edit commit messages, and if you already
72  * have an instance of the editor running, the editing will happen
73  * in the running instance, instead of opening a new one. An important
74  * aspect of this use case is that the process that gets started by git
75  * does not return until the editing is done.
76  *
77  * Normally, the commandline is completely handled in the
78  * #GApplication::command-line handler. The launching instance exits
79  * once the signal handler in the primary instance has returned, and
80  * the return value of the signal handler becomes the exit status
81  * of the launching instance.
82  * |[<!-- language="C" -->
83  * static int
84  * command_line (GApplication            *application,
85  *               GApplicationCommandLine *cmdline)
86  * {
87  *   gchar **argv;
88  *   gint argc;
89  *   gint i;
90  *
91  *   argv = g_application_command_line_get_arguments (cmdline, &argc);
92  *
93  *   g_application_command_line_print (cmdline,
94  *                                     "This text is written back\n"
95  *                                     "to stdout of the caller\n");
96  *
97  *   for (i = 0; i < argc; i++)
98  *     g_print ("argument %d: %s\n", i, argv[i]);
99  *
100  *   g_strfreev (argv);
101  *
102  *   return 0;
103  * }
104  * ]|
105  * The complete example can be found here: 
106  * [gapplication-example-cmdline.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline.c)
107  *
108  * In more complicated cases, the handling of the comandline can be
109  * split between the launcher and the primary instance.
110  * |[<!-- language="C" -->
111  * static gboolean
112  *  test_local_cmdline (GApplication   *application,
113  *                      gchar        ***arguments,
114  *                      gint           *exit_status)
115  * {
116  *   gint i, j;
117  *   gchar **argv;
118  *
119  *   argv = *arguments;
120  *
121  *   i = 1;
122  *   while (argv[i])
123  *     {
124  *       if (g_str_has_prefix (argv[i], "--local-"))
125  *         {
126  *           g_print ("handling argument %s locally\n", argv[i]);
127  *           g_free (argv[i]);
128  *           for (j = i; argv[j]; j++)
129  *             argv[j] = argv[j + 1];
130  *         }
131  *       else
132  *         {
133  *           g_print ("not handling argument %s locally\n", argv[i]);
134  *           i++;
135  *         }
136  *     }
137  *
138  *   *exit_status = 0;
139  *
140  *   return FALSE;
141  * }
142  *
143  * static void
144  * test_application_class_init (TestApplicationClass *class)
145  * {
146  *   G_APPLICATION_CLASS (class)->local_command_line = test_local_cmdline;
147  *
148  *   ...
149  * }
150  * ]|
151  * In this example of split commandline handling, options that start
152  * with <literal>--local-</literal> are handled locally, all other
153  * options are passed to the #GApplication::command-line handler
154  * which runs in the primary instance.
155  *
156  * The complete example can be found here:
157  * [gapplication-example-cmdline2.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline2.c)
158  *
159  * If handling the commandline requires a lot of work, it may
160  * be better to defer it.
161  * |[<!-- language="C" -->
162  * static gboolean
163  * my_cmdline_handler (gpointer data)
164  * {
165  *   GApplicationCommandLine *cmdline = data;
166  *
167  *   /&ast; do the heavy lifting in an idle &ast;/
168  *
169  *   g_application_command_line_set_exit_status (cmdline, 0);
170  *   g_object_unref (cmdline); /&ast; this releases the application &ast;/
171  *
172  *   return G_SOURCE_REMOVE;
173  * }
174  *
175  * static int
176  * command_line (GApplication            *application,
177  *               GApplicationCommandLine *cmdline)
178  * {
179  *   /&ast; keep the application running until we are done with this commandline &ast;/
180  *   g_application_hold (application);
181  *
182  *   g_object_set_data_full (G_OBJECT (cmdline),
183  *                           "application", application,
184  *                           (GDestroyNotify)g_application_release);
185  *
186  *   g_object_ref (cmdline);
187  *   g_idle_add (my_cmdline_handler, cmdline);
188  *
189  *   return 0;
190  * }
191  * ]|
192  * In this example the commandline is not completely handled before
193  * the #GApplication::command-line handler returns. Instead, we keep
194  * a reference to the #GApplicationCommandLine object and handle it
195  * later (in this example, in an idle). Note that it is necessary to
196  * hold the application until you are done with the commandline.
197  *
198  * The complete example can be found here:
199  * [gapplication-example-cmdline3.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-cmdline3.c)
200  */
201
202 /**
203  * GApplicationCommandLineClass:
204  *
205  * The #GApplicationCommandLineClass-struct 
206  * contains private data only.
207  *
208  * Since: 2.28
209  **/
210 enum
211 {
212   PROP_NONE,
213   PROP_ARGUMENTS,
214   PROP_PLATFORM_DATA,
215   PROP_IS_REMOTE
216 };
217
218 struct _GApplicationCommandLinePrivate
219 {
220   GVariant *platform_data;
221   GVariant *arguments;
222   gchar *cwd;
223
224   gchar **environ;
225   gint exit_status;
226 };
227
228 G_DEFINE_TYPE_WITH_PRIVATE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT)
229
230 /* All subclasses represent remote invocations of some kind. */
231 #define IS_REMOTE(cmdline) (G_TYPE_FROM_INSTANCE (cmdline) != \
232                             G_TYPE_APPLICATION_COMMAND_LINE)
233
234 static void
235 grok_platform_data (GApplicationCommandLine *cmdline)
236 {
237   GVariantIter iter;
238   const gchar *key;
239   GVariant *value;
240
241   g_variant_iter_init (&iter, cmdline->priv->platform_data);
242
243   while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
244     if (strcmp (key, "cwd") == 0)
245       {
246         if (!cmdline->priv->cwd)
247           cmdline->priv->cwd = g_variant_dup_bytestring (value, NULL);
248       }
249
250     else if (strcmp (key, "environ") == 0)
251       {
252         if (!cmdline->priv->environ)
253           cmdline->priv->environ =
254             g_variant_dup_bytestring_array (value, NULL);
255       }
256 }
257
258 static void
259 g_application_command_line_real_print_literal (GApplicationCommandLine *cmdline,
260                                                const gchar             *message)
261 {
262   g_print ("%s", message);
263 }
264
265 static void
266 g_application_command_line_real_printerr_literal (GApplicationCommandLine *cmdline,
267                                                   const gchar             *message)
268 {
269   g_printerr ("%s", message);
270 }
271
272 static GInputStream *
273 g_application_command_line_real_get_stdin (GApplicationCommandLine *cmdline)
274 {
275 #ifdef G_OS_UNIX
276   return g_unix_input_stream_new (0, FALSE);
277 #else
278   return g_win32_input_stream_new (GetStdHandle (STD_INPUT_HANDLE), FALSE);
279 #endif
280 }
281
282 static void
283 g_application_command_line_get_property (GObject    *object,
284                                          guint       prop_id,
285                                          GValue     *value,
286                                          GParamSpec *pspec)
287 {
288   GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
289
290   switch (prop_id)
291     {
292     case PROP_ARGUMENTS:
293       g_value_set_variant (value, cmdline->priv->arguments);
294       break;
295
296     case PROP_PLATFORM_DATA:
297       g_value_set_variant (value, cmdline->priv->platform_data);
298       break;
299
300     case PROP_IS_REMOTE:
301       g_value_set_boolean (value, IS_REMOTE (cmdline));
302       break;
303
304     default:
305       g_assert_not_reached ();
306     }
307 }
308
309 static void
310 g_application_command_line_set_property (GObject      *object,
311                                          guint         prop_id,
312                                          const GValue *value,
313                                          GParamSpec   *pspec)
314 {
315   GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
316
317   switch (prop_id)
318     {
319     case PROP_ARGUMENTS:
320       g_assert (cmdline->priv->arguments == NULL);
321       cmdline->priv->arguments = g_value_dup_variant (value);
322       break;
323
324     case PROP_PLATFORM_DATA:
325       g_assert (cmdline->priv->platform_data == NULL);
326       cmdline->priv->platform_data = g_value_dup_variant (value);
327       if (cmdline->priv->platform_data != NULL)
328         grok_platform_data (cmdline);
329       break;
330
331     default:
332       g_assert_not_reached ();
333     }
334 }
335
336 static void
337 g_application_command_line_finalize (GObject *object)
338 {
339   GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
340
341   if (cmdline->priv->platform_data)
342     g_variant_unref (cmdline->priv->platform_data);
343   if (cmdline->priv->arguments)
344     g_variant_unref (cmdline->priv->arguments);
345
346   g_free (cmdline->priv->cwd);
347   g_strfreev (cmdline->priv->environ);
348
349   G_OBJECT_CLASS (g_application_command_line_parent_class)
350     ->finalize (object);
351 }
352
353 static void
354 g_application_command_line_init (GApplicationCommandLine *cmdline)
355 {
356   cmdline->priv = g_application_command_line_get_instance_private (cmdline);
357 }
358
359 static void
360 g_application_command_line_constructed (GObject *object)
361 {
362   GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
363
364   if (IS_REMOTE (cmdline))
365     return;
366
367   /* In the local case, set cmd and environ */
368   if (!cmdline->priv->cwd)
369     cmdline->priv->cwd = g_get_current_dir ();
370
371   if (!cmdline->priv->environ)
372     cmdline->priv->environ = g_get_environ ();
373 }
374
375 static void
376 g_application_command_line_class_init (GApplicationCommandLineClass *class)
377 {
378   GObjectClass *object_class = G_OBJECT_CLASS (class);
379
380   object_class->get_property = g_application_command_line_get_property;
381   object_class->set_property = g_application_command_line_set_property;
382   object_class->finalize = g_application_command_line_finalize;
383   object_class->constructed = g_application_command_line_constructed;
384
385   class->printerr_literal = g_application_command_line_real_printerr_literal;
386   class->print_literal = g_application_command_line_real_print_literal;
387   class->get_stdin = g_application_command_line_real_get_stdin;
388
389   g_object_class_install_property (object_class, PROP_ARGUMENTS,
390     g_param_spec_variant ("arguments",
391                           P_("Commandline arguments"),
392                           P_("The commandline that caused this ::command-line signal emission"),
393                           G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL,
394                           G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
395                           G_PARAM_STATIC_STRINGS));
396
397   g_object_class_install_property (object_class, PROP_PLATFORM_DATA,
398     g_param_spec_variant ("platform-data",
399                           P_("Platform data"),
400                           P_("Platform-specific data for the commandline"),
401                           G_VARIANT_TYPE ("a{sv}"), NULL,
402                           G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
403                           G_PARAM_STATIC_STRINGS));
404
405   g_object_class_install_property (object_class, PROP_IS_REMOTE,
406     g_param_spec_boolean ("is-remote",
407                           P_("Is remote"),
408                           P_("TRUE if this is a remote commandline"),
409                           FALSE,
410                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
411 }
412
413
414 /**
415  * g_application_command_line_get_arguments:
416  * @cmdline: a #GApplicationCommandLine
417  * @argc: (out) (allow-none): the length of the arguments array, or %NULL
418  *
419  * Gets the list of arguments that was passed on the command line.
420  *
421  * The strings in the array may contain non-UTF-8 data on UNIX (such as
422  * filenames or arguments given in the system locale) but are always in
423  * UTF-8 on Windows.
424  *
425  * If you wish to use the return value with #GOptionContext, you must
426  * use g_option_context_parse_strv().
427  *
428  * The return value is %NULL-terminated and should be freed using
429  * g_strfreev().
430  *
431  * Returns: (array length=argc) (transfer full): the string array
432  * containing the arguments (the argv)
433  *
434  * Since: 2.28
435  **/
436 gchar **
437 g_application_command_line_get_arguments (GApplicationCommandLine *cmdline,
438                                           int                     *argc)
439 {
440   gchar **argv;
441   gsize len;
442
443   g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL);
444
445   argv = g_variant_dup_bytestring_array (cmdline->priv->arguments, &len);
446
447   if (argc)
448     *argc = len;
449
450   return argv;
451 }
452
453 /**
454  * g_application_command_line_get_stdin:
455  * @cmdline: a #GApplicationCommandLine
456  *
457  * Gets the stdin of the invoking process.
458  *
459  * The #GInputStream can be used to read data passed to the standard
460  * input of the invoking process.
461  * This doesn't work on all platforms.  Presently, it is only available
462  * on UNIX when using a DBus daemon capable of passing file descriptors.
463  * If stdin is not available then %NULL will be returned.  In the
464  * future, support may be expanded to other platforms.
465  *
466  * You must only call this function once per commandline invocation.
467  *
468  * Returns: (transfer full): a #GInputStream for stdin
469  *
470  * Since: 2.34
471  **/
472 GInputStream *
473 g_application_command_line_get_stdin (GApplicationCommandLine *cmdline)
474 {
475   return G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)->get_stdin (cmdline);
476 }
477
478 /**
479  * g_application_command_line_get_cwd:
480  * @cmdline: a #GApplicationCommandLine
481  *
482  * Gets the working directory of the command line invocation.
483  * The string may contain non-utf8 data.
484  *
485  * It is possible that the remote application did not send a working
486  * directory, so this may be %NULL.
487  *
488  * The return value should not be modified or freed and is valid for as
489  * long as @cmdline exists.
490  *
491  * Returns: the current directory, or %NULL
492  *
493  * Since: 2.28
494  **/
495 const gchar *
496 g_application_command_line_get_cwd (GApplicationCommandLine *cmdline)
497 {
498   return cmdline->priv->cwd;
499 }
500
501 /**
502  * g_application_command_line_get_environ:
503  * @cmdline: a #GApplicationCommandLine
504  *
505  * Gets the contents of the 'environ' variable of the command line
506  * invocation, as would be returned by g_get_environ(), ie as a
507  * %NULL-terminated list of strings in the form 'NAME=VALUE'.
508  * The strings may contain non-utf8 data.
509  *
510  * The remote application usually does not send an environment.  Use
511  * %G_APPLICATION_SEND_ENVIRONMENT to affect that.  Even with this flag
512  * set it is possible that the environment is still not available (due
513  * to invocation messages from other applications).
514  *
515  * The return value should not be modified or freed and is valid for as
516  * long as @cmdline exists.
517  *
518  * See g_application_command_line_getenv() if you are only interested
519  * in the value of a single environment variable.
520  *
521  * Returns: (array zero-terminated=1) (transfer none): the environment
522  * strings, or %NULL if they were not sent
523  *
524  * Since: 2.28
525  **/
526 const gchar * const *
527 g_application_command_line_get_environ (GApplicationCommandLine *cmdline)
528 {
529   return (const gchar **)cmdline->priv->environ;
530 }
531
532 /**
533  * g_application_command_line_getenv:
534  * @cmdline: a #GApplicationCommandLine
535  * @name: the environment variable to get
536  *
537  * Gets the value of a particular environment variable of the command
538  * line invocation, as would be returned by g_getenv().  The strings may
539  * contain non-utf8 data.
540  *
541  * The remote application usually does not send an environment.  Use
542  * %G_APPLICATION_SEND_ENVIRONMENT to affect that.  Even with this flag
543  * set it is possible that the environment is still not available (due
544  * to invocation messages from other applications).
545  *
546  * The return value should not be modified or freed and is valid for as
547  * long as @cmdline exists.
548  *
549  * Returns: the value of the variable, or %NULL if unset or unsent
550  *
551  * Since: 2.28
552  **/
553 const gchar *
554 g_application_command_line_getenv (GApplicationCommandLine *cmdline,
555                                    const gchar             *name)
556 {
557   gint length = strlen (name);
558   gint i;
559
560   /* TODO: expand on windows */
561   if (cmdline->priv->environ)
562     for (i = 0; cmdline->priv->environ[i]; i++)
563       if (strncmp (cmdline->priv->environ[i], name, length) == 0 &&
564           cmdline->priv->environ[i][length] == '=')
565         return cmdline->priv->environ[i] + length + 1;
566
567   return NULL;
568 }
569
570 /**
571  * g_application_command_line_get_is_remote:
572  * @cmdline: a #GApplicationCommandLine
573  *
574  * Determines if @cmdline represents a remote invocation.
575  *
576  * Returns: %TRUE if the invocation was remote
577  *
578  * Since: 2.28
579  **/
580 gboolean
581 g_application_command_line_get_is_remote (GApplicationCommandLine *cmdline)
582 {
583   return IS_REMOTE (cmdline);
584 }
585
586 /**
587  * g_application_command_line_print:
588  * @cmdline: a #GApplicationCommandLine
589  * @format: a printf-style format string
590  * @...: arguments, as per @format
591  *
592  * Formats a message and prints it using the stdout print handler in the
593  * invoking process.
594  *
595  * If @cmdline is a local invocation then this is exactly equivalent to
596  * g_print().  If @cmdline is remote then this is equivalent to calling
597  * g_print() in the invoking process.
598  *
599  * Since: 2.28
600  **/
601 void
602 g_application_command_line_print (GApplicationCommandLine *cmdline,
603                                   const gchar             *format,
604                                   ...)
605 {
606   gchar *message;
607   va_list ap;
608
609   g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
610   g_return_if_fail (format != NULL);
611
612   va_start (ap, format);
613   message = g_strdup_vprintf (format, ap);
614   va_end (ap);
615
616   G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)
617     ->print_literal (cmdline, message);
618   g_free (message);
619 }
620
621 /**
622  * g_application_command_line_printerr:
623  * @cmdline: a #GApplicationCommandLine
624  * @format: a printf-style format string
625  * @...: arguments, as per @format
626  *
627  * Formats a message and prints it using the stderr print handler in the
628  * invoking process.
629  *
630  * If @cmdline is a local invocation then this is exactly equivalent to
631  * g_printerr().  If @cmdline is remote then this is equivalent to
632  * calling g_printerr() in the invoking process.
633  *
634  * Since: 2.28
635  **/
636 void
637 g_application_command_line_printerr (GApplicationCommandLine *cmdline,
638                                      const gchar             *format,
639                                      ...)
640 {
641   gchar *message;
642   va_list ap;
643
644   g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
645   g_return_if_fail (format != NULL);
646
647   va_start (ap, format);
648   message = g_strdup_vprintf (format, ap);
649   va_end (ap);
650
651   G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)
652     ->printerr_literal (cmdline, message);
653   g_free (message);
654 }
655
656 /**
657  * g_application_command_line_set_exit_status:
658  * @cmdline: a #GApplicationCommandLine
659  * @exit_status: the exit status
660  *
661  * Sets the exit status that will be used when the invoking process
662  * exits.
663  *
664  * The return value of the #GApplication::command-line signal is
665  * passed to this function when the handler returns.  This is the usual
666  * way of setting the exit status.
667  *
668  * In the event that you want the remote invocation to continue running
669  * and want to decide on the exit status in the future, you can use this
670  * call.  For the case of a remote invocation, the remote process will
671  * typically exit when the last reference is dropped on @cmdline.  The
672  * exit status of the remote process will be equal to the last value
673  * that was set with this function.
674  *
675  * In the case that the commandline invocation is local, the situation
676  * is slightly more complicated.  If the commandline invocation results
677  * in the mainloop running (ie: because the use-count of the application
678  * increased to a non-zero value) then the application is considered to
679  * have been 'successful' in a certain sense, and the exit status is
680  * always zero.  If the application use count is zero, though, the exit
681  * status of the local #GApplicationCommandLine is used.
682  *
683  * Since: 2.28
684  **/
685 void
686 g_application_command_line_set_exit_status (GApplicationCommandLine *cmdline,
687                                             int                      exit_status)
688 {
689   g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
690
691   cmdline->priv->exit_status = exit_status;
692 }
693
694 /**
695  * g_application_command_line_get_exit_status:
696  * @cmdline: a #GApplicationCommandLine
697  *
698  * Gets the exit status of @cmdline.  See
699  * g_application_command_line_set_exit_status() for more information.
700  *
701  * Returns: the exit status
702  *
703  * Since: 2.28
704  **/
705 int
706 g_application_command_line_get_exit_status (GApplicationCommandLine *cmdline)
707 {
708   g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), -1);
709
710   return cmdline->priv->exit_status;
711 }
712
713 /**
714  * g_application_command_line_get_platform_data:
715  * @cmdline: #GApplicationCommandLine
716  *
717  * Gets the platform data associated with the invocation of @cmdline.
718  *
719  * This is a #GVariant dictionary containing information about the
720  * context in which the invocation occurred.  It typically contains
721  * information like the current working directory and the startup
722  * notification ID.
723  *
724  * For local invocation, it will be %NULL.
725  *
726  * Returns: (allow-none): the platform data, or %NULL
727  *
728  * Since: 2.28
729  **/
730 GVariant *
731 g_application_command_line_get_platform_data (GApplicationCommandLine *cmdline)
732 {
733   g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL);
734
735   if (cmdline->priv->platform_data)
736     return g_variant_ref (cmdline->priv->platform_data);
737   else
738       return NULL;
739 }
740
741 /**
742  * g_application_command_line_create_file_for_arg:
743  * @cmdline: a #GApplicationCommandLine
744  * @arg: an argument from @cmdline
745  *
746  * Creates a #GFile corresponding to a filename that was given as part
747  * of the invocation of @cmdline.
748  *
749  * This differs from g_file_new_for_commandline_arg() in that it
750  * resolves relative pathnames using the current working directory of
751  * the invoking process rather than the local process.
752  *
753  * Returns: (transfer full): a new #GFile
754  *
755  * Since: 2.36
756  **/
757 GFile *
758 g_application_command_line_create_file_for_arg (GApplicationCommandLine *cmdline,
759                                                 const gchar             *arg)
760 {
761   g_return_val_if_fail (arg != NULL, NULL);
762
763   if (cmdline->priv->cwd)
764     return g_file_new_for_commandline_arg_and_cwd (arg, cmdline->priv->cwd);
765
766   g_warning ("Requested creation of GFile for commandline invocation that did not send cwd. "
767              "Using cwd of local process to resolve relative path names.");
768
769   return g_file_new_for_commandline_arg (arg);
770 }