Coverage Report

Created: 2025-07-01 07:09

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