mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-23 04:36:17 +01:00
Add g_application_command_line_get_stdin()
This returns a GInputStream corresponding to the stdin on the commandline that caused this invocation. The local case works on both UNIX (GUnixInputStream on stdin) and Windows (GWin32InputStream on GetStdHandle(STD_INPUT_HANDLE)). The remote case works only on UNIX (by fd passing over D-Bus). https://bugzilla.gnome.org/show_bug.cgi?id=668210
This commit is contained in:
parent
3e97776276
commit
89d48d7800
@ -29,6 +29,16 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
#include "gunixinputstream.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#undef environ
|
||||||
|
#include "gwin32inputstream.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
G_DEFINE_TYPE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,6 +198,16 @@ g_application_command_line_real_printerr_literal (GApplicationCommandLine *cmdli
|
|||||||
g_printerr ("%s", message);
|
g_printerr ("%s", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GInputStream *
|
||||||
|
g_application_command_line_real_get_stdin (GApplicationCommandLine *cmdline)
|
||||||
|
{
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
return g_unix_input_stream_new (0, FALSE);
|
||||||
|
#else
|
||||||
|
return g_win32_input_stream_new (GetStdHandle (STD_INPUT_HANDLE), FALSE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_application_command_line_get_property (GObject *object,
|
g_application_command_line_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -296,6 +316,7 @@ g_application_command_line_class_init (GApplicationCommandLineClass *class)
|
|||||||
|
|
||||||
class->printerr_literal = g_application_command_line_real_printerr_literal;
|
class->printerr_literal = g_application_command_line_real_printerr_literal;
|
||||||
class->print_literal = g_application_command_line_real_print_literal;
|
class->print_literal = g_application_command_line_real_print_literal;
|
||||||
|
class->get_stdin = g_application_command_line_real_get_stdin;
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_ARGUMENTS,
|
g_object_class_install_property (object_class, PROP_ARGUMENTS,
|
||||||
g_param_spec_variant ("arguments",
|
g_param_spec_variant ("arguments",
|
||||||
@ -358,6 +379,31 @@ g_application_command_line_get_arguments (GApplicationCommandLine *cmdline,
|
|||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_application_command_line_get_stdin_data:
|
||||||
|
* @cmdline: a #GApplicationCommandLine
|
||||||
|
*
|
||||||
|
* Gets the stdin of the invoking process.
|
||||||
|
*
|
||||||
|
* The #GInputStream can be used to read data passed to the standard
|
||||||
|
* input of the invoking process.
|
||||||
|
* This doesn't work on all platforms. Presently, it is only available
|
||||||
|
* on UNIX when using a DBus daemon capable of passing file descriptors.
|
||||||
|
* If stdin is not available then %NULL will be returned. In the
|
||||||
|
* future, support may be expanded to other platforms.
|
||||||
|
*
|
||||||
|
* You must only call this function once per commandline invocation.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): a #GInputStream for stdin
|
||||||
|
*
|
||||||
|
* Since: 2.34
|
||||||
|
**/
|
||||||
|
GInputStream *
|
||||||
|
g_application_command_line_get_stdin (GApplicationCommandLine *cmdline)
|
||||||
|
{
|
||||||
|
return G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)->get_stdin (cmdline);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_application_command_line_get_cwd:
|
* g_application_command_line_get_cwd:
|
||||||
* @cmdline: a #GApplicationCommandLine
|
* @cmdline: a #GApplicationCommandLine
|
||||||
|
@ -62,12 +62,13 @@ struct _GApplicationCommandLineClass
|
|||||||
/*< private >*/
|
/*< private >*/
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
void (* print_literal) (GApplicationCommandLine *cmdline,
|
void (* print_literal) (GApplicationCommandLine *cmdline,
|
||||||
const gchar *message);
|
const gchar *message);
|
||||||
void (* printerr_literal) (GApplicationCommandLine *cmdline,
|
void (* printerr_literal) (GApplicationCommandLine *cmdline,
|
||||||
const gchar *message);
|
const gchar *message);
|
||||||
|
GInputStream * (* get_stdin) (GApplicationCommandLine *cmdline);
|
||||||
|
|
||||||
gpointer padding[12];
|
gpointer padding[11];
|
||||||
};
|
};
|
||||||
|
|
||||||
GType g_application_command_line_get_type (void) G_GNUC_CONST;
|
GType g_application_command_line_get_type (void) G_GNUC_CONST;
|
||||||
@ -75,6 +76,8 @@ GType g_application_command_line_get_type (void) G
|
|||||||
gchar ** g_application_command_line_get_arguments (GApplicationCommandLine *cmdline,
|
gchar ** g_application_command_line_get_arguments (GApplicationCommandLine *cmdline,
|
||||||
int *argc);
|
int *argc);
|
||||||
|
|
||||||
|
GInputStream * g_application_command_line_get_stdin (GApplicationCommandLine *cmdline);
|
||||||
|
|
||||||
const gchar * const * g_application_command_line_get_environ (GApplicationCommandLine *cmdline);
|
const gchar * const * g_application_command_line_get_environ (GApplicationCommandLine *cmdline);
|
||||||
|
|
||||||
const gchar * g_application_command_line_getenv (GApplicationCommandLine *cmdline,
|
const gchar * g_application_command_line_getenv (GApplicationCommandLine *cmdline,
|
||||||
|
@ -39,6 +39,11 @@
|
|||||||
#include "gapplicationcommandline.h"
|
#include "gapplicationcommandline.h"
|
||||||
#include "gdbusmethodinvocation.h"
|
#include "gdbusmethodinvocation.h"
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
#include "gunixinputstream.h"
|
||||||
|
#include "gunixfdlist.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* DBus Interface definition {{{1 */
|
/* DBus Interface definition {{{1 */
|
||||||
|
|
||||||
/* For documentation of these interfaces, see
|
/* For documentation of these interfaces, see
|
||||||
@ -524,8 +529,12 @@ g_application_impl_cmdline_done (GObject *source,
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GVariant *reply;
|
GVariant *reply;
|
||||||
|
|
||||||
reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
|
#ifdef G_OS_UNIX
|
||||||
result, &error);
|
reply = g_dbus_connection_call_with_unix_fd_list_finish (G_DBUS_CONNECTION (source), NULL, result, &error);
|
||||||
|
#else
|
||||||
|
reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (reply != NULL)
|
if (reply != NULL)
|
||||||
{
|
{
|
||||||
@ -580,15 +589,31 @@ g_application_impl_command_line (GApplicationImpl *impl,
|
|||||||
/* In theory we should try other paths... */
|
/* In theory we should try other paths... */
|
||||||
g_assert (object_id != 0);
|
g_assert (object_id != 0);
|
||||||
|
|
||||||
g_dbus_connection_call (impl->session_bus,
|
#ifdef G_OS_UNIX
|
||||||
impl->bus_name,
|
{
|
||||||
impl->object_path,
|
GError *error = NULL;
|
||||||
"org.gtk.Application",
|
GUnixFDList *fd_list;
|
||||||
"CommandLine",
|
|
||||||
g_variant_new ("(o^aay@a{sv})", object_path,
|
/* send along the stdin in case
|
||||||
arguments, platform_data),
|
* g_application_command_line_get_stdin_data() is called
|
||||||
|
*/
|
||||||
|
fd_list = g_unix_fd_list_new ();
|
||||||
|
g_unix_fd_list_append (fd_list, 0, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_dbus_connection_call_with_unix_fd_list (impl->session_bus, impl->bus_name, impl->object_path,
|
||||||
|
"org.gtk.Application", "CommandLine",
|
||||||
|
g_variant_new ("(o^aay@a{sv})", object_path, arguments, platform_data),
|
||||||
|
G_VARIANT_TYPE ("(i)"), 0, G_MAXINT, fd_list, NULL,
|
||||||
|
g_application_impl_cmdline_done, &data);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
g_dbus_connection_call (impl->session_bus, impl->bus_name, impl->object_path,
|
||||||
|
"org.gtk.Application", "CommandLine",
|
||||||
|
g_variant_new ("(o^aay@a{sv})", object_path, arguments, platform_data),
|
||||||
G_VARIANT_TYPE ("(i)"), 0, G_MAXINT, NULL,
|
G_VARIANT_TYPE ("(i)"), 0, G_MAXINT, NULL,
|
||||||
g_application_impl_cmdline_done, &data);
|
g_application_impl_cmdline_done, &data);
|
||||||
|
#endif
|
||||||
|
|
||||||
g_main_loop_run (data.loop);
|
g_main_loop_run (data.loop);
|
||||||
|
|
||||||
@ -665,6 +690,35 @@ g_dbus_command_line_printerr_literal (GApplicationCommandLine *cmdline,
|
|||||||
NULL, 0, -1, NULL, NULL, NULL);
|
NULL, 0, -1, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GInputStream *
|
||||||
|
g_dbus_command_line_get_stdin (GApplicationCommandLine *cmdline)
|
||||||
|
{
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline;
|
||||||
|
GInputStream *result = NULL;
|
||||||
|
GDBusMessage *message;
|
||||||
|
GUnixFDList *fd_list;
|
||||||
|
|
||||||
|
message = g_dbus_method_invocation_get_message (gdbcl->invocation);
|
||||||
|
fd_list = g_dbus_message_get_unix_fd_list (message);
|
||||||
|
|
||||||
|
if (fd_list && g_unix_fd_list_get_length (fd_list))
|
||||||
|
{
|
||||||
|
gint *fds, n_fds, i;
|
||||||
|
|
||||||
|
fds = g_unix_fd_list_steal_fds (fd_list, &n_fds);
|
||||||
|
result = g_unix_input_stream_new (fds[0], TRUE);
|
||||||
|
for (i = 1; i < n_fds; i++)
|
||||||
|
close (fds[i]);
|
||||||
|
g_free (fds);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_dbus_command_line_finalize (GObject *object)
|
g_dbus_command_line_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
@ -695,6 +749,7 @@ g_dbus_command_line_class_init (GApplicationCommandLineClass *class)
|
|||||||
object_class->finalize = g_dbus_command_line_finalize;
|
object_class->finalize = g_dbus_command_line_finalize;
|
||||||
class->printerr_literal = g_dbus_command_line_printerr_literal;
|
class->printerr_literal = g_dbus_command_line_printerr_literal;
|
||||||
class->print_literal = g_dbus_command_line_print_literal;
|
class->print_literal = g_dbus_command_line_print_literal;
|
||||||
|
class->get_stdin = g_dbus_command_line_get_stdin;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GApplicationCommandLine *
|
static GApplicationCommandLine *
|
||||||
|
@ -34,6 +34,7 @@ g_application_set_default
|
|||||||
g_application_set_flags
|
g_application_set_flags
|
||||||
g_application_set_inactivity_timeout
|
g_application_set_inactivity_timeout
|
||||||
g_application_quit
|
g_application_quit
|
||||||
|
g_application_command_line_get_stdin
|
||||||
g_application_command_line_create_file_for_arg
|
g_application_command_line_create_file_for_arg
|
||||||
g_application_command_line_get_arguments
|
g_application_command_line_get_arguments
|
||||||
g_application_command_line_get_cwd
|
g_application_command_line_get_cwd
|
||||||
|
Loading…
Reference in New Issue
Block a user