[gnome-builder/wip/gtk4-port: 1553/1774] libide/threading: port subprocess launcher to IdeUnixFDMap
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/gtk4-port: 1553/1774] libide/threading: port subprocess launcher to IdeUnixFDMap
- Date: Mon, 11 Jul 2022 22:31:49 +0000 (UTC)
commit d31f2f4a64a1df24e3be2c481860c0ad28857087
Author: Christian Hergert <chergert redhat com>
Date: Thu Jun 16 16:16:40 2022 -0700
libide/threading: port subprocess launcher to IdeUnixFDMap
This ports the subprocess launching to using the new IdeUnixFDMap as a
first test to see how the API is working for us. Ideally this will flush
out any bugs quickly so we can use it for run contexts and other areas
where you find something like a "FDMap" struct.
.../threading/ide-flatpak-subprocess-private.h | 27 +-
src/libide/threading/ide-flatpak-subprocess.c | 261 +++++++-------
src/libide/threading/ide-subprocess-launcher.c | 381 +++++++--------------
3 files changed, 261 insertions(+), 408 deletions(-)
---
diff --git a/src/libide/threading/ide-flatpak-subprocess-private.h
b/src/libide/threading/ide-flatpak-subprocess-private.h
index 64628c69b..3a9cf413a 100644
--- a/src/libide/threading/ide-flatpak-subprocess-private.h
+++ b/src/libide/threading/ide-flatpak-subprocess-private.h
@@ -21,6 +21,7 @@
#pragma once
#include "ide-subprocess.h"
+#include "ide-unix-fd-map.h"
G_BEGIN_DECLS
@@ -28,23 +29,13 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeFlatpakSubprocess, ide_flatpak_subprocess, IDE, FLATPAK_SUBPROCESS, GObject)
-typedef struct
-{
- gint source_fd;
- gint dest_fd;
-} IdeBreakoutFdMapping;
-
-IdeSubprocess *_ide_flatpak_subprocess_new (const gchar *cwd,
- const gchar * const *argv,
- const gchar * const *env,
- GSubprocessFlags flags,
- gboolean clear_flags,
- gint stdin_fd,
- gint stdout_fd,
- gint stderr_fd,
- const IdeBreakoutFdMapping *fd_map,
- guint fd_map_len,
- GCancellable *cancellable,
- GError **error) G_GNUC_INTERNAL;
+IdeSubprocess *_ide_flatpak_subprocess_new (const char *cwd,
+ const char * const *argv,
+ const char * const *env,
+ GSubprocessFlags flags,
+ gboolean clear_flags,
+ IdeUnixFDMap *unix_fd_map,
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
diff --git a/src/libide/threading/ide-flatpak-subprocess.c b/src/libide/threading/ide-flatpak-subprocess.c
index 065f597d4..3a5003c0c 100644
--- a/src/libide/threading/ide-flatpak-subprocess.c
+++ b/src/libide/threading/ide-flatpak-subprocess.c
@@ -58,29 +58,24 @@ struct _IdeFlatpakSubprocess
gulong connection_closed_handler;
GPid client_pid;
- gint status;
+ int status;
GSubprocessFlags flags;
/* No reference */
GThread *spawn_thread;
- gchar **argv;
- gchar **env;
- gchar *cwd;
+ char **argv;
+ char **env;
+ char *cwd;
- gchar *identifier;
-
- gint stdin_fd;
- gint stdout_fd;
- gint stderr_fd;
+ char *identifier;
GOutputStream *stdin_pipe;
GInputStream *stdout_pipe;
GInputStream *stderr_pipe;
- IdeBreakoutFdMapping *fd_mapping;
- guint fd_mapping_len;
+ IdeUnixFDMap *unix_fd_map;
GMainContext *main_context;
@@ -139,29 +134,31 @@ struct _IdeFlatpakSubprocess
*/
typedef struct
{
- const gchar *stdin_data;
- gsize stdin_length;
- gsize stdin_offset;
+ const char *stdin_data;
+ gsize stdin_length;
+ gsize stdin_offset;
- gboolean add_nul;
+ gboolean add_nul;
- GInputStream *stdin_buf;
+ GInputStream *stdin_buf;
GMemoryOutputStream *stdout_buf;
GMemoryOutputStream *stderr_buf;
- GCancellable *cancellable;
- GSource *cancellable_source;
+ GCancellable *cancellable;
+ GSource *cancellable_source;
- guint outstanding_ops;
- gboolean reported_error;
+ guint outstanding_ops;
+ gboolean reported_error;
} CommunicateState;
enum {
PROP_0,
PROP_ARGV,
+ PROP_CLEAR_ENV,
PROP_CWD,
PROP_ENV,
PROP_FLAGS,
+ PROP_UNIX_FD_MAP,
N_PROPS
};
@@ -180,7 +177,7 @@ static CommunicateState *ide_flatpak_subprocess_communicate_internal (IdeFlatpak
static GParamSpec *properties [N_PROPS];
-static const gchar *
+static const char *
ide_flatpak_subprocess_get_identifier (IdeSubprocess *subprocess)
{
IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
@@ -485,7 +482,7 @@ ide_flatpak_subprocess_get_if_exited (IdeSubprocess *subprocess)
return WIFEXITED (self->status);
}
-static gint
+static int
ide_flatpak_subprocess_get_exit_status (IdeSubprocess *subprocess)
{
IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
@@ -510,7 +507,7 @@ ide_flatpak_subprocess_get_if_signaled (IdeSubprocess *subprocess)
return WIFSIGNALED (self->status);
}
-static gint
+static int
ide_flatpak_subprocess_get_term_sig (IdeSubprocess *subprocess)
{
IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
@@ -521,7 +518,7 @@ ide_flatpak_subprocess_get_term_sig (IdeSubprocess *subprocess)
return WTERMSIG (self->status);
}
-static gint
+static int
ide_flatpak_subprocess_get_status (IdeSubprocess *subprocess)
{
IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
@@ -534,7 +531,7 @@ ide_flatpak_subprocess_get_status (IdeSubprocess *subprocess)
static void
ide_flatpak_subprocess_send_signal (IdeSubprocess *subprocess,
- gint signal_num)
+ int signal_num)
{
IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)subprocess;
@@ -945,7 +942,7 @@ subprocess_iface_init (IdeSubprocessInterface *iface)
static void
maybe_create_input_stream (GInputStream **ret,
- gint *fdptr,
+ int *fdptr,
gboolean needs_stream)
{
g_assert (ret != NULL);
@@ -972,7 +969,7 @@ maybe_create_input_stream (GInputStream **ret,
static void
maybe_create_output_stream (GOutputStream **ret,
- gint *fdptr,
+ int *fdptr,
gboolean needs_stream)
{
g_assert (ret != NULL);
@@ -999,7 +996,7 @@ maybe_create_output_stream (GOutputStream **ret,
static void
ide_flatpak_subprocess_complete_command_locked (IdeFlatpakSubprocess *self,
- gint exit_status)
+ int exit_status)
{
GList *waiting;
@@ -1046,10 +1043,10 @@ ide_flatpak_subprocess_complete_command_locked (IdeFlatpakSubprocess *self,
static void
host_command_exited_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
+ const char *sender_name,
+ const char *object_path,
+ const char *interface_name,
+ const char *signal_name,
GVariant *parameters,
gpointer user_data)
{
@@ -1094,7 +1091,7 @@ host_command_exited_cb (GDBusConnection *connection,
static void
ide_flatpak_subprocess_cancelled (IdeFlatpakSubprocess *self,
- GCancellable *cancellable)
+ GCancellable *cancellable)
{
IDE_ENTRY;
@@ -1107,7 +1104,7 @@ ide_flatpak_subprocess_cancelled (IdeFlatpakSubprocess *self,
}
static inline void
-maybe_close (gint *fd)
+maybe_close (int *fd)
{
g_assert (fd != NULL);
g_assert (*fd >= -1);
@@ -1120,9 +1117,9 @@ maybe_close (gint *fd)
static void
ide_flatpak_subprocess_connection_closed (IdeFlatpakSubprocess *self,
- gboolean remote_peer_vanished,
- const GError *error,
- GDBusConnection *connection)
+ gboolean remote_peer_vanished,
+ const GError *error,
+ GDBusConnection *connection)
{
g_autoptr(GMutexLocker) locker = NULL;
@@ -1143,8 +1140,8 @@ ide_flatpak_subprocess_connection_closed (IdeFlatpakSubprocess *self,
static gboolean
ide_flatpak_subprocess_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
+ GCancellable *cancellable,
+ GError **error)
{
IdeFlatpakSubprocess *self = (IdeFlatpakSubprocess *)initable;
g_autoptr(GVariantBuilder) fd_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{uh}"));
@@ -1153,18 +1150,20 @@ ide_flatpak_subprocess_initable_init (GInitable *initable,
g_autoptr(GVariant) reply = NULL;
g_autoptr(GVariant) params = NULL;
guint32 client_pid = 0;
- gint stdout_pair[2] = { -1, -1 };
- gint stderr_pair[2] = { -1, -1 };
- gint stdin_pair[2] = { -1, -1 };
- gint stdin_handle = -1;
- gint stdout_handle = -1;
- gint stderr_handle = -1;
+ int stdout_pair[2] = { -1, -1 };
+ int stderr_pair[2] = { -1, -1 };
+ int stdin_pair[2] = { -1, -1 };
+ int stdin_handle = -1;
+ int stdout_handle = -1;
+ int stderr_handle = -1;
gboolean ret = FALSE;
guint flags = FLATPAK_HOST_COMMAND_FLAGS_WATCH_BUS;
+ guint length;
IDE_ENTRY;
g_assert (IDE_IS_FLATPAK_SUBPROCESS (self));
+ g_assert (IDE_IS_UNIX_FD_MAP (self->unix_fd_map));
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
if (!(self->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, error)))
@@ -1173,18 +1172,14 @@ ide_flatpak_subprocess_initable_init (GInitable *initable,
if (self->clear_env)
flags |= FLATPAK_HOST_COMMAND_FLAGS_CLEAR_ENV;
-
- /*
- * Handle STDIN for the process.
+ /* Handle STDIN for the process.
*
* Make sure we handle inherit STDIN, a new pipe (so that the application can
* get the stdin stream), or simply redirect to /dev/null.
*/
- if (self->stdin_fd != -1)
+ if (-1 != (stdin_pair[0] = ide_unix_fd_map_steal_stdin (self->unix_fd_map)))
{
self->flags &= ~G_SUBPROCESS_FLAGS_STDIN_PIPE;
- stdin_pair[0] = self->stdin_fd;
- self->stdin_fd = -1;
}
else if (self->flags & G_SUBPROCESS_FLAGS_STDIN_INHERIT)
{
@@ -1213,18 +1208,15 @@ ide_flatpak_subprocess_initable_init (GInitable *initable,
maybe_close (&stdin_pair[0]);
- /*
- * Setup STDOUT for the process.
+ /* Setup STDOUT for the process.
*
* Make sure we redirect STDOUT to our stdout, unless a pipe was requested
* for the application to read. However, if silence was requested, redirect
* to /dev/null.
*/
- if (self->stdout_fd != -1)
+ if (-1 != (stdout_pair[1] = ide_unix_fd_map_steal_stdout (self->unix_fd_map)))
{
self->flags &= ~G_SUBPROCESS_FLAGS_STDOUT_PIPE;
- stdout_pair[1] = self->stdout_fd;
- self->stdout_fd = -1;
}
else if (self->flags & G_SUBPROCESS_FLAGS_STDOUT_SILENCE)
{
@@ -1253,18 +1245,15 @@ ide_flatpak_subprocess_initable_init (GInitable *initable,
maybe_close (&stdout_pair[1]);
- /*
- * Handle STDERR for the process.
+ /* Handle STDERR for the process.
*
* If silence is requested, we simply redirect to /dev/null. If the
* application requested to read from the subprocesses stderr, then we need
* to create a pipe. Otherwose, merge stderr into our own stderr.
*/
- if (self->stderr_fd != -1)
+ if (-1 != (stderr_pair[1] = ide_unix_fd_map_steal_stderr (self->unix_fd_map)))
{
self->flags &= ~G_SUBPROCESS_FLAGS_STDERR_PIPE;
- stderr_pair[1] = self->stderr_fd;
- self->stderr_fd = -1;
}
else if (self->flags & G_SUBPROCESS_FLAGS_STDERR_SILENCE)
{
@@ -1293,39 +1282,32 @@ ide_flatpak_subprocess_initable_init (GInitable *initable,
maybe_close (&stderr_pair[1]);
- /*
- * Build our FDs for the message.
- */
+ /* Build our FDs for the message. */
g_variant_builder_add (fd_builder, "{uh}", 0, stdin_handle);
g_variant_builder_add (fd_builder, "{uh}", 1, stdout_handle);
g_variant_builder_add (fd_builder, "{uh}", 2, stderr_handle);
- /*
- * Now add the rest of our FDs that we might need to map in for which
+ /* Now add the rest of our FDs that we might need to map in for which
* the subprocess launcher tried to map.
*/
- for (guint i = 0; i < self->fd_mapping_len; i++)
+ length = ide_unix_fd_map_get_length (self->unix_fd_map);
+ for (guint i = 0; i < length; i++)
{
- const IdeBreakoutFdMapping *map = &self->fd_mapping[i];
- g_autoptr(GError) fd_error = NULL;
- gint dest_handle;
+ int source_fd;
+ int dest_fd;
- dest_handle = g_unix_fd_list_append (fd_list, map->source_fd, &fd_error);
-
- if (dest_handle != -1)
- g_variant_builder_add (fd_builder, "{uh}", map->dest_fd, dest_handle);
- else
- g_warning ("%s", fd_error->message);
+ if (-1 != (source_fd = ide_unix_fd_map_peek (self->unix_fd_map, i, &dest_fd)))
+ {
+ int dest_handle = g_unix_fd_list_append (fd_list, source_fd, NULL);
- close (map->source_fd);
+ if (dest_handle != -1)
+ g_variant_builder_add (fd_builder, "{uh}", dest_fd, dest_handle);
+ }
}
- /*
- * We don't want to allow these FDs to be used again.
- */
- self->fd_mapping_len = 0;
- g_clear_pointer (&self->fd_mapping, g_free);
+ /* We don't want to allow these FDs to be used again. */
+ g_clear_object (&self->unix_fd_map);
/*
@@ -1343,10 +1325,10 @@ ide_flatpak_subprocess_initable_init (GInitable *initable,
{
for (guint i = 0; self->env[i]; i++)
{
- const gchar *pair = self->env[i];
- const gchar *eq = strchr (pair, '=');
- const gchar *val = eq ? eq + 1 : "";
- g_autofree gchar *key = eq ? g_strndup (pair, eq - pair) : g_strdup (pair);
+ const char *pair = self->env[i];
+ const char *eq = strchr (pair, '=');
+ const char *val = eq ? eq + 1 : "";
+ g_autofree char *key = eq ? g_strndup (pair, eq - pair) : g_strdup (pair);
g_variant_builder_add (env_builder, "{ss}", key, val);
}
@@ -1410,7 +1392,7 @@ ide_flatpak_subprocess_initable_init (GInitable *initable,
#ifdef IDE_ENABLE_TRACE
{
- g_autofree gchar *str = g_variant_print (params, TRUE);
+ g_autofree char *str = g_variant_print (params, TRUE);
IDE_TRACE_MSG ("Calling HostCommand with %s", str);
}
#endif
@@ -1474,9 +1456,9 @@ initiable_iface_init (GInitableIface *iface)
iface->init = ide_flatpak_subprocess_initable_init;
}
-G_DEFINE_TYPE_EXTENDED (IdeFlatpakSubprocess, ide_flatpak_subprocess, G_TYPE_OBJECT, G_TYPE_FLAG_FINAL,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initiable_iface_init)
- G_IMPLEMENT_INTERFACE (IDE_TYPE_SUBPROCESS, subprocess_iface_init))
+G_DEFINE_FINAL_TYPE_WITH_CODE (IdeFlatpakSubprocess, ide_flatpak_subprocess, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initiable_iface_init)
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_SUBPROCESS, subprocess_iface_init))
static void
ide_flatpak_subprocess_dispose (GObject *object)
@@ -1522,23 +1504,11 @@ ide_flatpak_subprocess_finalize (GObject *object)
g_clear_object (&self->stdout_pipe);
g_clear_object (&self->stderr_pipe);
g_clear_object (&self->connection);
+ g_clear_object (&self->unix_fd_map);
g_mutex_clear (&self->waiter_mutex);
g_cond_clear (&self->waiter_cond);
- if (self->stdin_fd != -1)
- close (self->stdin_fd);
-
- if (self->stdout_fd != -1)
- close (self->stdout_fd);
-
- if (self->stderr_fd != -1)
- close (self->stderr_fd);
-
- for (guint i = 0; i < self->fd_mapping_len; i++)
- close (self->fd_mapping[i].source_fd);
- g_clear_pointer (&self->fd_mapping, g_free);
-
G_OBJECT_CLASS (ide_flatpak_subprocess_parent_class)->finalize (object);
IDE_EXIT;
@@ -1546,14 +1516,18 @@ ide_flatpak_subprocess_finalize (GObject *object)
static void
ide_flatpak_subprocess_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
IdeFlatpakSubprocess *self = IDE_FLATPAK_SUBPROCESS (object);
switch (prop_id)
{
+ case PROP_CLEAR_ENV:
+ g_value_set_boolean (value, self->clear_env);
+ break;
+
case PROP_CWD:
g_value_set_string (value, self->cwd);
break;
@@ -1570,6 +1544,10 @@ ide_flatpak_subprocess_get_property (GObject *object,
g_value_set_flags (value, self->flags);
break;
+ case PROP_UNIX_FD_MAP:
+ g_value_set_object (value, self->unix_fd_map);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -1577,22 +1555,26 @@ ide_flatpak_subprocess_get_property (GObject *object,
static void
ide_flatpak_subprocess_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
IdeFlatpakSubprocess *self = IDE_FLATPAK_SUBPROCESS (object);
switch (prop_id)
{
- case PROP_CWD:
- self->cwd = g_value_dup_string (value);
- break;
-
case PROP_ARGV:
self->argv = g_value_dup_boxed (value);
break;
+ case PROP_CLEAR_ENV:
+ self->clear_env = g_value_get_boolean (value);
+ break;
+
+ case PROP_CWD:
+ self->cwd = g_value_dup_string (value);
+ break;
+
case PROP_ENV:
self->env = g_value_dup_boxed (value);
break;
@@ -1601,6 +1583,12 @@ ide_flatpak_subprocess_set_property (GObject *object,
self->flags = g_value_get_flags (value);
break;
+ case PROP_UNIX_FD_MAP:
+ self->unix_fd_map = g_value_dup_object (value);
+ if (self->unix_fd_map == NULL)
+ self->unix_fd_map = ide_unix_fd_map_new ();
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -1616,6 +1604,11 @@ ide_flatpak_subprocess_class_init (IdeFlatpakSubprocessClass *klass)
object_class->get_property = ide_flatpak_subprocess_get_property;
object_class->set_property = ide_flatpak_subprocess_set_property;
+ properties [PROP_CLEAR_ENV] =
+ g_param_spec_boolean ("clear-env", NULL, NULL,
+ FALSE,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
properties [PROP_CWD] =
g_param_spec_string ("cwd",
"Current Working Directory",
@@ -1645,6 +1638,11 @@ ide_flatpak_subprocess_class_init (IdeFlatpakSubprocessClass *klass)
G_SUBPROCESS_FLAGS_NONE,
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ properties [PROP_UNIX_FD_MAP] =
+ g_param_spec_object ("unix-fd-map", NULL, NULL,
+ IDE_TYPE_UNIX_FD_MAP,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@@ -1653,10 +1651,6 @@ ide_flatpak_subprocess_init (IdeFlatpakSubprocess *self)
{
IDE_ENTRY;
- self->stdin_fd = -1;
- self->stdout_fd = -1;
- self->stderr_fd = -1;
-
g_mutex_init (&self->waiter_mutex);
g_cond_init (&self->waiter_cond);
@@ -1664,40 +1658,31 @@ ide_flatpak_subprocess_init (IdeFlatpakSubprocess *self)
}
IdeSubprocess *
-_ide_flatpak_subprocess_new (const gchar *cwd,
- const gchar * const *argv,
- const gchar * const *env,
- GSubprocessFlags flags,
- gboolean clear_env,
- gint stdin_fd,
- gint stdout_fd,
- gint stderr_fd,
- const IdeBreakoutFdMapping *fd_mapping,
- guint fd_mapping_len,
- GCancellable *cancellable,
- GError **error)
+_ide_flatpak_subprocess_new (const char *cwd,
+ const char * const *argv,
+ const char * const *env,
+ GSubprocessFlags flags,
+ gboolean clear_env,
+ IdeUnixFDMap *unix_fd_map,
+ GCancellable *cancellable,
+ GError **error)
{
g_autoptr(IdeFlatpakSubprocess) ret = NULL;
g_return_val_if_fail (argv != NULL, NULL);
g_return_val_if_fail (argv[0] != NULL, NULL);
+ g_return_val_if_fail (!unix_fd_map || IDE_IS_UNIX_FD_MAP (unix_fd_map), NULL);
+ g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
ret = g_object_new (IDE_TYPE_FLATPAK_SUBPROCESS,
"cwd", cwd,
"argv", argv,
+ "clear-env", clear_env,
"env", env,
"flags", flags,
+ "unix-fd-map", unix_fd_map,
NULL);
- ret->clear_env = clear_env;
- ret->stdin_fd = stdin_fd;
- ret->stdout_fd = stdout_fd;
- ret->stderr_fd = stderr_fd;
-
- ret->fd_mapping = g_new0 (IdeBreakoutFdMapping, fd_mapping_len);
- ret->fd_mapping_len = fd_mapping_len;
- memcpy (ret->fd_mapping, fd_mapping, sizeof(IdeBreakoutFdMapping) * fd_mapping_len);
-
if (!g_initable_init (G_INITABLE (ret), cancellable, error))
return NULL;
diff --git a/src/libide/threading/ide-subprocess-launcher.c b/src/libide/threading/ide-subprocess-launcher.c
index ffa3c9208..7e5daf93a 100644
--- a/src/libide/threading/ide-subprocess-launcher.c
+++ b/src/libide/threading/ide-subprocess-launcher.c
@@ -41,6 +41,7 @@
#include "ide-flatpak-subprocess-private.h"
#include "ide-simple-subprocess-private.h"
#include "ide-subprocess-launcher.h"
+#include "ide-unix-fd-map.h"
/* This comes from libide-io but we need access to it */
#include "../io/ide-shell.h"
@@ -49,28 +50,17 @@
typedef struct
{
- GSubprocessFlags flags;
-
GPtrArray *argv;
- gchar *cwd;
- gchar **environ;
- GArray *fd_mapping;
- gchar *stdout_file_path;
-
- gint stdin_fd;
- gint stdout_fd;
- gint stderr_fd;
+ char *cwd;
+ char **environ;
+ char *stdout_file_path;
+ IdeUnixFDMap *unix_fd_map;
+ GSubprocessFlags flags : 14;
guint run_on_host : 1;
guint clear_env : 1;
} IdeSubprocessLauncherPrivate;
-typedef struct
-{
- gint source_fd;
- gint dest_fd;
-} FdMapping;
-
G_DEFINE_TYPE_WITH_PRIVATE (IdeSubprocessLauncher, ide_subprocess_launcher, G_TYPE_OBJECT)
enum {
@@ -122,7 +112,7 @@ ide_subprocess_launcher_kill_process_group (GCancellable *cancellable,
GSubprocess *subprocess)
{
#ifdef G_OS_UNIX
- const gchar *ident;
+ const char *ident;
pid_t pid;
IDE_ENTRY;
@@ -204,10 +194,6 @@ ide_subprocess_launcher_spawn_host_worker (GTask *task,
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
g_autoptr(IdeSubprocess) process = NULL;
g_autoptr(GError) error = NULL;
- g_autoptr(GArray) fds = NULL;
- gint stdin_fd = -1;
- gint stdout_fd = -1;
- gint stderr_fd = -1;
IDE_ENTRY;
@@ -215,56 +201,44 @@ ide_subprocess_launcher_spawn_host_worker (GTask *task,
#ifdef IDE_ENABLE_TRACE
{
- g_autofree gchar *str = NULL;
- g_autofree gchar *env = NULL;
- str = g_strjoinv (" ", (gchar **)priv->argv->pdata);
+ g_autofree char *str = NULL;
+ g_autofree char *env = NULL;
+ str = g_strjoinv (" ", (char **)priv->argv->pdata);
env = priv->environ ? g_strjoinv (" ", priv->environ) : g_strdup ("");
IDE_TRACE_MSG ("Launching '%s' with environment %s %s parent environment",
str, env, priv->clear_env ? "clearing" : "inheriting");
}
#endif
- fds = g_steal_pointer (&priv->fd_mapping);
-
- if (priv->stdin_fd != -1)
- stdin_fd = dup (priv->stdin_fd);
-
- if (priv->stdout_fd != -1)
- stdout_fd = dup (priv->stdout_fd);
- else if (priv->stdout_file_path != NULL)
- stdout_fd = open (priv->stdout_file_path, O_WRONLY);
-
- if (priv->stderr_fd != -1)
- stderr_fd = dup (priv->stderr_fd);
-
- process = _ide_flatpak_subprocess_new (priv->cwd,
- (const gchar * const *)priv->argv->pdata,
- (const gchar * const *)priv->environ,
- priv->flags,
- priv->clear_env,
- stdin_fd,
- stdout_fd,
- stderr_fd,
- fds ? (gpointer)fds->data : NULL,
- fds ? fds->len : 0,
- cancellable,
- &error);
-
- if (process == NULL)
+ if (priv->stdout_file_path != NULL &&
+ !ide_unix_fd_map_open_file (priv->unix_fd_map,
+ priv->stdout_file_path, O_WRONLY, STDOUT_FILENO,
+ &error))
{
g_task_return_error (task, g_steal_pointer (&error));
IDE_EXIT;
}
- if (cancellable != NULL)
+ if (!(process = _ide_flatpak_subprocess_new (priv->cwd,
+ (const char * const *)priv->argv->pdata,
+ (const char * const *)priv->environ,
+ priv->flags,
+ priv->clear_env,
+ priv->unix_fd_map,
+ cancellable,
+ &error)))
{
- g_signal_connect_object (cancellable,
- "cancelled",
- G_CALLBACK (ide_subprocess_launcher_kill_host_process),
- process,
- 0);
+ g_task_return_error (task, g_steal_pointer (&error));
+ IDE_EXIT;
}
+ if (cancellable != NULL)
+ g_signal_connect_object (cancellable,
+ "cancelled",
+ G_CALLBACK (ide_subprocess_launcher_kill_host_process),
+ process,
+ 0);
+
g_task_return_pointer (task, g_steal_pointer (&process), g_object_unref);
IDE_EXIT;
@@ -283,6 +257,7 @@ ide_subprocess_launcher_spawn_worker (GTask *task,
g_autoptr(IdeSubprocess) wrapped = NULL;
g_autoptr(GError) error = NULL;
gpointer child_data = NULL;
+ guint length;
IDE_ENTRY;
@@ -292,10 +267,10 @@ ide_subprocess_launcher_spawn_worker (GTask *task,
child_data = GUINT_TO_POINTER (TRUE);
{
- g_autofree gchar *str = NULL;
- g_autofree gchar *env = NULL;
+ g_autofree char *str = NULL;
+ g_autofree char *env = NULL;
- str = g_strjoinv (" ", (gchar **)priv->argv->pdata);
+ str = g_strjoinv (" ", (char **)priv->argv->pdata);
env = priv->environ ? g_strjoinv (" ", priv->environ) : g_strdup ("");
g_debug ("Launching '%s' from directory '%s' with environment %s %s parent environment",
@@ -309,33 +284,22 @@ ide_subprocess_launcher_spawn_worker (GTask *task,
if (priv->stdout_file_path != NULL)
g_subprocess_launcher_set_stdout_file_path (launcher, priv->stdout_file_path);
- if (priv->stdin_fd != -1)
- {
- g_subprocess_launcher_take_stdin_fd (launcher, priv->stdin_fd);
- priv->stdin_fd = -1;
- }
-
- if (priv->stdout_fd != -1)
+ length = ide_unix_fd_map_get_length (priv->unix_fd_map);
+ for (guint i = 0; i < length; i++)
{
- g_subprocess_launcher_take_stdout_fd (launcher, priv->stdout_fd);
- priv->stdout_fd = -1;
- }
+ int source_fd;
+ int dest_fd;
- if (priv->stderr_fd != -1)
- {
- g_subprocess_launcher_take_stderr_fd (launcher, priv->stderr_fd);
- priv->stderr_fd = -1;
- }
-
- if (priv->fd_mapping != NULL)
- {
- g_autoptr(GArray) ar = g_steal_pointer (&priv->fd_mapping);
-
- for (guint i = 0; i < ar->len; i++)
+ if (-1 != (source_fd = ide_unix_fd_map_steal (priv->unix_fd_map, i, &dest_fd)))
{
- const FdMapping *map = &g_array_index (ar, FdMapping, i);
-
- g_subprocess_launcher_take_fd (launcher, map->source_fd, map->dest_fd);
+ if (dest_fd == STDIN_FILENO)
+ g_subprocess_launcher_take_stdin_fd (launcher, source_fd);
+ else if (dest_fd == STDOUT_FILENO)
+ g_subprocess_launcher_take_stdout_fd (launcher, source_fd);
+ else if (dest_fd == STDERR_FILENO)
+ g_subprocess_launcher_take_stderr_fd (launcher, source_fd);
+ else
+ g_subprocess_launcher_take_fd (launcher, source_fd, dest_fd);
}
}
@@ -347,8 +311,8 @@ ide_subprocess_launcher_spawn_worker (GTask *task,
*/
if (priv->clear_env)
{
- gchar *envp[] = { NULL };
- g_subprocess_launcher_set_environ (launcher, envp);
+ static const char *envp[] = { NULL };
+ g_subprocess_launcher_set_environ (launcher, (char **)envp);
}
/*
@@ -357,35 +321,30 @@ ide_subprocess_launcher_spawn_worker (GTask *task,
*/
if (priv->environ != NULL)
{
- for (guint i = 0; priv->environ[i] != NULL; i++)
+ for (guint i = 0; priv->environ[i]; i++)
{
- const gchar *pair = priv->environ[i];
- const gchar *eq = strchr (pair, '=');
- g_autofree gchar *key = g_strndup (pair, eq - pair);
- const gchar *val = eq ? eq + 1 : NULL;
+ g_autofree char *key = NULL;
+ g_autofree char *value = NULL;
- g_subprocess_launcher_setenv (launcher, key, val, TRUE);
+ if (ide_environ_parse (priv->environ[i], &key, &value))
+ g_subprocess_launcher_setenv (launcher, key, value, TRUE);
}
}
- real = g_subprocess_launcher_spawnv (launcher,
- (const gchar * const *)priv->argv->pdata,
- &error);
-
- if (real == NULL)
+ if (!(real = g_subprocess_launcher_spawnv (launcher,
+ (const char * const *)priv->argv->pdata,
+ &error)))
{
g_task_return_error (task, g_steal_pointer (&error));
IDE_EXIT;
}
if (cancellable != NULL)
- {
- g_signal_connect_object (cancellable,
- "cancelled",
- G_CALLBACK (ide_subprocess_launcher_kill_process_group),
- real,
- 0);
- }
+ g_signal_connect_object (cancellable,
+ "cancelled",
+ G_CALLBACK (ide_subprocess_launcher_kill_process_group),
+ real,
+ 0);
wrapped = ide_simple_subprocess_new (real);
@@ -448,42 +407,12 @@ ide_subprocess_launcher_finalize (GObject *object)
IdeSubprocessLauncher *self = (IdeSubprocessLauncher *)object;
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
- if (priv->fd_mapping != NULL)
- {
- for (guint i = 0; i < priv->fd_mapping->len; i++)
- {
- FdMapping *map = &g_array_index (priv->fd_mapping, FdMapping, i);
-
- if (map->source_fd != -1)
- close (map->source_fd);
- }
-
- g_clear_pointer (&priv->fd_mapping, g_array_unref);
- }
-
+ g_clear_object (&priv->unix_fd_map);
g_clear_pointer (&priv->argv, g_ptr_array_unref);
g_clear_pointer (&priv->cwd, g_free);
g_clear_pointer (&priv->environ, g_strfreev);
g_clear_pointer (&priv->stdout_file_path, g_free);
- if (priv->stdin_fd != -1)
- {
- close (priv->stdin_fd);
- priv->stdin_fd = -1;
- }
-
- if (priv->stdout_fd != -1)
- {
- close (priv->stdout_fd);
- priv->stdout_fd = -1;
- }
-
- if (priv->stderr_fd != -1)
- {
- close (priv->stderr_fd);
- priv->stderr_fd = -1;
- }
-
G_OBJECT_CLASS (ide_subprocess_launcher_parent_class)->finalize (object);
}
@@ -573,14 +502,14 @@ ide_subprocess_launcher_class_init (IdeSubprocessLauncherClass *klass)
"Clear Environment",
"If the environment should be cleared before setting environment variables.",
FALSE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
properties [PROP_CWD] =
g_param_spec_string ("cwd",
"Current Working Directory",
"Current Working Directory",
NULL,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
properties [PROP_FLAGS] =
g_param_spec_flags ("flags",
@@ -592,17 +521,17 @@ ide_subprocess_launcher_class_init (IdeSubprocessLauncherClass *klass)
properties [PROP_ENVIRON] =
g_param_spec_boxed ("environ",
- "Environ",
- "Environ",
+ "Environment",
+ "The environment variables for the subprocess",
G_TYPE_STRV,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
properties [PROP_RUN_ON_HOST] =
g_param_spec_boolean ("run-on-host",
"Run on Host",
"Run on Host",
FALSE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@@ -614,9 +543,7 @@ ide_subprocess_launcher_init (IdeSubprocessLauncher *self)
priv->clear_env = TRUE;
- priv->stdin_fd = -1;
- priv->stdout_fd = -1;
- priv->stderr_fd = -1;
+ priv->unix_fd_map = ide_unix_fd_map_new ();
priv->argv = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (priv->argv, NULL);
@@ -649,14 +576,14 @@ ide_subprocess_launcher_get_flags (IdeSubprocessLauncher *self)
return priv->flags;
}
-const gchar * const *
+const char * const *
ide_subprocess_launcher_get_environ (IdeSubprocessLauncher *self)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
g_return_val_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self), NULL);
- return (const gchar * const *)priv->environ;
+ return (const char * const *)priv->environ;
}
/**
@@ -669,22 +596,27 @@ ide_subprocess_launcher_get_environ (IdeSubprocessLauncher *self)
*/
void
ide_subprocess_launcher_set_environ (IdeSubprocessLauncher *self,
- const gchar * const *environ_)
+ const char * const *environ_)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
- if (priv->environ != (gchar **)environ_)
+ if (priv->environ == (char **)environ_)
+ return;
+
+ if ((priv->environ == NULL || environ_ == NULL) ||
+ !g_strv_equal ((const char * const *)priv->environ, environ_))
{
g_strfreev (priv->environ);
- priv->environ = g_strdupv ((gchar **)environ_);
+ priv->environ = g_strdupv ((char **)environ_);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ENVIRON]);
}
}
-const gchar *
+const char *
ide_subprocess_launcher_getenv (IdeSubprocessLauncher *self,
- const gchar *key)
+ const char *key)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
@@ -696,8 +628,8 @@ ide_subprocess_launcher_getenv (IdeSubprocessLauncher *self,
void
ide_subprocess_launcher_setenv (IdeSubprocessLauncher *self,
- const gchar *key,
- const gchar *value,
+ const char *key,
+ const char *value,
gboolean replace)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
@@ -713,7 +645,7 @@ ide_subprocess_launcher_setenv (IdeSubprocessLauncher *self,
void
ide_subprocess_launcher_push_argv (IdeSubprocessLauncher *self,
- const gchar *argv)
+ const char *argv)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
@@ -744,7 +676,7 @@ ide_subprocess_launcher_spawn (IdeSubprocessLauncher *self,
void
ide_subprocess_launcher_set_cwd (IdeSubprocessLauncher *self,
- const gchar *cwd)
+ const char *cwd)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
@@ -761,7 +693,7 @@ ide_subprocess_launcher_set_cwd (IdeSubprocessLauncher *self,
}
}
-const gchar *
+const char *
ide_subprocess_launcher_get_cwd (IdeSubprocessLauncher *self)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
@@ -785,8 +717,8 @@ ide_subprocess_launcher_overlay_environment (IdeSubprocessLauncher *self,
for (guint i = 0; i < n_items; i++)
{
g_autoptr(IdeEnvironmentVariable) var = NULL;
- const gchar *key;
- const gchar *value;
+ const char *key;
+ const char *value;
var = g_list_model_get_item (G_LIST_MODEL (environment), i);
key = ide_environment_variable_get_key (var);
@@ -810,7 +742,7 @@ ide_subprocess_launcher_overlay_environment (IdeSubprocessLauncher *self,
*/
void
ide_subprocess_launcher_push_args (IdeSubprocessLauncher *self,
- const gchar * const *args)
+ const char * const *args)
{
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
@@ -821,11 +753,11 @@ ide_subprocess_launcher_push_args (IdeSubprocessLauncher *self,
}
}
-gchar *
+char *
ide_subprocess_launcher_pop_argv (IdeSubprocessLauncher *self)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
- gchar *ret = NULL;
+ char *ret = NULL;
g_return_val_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self), NULL);
@@ -913,50 +845,36 @@ ide_subprocess_launcher_set_clear_env (IdeSubprocessLauncher *self,
void
ide_subprocess_launcher_take_stdin_fd (IdeSubprocessLauncher *self,
- gint stdin_fd)
+ int stdin_fd)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
+ g_autoptr(GError) error = NULL;
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
- if (priv->stdin_fd != stdin_fd)
- {
- if (priv->stdin_fd != -1)
- close (priv->stdin_fd);
- priv->stdin_fd = stdin_fd;
- }
+ ide_unix_fd_map_take (priv->unix_fd_map, stdin_fd, STDIN_FILENO);
}
void
ide_subprocess_launcher_take_stdout_fd (IdeSubprocessLauncher *self,
- gint stdout_fd)
+ int stdout_fd)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
- if (priv->stdout_fd != stdout_fd)
- {
- if (priv->stdout_fd != -1)
- close (priv->stdout_fd);
- priv->stdout_fd = stdout_fd;
- }
+ ide_unix_fd_map_take (priv->unix_fd_map, stdout_fd, STDOUT_FILENO);
}
void
ide_subprocess_launcher_take_stderr_fd (IdeSubprocessLauncher *self,
- gint stderr_fd)
+ int stderr_fd)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
- if (priv->stderr_fd != stderr_fd)
- {
- if (priv->stderr_fd != -1)
- close (priv->stderr_fd);
- priv->stderr_fd = stderr_fd;
- }
+ ide_unix_fd_map_take (priv->unix_fd_map, stderr_fd, STDERR_FILENO);
}
/**
@@ -970,7 +888,7 @@ ide_subprocess_launcher_take_stderr_fd (IdeSubprocessLauncher *self,
*/
void
ide_subprocess_launcher_set_argv (IdeSubprocessLauncher *self,
- const gchar * const *args)
+ const char * const *args)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
@@ -987,20 +905,20 @@ ide_subprocess_launcher_set_argv (IdeSubprocessLauncher *self,
g_ptr_array_add (priv->argv, NULL);
}
-const gchar * const *
+const char * const *
ide_subprocess_launcher_get_argv (IdeSubprocessLauncher *self)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
g_return_val_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self), NULL);
- return (const gchar * const *)priv->argv->pdata;
+ return (const char * const *)priv->argv->pdata;
}
void
ide_subprocess_launcher_insert_argv (IdeSubprocessLauncher *self,
guint index,
- const gchar *arg)
+ const char *arg)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
@@ -1015,10 +933,10 @@ ide_subprocess_launcher_insert_argv (IdeSubprocessLauncher *self,
void
ide_subprocess_launcher_replace_argv (IdeSubprocessLauncher *self,
guint index,
- const gchar *arg)
+ const char *arg)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
- gchar *old_arg;
+ char *old_arg;
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
g_return_if_fail (priv->argv->len > 0);
@@ -1033,28 +951,21 @@ ide_subprocess_launcher_replace_argv (IdeSubprocessLauncher *self,
void
ide_subprocess_launcher_take_fd (IdeSubprocessLauncher *self,
- gint source_fd,
- gint dest_fd)
+ int source_fd,
+ int dest_fd)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
- FdMapping map = {
- .source_fd = source_fd,
- .dest_fd = dest_fd
- };
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
g_return_if_fail (source_fd > -1);
g_return_if_fail (dest_fd > -1);
- if (priv->fd_mapping == NULL)
- priv->fd_mapping = g_array_new (FALSE, FALSE, sizeof (FdMapping));
-
- g_array_append_val (priv->fd_mapping, map);
+ ide_unix_fd_map_take (priv->unix_fd_map, source_fd, dest_fd);
}
void
ide_subprocess_launcher_set_stdout_file_path (IdeSubprocessLauncher *self,
- const gchar *stdout_file_path)
+ const char *stdout_file_path)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
@@ -1069,9 +980,9 @@ ide_subprocess_launcher_set_stdout_file_path (IdeSubprocessLauncher *self,
void
ide_subprocess_launcher_prepend_path (IdeSubprocessLauncher *self,
- const gchar *path)
+ const char *path)
{
- const gchar *old_path;
+ const char *old_path;
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
@@ -1082,7 +993,7 @@ ide_subprocess_launcher_prepend_path (IdeSubprocessLauncher *self,
if (old_path != NULL)
{
- g_autofree gchar *new_path = g_strdup_printf ("%s:%s", path, old_path);
+ g_autofree char *new_path = g_strdup_printf ("%s:%s", path, old_path);
ide_subprocess_launcher_setenv (self, "PATH", new_path, TRUE);
}
else
@@ -1093,9 +1004,9 @@ ide_subprocess_launcher_prepend_path (IdeSubprocessLauncher *self,
void
ide_subprocess_launcher_append_path (IdeSubprocessLauncher *self,
- const gchar *path)
+ const char *path)
{
- const gchar *old_path;
+ const char *old_path;
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
@@ -1106,7 +1017,7 @@ ide_subprocess_launcher_append_path (IdeSubprocessLauncher *self,
if (old_path != NULL)
{
- g_autofree gchar *new_path = g_strdup_printf ("%s:%s", old_path, path);
+ g_autofree char *new_path = g_strdup_printf ("%s:%s", old_path, path);
ide_subprocess_launcher_setenv (self, "PATH", new_path, TRUE);
}
else
@@ -1121,34 +1032,11 @@ ide_subprocess_launcher_get_needs_tty (IdeSubprocessLauncher *self)
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
g_return_val_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self), FALSE);
+ g_return_val_if_fail (IDE_IS_UNIX_FD_MAP (priv->unix_fd_map), FALSE);
- if ((priv->stdin_fd != -1 && isatty (priv->stdin_fd)) ||
- (priv->stdout_fd != -1 && isatty (priv->stdout_fd)) ||
- (priv->stderr_fd != -1 && isatty (priv->stderr_fd)))
- return TRUE;
-
- if (priv->fd_mapping != NULL)
- {
- for (guint i = 0; i < priv->fd_mapping->len; i++)
- {
- const FdMapping *fdmap = &g_array_index (priv->fd_mapping, FdMapping, i);
-
- switch (fdmap->dest_fd)
- {
- case STDIN_FILENO:
- case STDOUT_FILENO:
- case STDERR_FILENO:
- if (isatty (fdmap->source_fd))
- return TRUE;
- break;
-
- default:
- break;
- }
- }
- }
-
- return FALSE;
+ return ide_unix_fd_map_stdin_isatty (priv->unix_fd_map) ||
+ ide_unix_fd_map_stdout_isatty (priv->unix_fd_map) ||
+ ide_unix_fd_map_stderr_isatty (priv->unix_fd_map);
}
/**
@@ -1162,29 +1050,18 @@ ide_subprocess_launcher_get_needs_tty (IdeSubprocessLauncher *self)
*
* Returns: an integer for the max-fd
*/
-gint
+int
ide_subprocess_launcher_get_max_fd (IdeSubprocessLauncher *self)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
- gint max_fd = 2;
-
- g_return_val_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self), 2);
- if (priv->fd_mapping != NULL)
- {
- for (guint i = 0; i < priv->fd_mapping->len; i++)
- {
- const FdMapping *map = &g_array_index (priv->fd_mapping, FdMapping, i);
-
- if (map->dest_fd > max_fd)
- max_fd = map->dest_fd;
- }
- }
+ g_return_val_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self), -1);
+ g_return_val_if_fail (IDE_IS_UNIX_FD_MAP (priv->unix_fd_map), -1);
- return max_fd;
+ return ide_unix_fd_map_get_max_dest_fd (priv->unix_fd_map);
}
-const gchar *
+const char *
ide_subprocess_launcher_get_arg (IdeSubprocessLauncher *self,
guint pos)
{
@@ -1203,7 +1080,7 @@ ide_subprocess_launcher_join_args_for_sh_c (IdeSubprocessLauncher *self,
guint start_pos)
{
IdeSubprocessLauncherPrivate *priv = ide_subprocess_launcher_get_instance_private (self);
- const gchar * const *argv;
+ const char * const *argv;
GString *str;
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (self));
@@ -1214,7 +1091,7 @@ ide_subprocess_launcher_join_args_for_sh_c (IdeSubprocessLauncher *self,
for (guint i = start_pos; argv[i] != NULL; i++)
{
- g_autofree gchar *quoted_string = g_shell_quote (argv[i]);
+ g_autofree char *quoted_string = g_shell_quote (argv[i]);
if (i > 0)
g_string_append_c (str, ' ');
@@ -1238,8 +1115,8 @@ ide_subprocess_launcher_join_args_for_sh_c (IdeSubprocessLauncher *self,
* ide_subprocess_launcher_push_argv() and then freed.
*/
void
-ide_subprocess_launcher_push_argv_format (IdeSubprocessLauncher *self,
- const char *format,
+ide_subprocess_launcher_push_argv_format (IdeSubprocessLauncher *self,
+ const char *format,
...)
{
g_autofree char *arg = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]