#include <string.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_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
g_application_command_line_get_property (GObject *object,
guint prop_id,
class->printerr_literal = g_application_command_line_real_printerr_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_param_spec_variant ("arguments",
}
/**
+ * 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:
* @cmdline: a #GApplicationCommandLine
*
/*< private >*/
GObjectClass parent_class;
- void (* print_literal) (GApplicationCommandLine *cmdline,
- const gchar *message);
- void (* printerr_literal) (GApplicationCommandLine *cmdline,
- const gchar *message);
+ void (* print_literal) (GApplicationCommandLine *cmdline,
+ const gchar *message);
+ void (* printerr_literal) (GApplicationCommandLine *cmdline,
+ 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;
gchar ** g_application_command_line_get_arguments (GApplicationCommandLine *cmdline,
int *argc);
+GInputStream * g_application_command_line_get_stdin (GApplicationCommandLine *cmdline);
+
const gchar * const * g_application_command_line_get_environ (GApplicationCommandLine *cmdline);
const gchar * g_application_command_line_getenv (GApplicationCommandLine *cmdline,
#include "gapplicationcommandline.h"
#include "gdbusmethodinvocation.h"
+#ifdef G_OS_UNIX
+#include "gunixinputstream.h"
+#include "gunixfdlist.h"
+#endif
+
/* DBus Interface definition {{{1 */
/* For documentation of these interfaces, see
GError *error = NULL;
GVariant *reply;
- reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
- result, &error);
+#ifdef G_OS_UNIX
+ 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)
{
/* In theory we should try other paths... */
g_assert (object_id != 0);
- 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),
+#ifdef G_OS_UNIX
+ {
+ GError *error = NULL;
+ GUnixFDList *fd_list;
+
+ /* send along the stdin in case
+ * 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_application_impl_cmdline_done, &data);
+#endif
g_main_loop_run (data.loop);
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
g_dbus_command_line_finalize (GObject *object)
{
object_class->finalize = g_dbus_command_line_finalize;
class->printerr_literal = g_dbus_command_line_printerr_literal;
class->print_literal = g_dbus_command_line_print_literal;
+ class->get_stdin = g_dbus_command_line_get_stdin;
}
static GApplicationCommandLine *