LCOV - code coverage report
Current view: top level - glib/gio - gapplicationcommandline.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 120 185 64.9 %
Date: 2024-03-26 05:16:46 Functions: 20 32 62.5 %
Branches: 47 70 67.1 %

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

Generated by: LCOV version 1.14