[gnome-builder] foundry: simplify PTY usage in IdeRunner
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] foundry: simplify PTY usage in IdeRunner
- Date: Sat, 27 Apr 2019 20:17:11 +0000 (UTC)
commit 99dd4fb4334aead217d716c57a729b855360eec4
Author: Christian Hergert <chergert redhat com>
Date: Sat Apr 27 13:16:11 2019 -0700
foundry: simplify PTY usage in IdeRunner
Rather than using FDs directly, we can just use a VtePty and allow
consumers to create the child side of the PTY as necessary.
src/libide/foundry/ide-runner.c | 171 ++++++++++-----------
src/libide/foundry/ide-runner.h | 14 +-
src/libide/terminal/ide-terminal-page.c | 10 +-
src/plugins/gdb/gbp-gdb-debugger.c | 22 ++-
.../terminal/gbp-terminal-workspace-addin.c | 7 +-
5 files changed, 114 insertions(+), 110 deletions(-)
---
diff --git a/src/libide/foundry/ide-runner.c b/src/libide/foundry/ide-runner.c
index 58454a1ac..d79d586de 100644
--- a/src/libide/foundry/ide-runner.c
+++ b/src/libide/foundry/ide-runner.c
@@ -55,11 +55,12 @@ typedef struct
GSubprocessFlags flags;
- int tty_fd;
+ VtePty *pty;
guint clear_env : 1;
guint failed : 1;
guint run_on_host : 1;
+ guint disable_pty : 1;
} IdeRunnerPrivate;
typedef struct
@@ -77,12 +78,13 @@ typedef struct
enum {
PROP_0,
PROP_ARGV,
+ PROP_BUILD_TARGET,
PROP_CLEAR_ENV,
PROP_CWD,
+ PROP_DISABLE_PTY,
PROP_ENV,
PROP_FAILED,
PROP_RUN_ON_HOST,
- PROP_BUILD_TARGET,
N_PROPS
};
@@ -251,12 +253,26 @@ ide_runner_real_run_async (IdeRunner *self,
* If we have a tty_fd set, then we want to override our stdin,
* stdout, and stderr fds with our TTY.
*/
- if (priv->tty_fd != -1)
+ if (priv->pty != NULL && !priv->disable_pty)
{
- IDE_TRACE_MSG ("Setting TTY fd to %d", priv->tty_fd);
- ide_subprocess_launcher_take_stdin_fd (launcher, dup (priv->tty_fd));
- ide_subprocess_launcher_take_stdout_fd (launcher, dup (priv->tty_fd));
- ide_subprocess_launcher_take_stderr_fd (launcher, dup (priv->tty_fd));
+ gint master_fd;
+ gint tty_fd;
+
+ master_fd = vte_pty_get_fd (priv->pty);
+ tty_fd = ide_pty_intercept_create_slave (master_fd, TRUE);
+
+ IDE_TRACE_MSG ("Setting TTY fd to %d", tty_fd);
+
+ if (!(priv->flags & G_SUBPROCESS_FLAGS_STDIN_PIPE))
+ ide_subprocess_launcher_take_stdin_fd (launcher, dup (tty_fd));
+
+ if (!(priv->flags & (G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDOUT_SILENCE)))
+ ide_subprocess_launcher_take_stdout_fd (launcher, dup (tty_fd));
+
+ if (!(priv->flags & (G_SUBPROCESS_FLAGS_STDERR_PIPE | G_SUBPROCESS_FLAGS_STDERR_SILENCE)))
+ ide_subprocess_launcher_take_stderr_fd (launcher, dup (tty_fd));
+
+ close (tty_fd);
}
/*
@@ -368,46 +384,6 @@ ide_runner_real_get_stderr (IdeRunner *self)
return NULL;
}
-gint
-ide_runner_steal_tty (IdeRunner *self)
-{
- IdeRunnerPrivate *priv = ide_runner_get_instance_private (self);
- gint fd;
-
- g_return_val_if_fail (IDE_IS_RUNNER (self), -1);
-
- fd = priv->tty_fd;
- priv->tty_fd = -1;
-
- return fd;
-}
-
-static void
-ide_runner_real_set_tty (IdeRunner *self,
- int tty_fd)
-{
- IdeRunnerPrivate *priv = ide_runner_get_instance_private (self);
-
- g_assert (IDE_IS_RUNNER (self));
- g_assert (tty_fd >= -1);
-
- if (tty_fd != priv->tty_fd)
- {
- if (priv->tty_fd != -1)
- {
- close (priv->tty_fd);
- priv->tty_fd = -1;
- }
-
- if (tty_fd != -1)
- {
- priv->tty_fd = dup (tty_fd);
- if (priv->tty_fd == -1)
- g_warning ("Failed to dup() tty_fd: %s", g_strerror (errno));
- }
- }
-}
-
static void
ide_runner_real_force_quit (IdeRunner *self)
{
@@ -511,12 +487,7 @@ ide_runner_finalize (GObject *object)
}
g_clear_pointer (&priv->fd_mapping, g_array_unref);
-
- if (priv->tty_fd != -1)
- {
- close (priv->tty_fd);
- priv->tty_fd = -1;
- }
+ g_clear_object (&priv->pty);
G_OBJECT_CLASS (ide_runner_parent_class)->finalize (object);
}
@@ -543,6 +514,10 @@ ide_runner_get_property (GObject *object,
g_value_set_string (value, ide_runner_get_cwd (self));
break;
+ case PROP_DISABLE_PTY:
+ g_value_set_boolean (value, ide_runner_get_disable_pty (self));
+ break;
+
case PROP_ENV:
g_value_set_object (value, ide_runner_get_environment (self));
break;
@@ -586,6 +561,10 @@ ide_runner_set_property (GObject *object,
ide_runner_set_cwd (self, g_value_get_string (value));
break;
+ case PROP_DISABLE_PTY:
+ ide_runner_set_disable_pty (self, g_value_get_boolean (value));
+ break;
+
case PROP_FAILED:
ide_runner_set_failed (self, g_value_get_boolean (value));
break;
@@ -615,7 +594,6 @@ ide_runner_class_init (IdeRunnerClass *klass)
klass->run_async = ide_runner_real_run_async;
klass->run_finish = ide_runner_real_run_finish;
- klass->set_tty = ide_runner_real_set_tty;
klass->create_launcher = ide_runner_real_create_launcher;
klass->get_stdin = ide_runner_real_get_stdin;
klass->get_stdout = ide_runner_real_get_stdout;
@@ -643,6 +621,13 @@ ide_runner_class_init (IdeRunnerClass *klass)
NULL,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+ properties [PROP_DISABLE_PTY] =
+ g_param_spec_boolean ("disable-pty",
+ "Disable PTY",
+ "If the pty should be disabled from use",
+ FALSE,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
properties [PROP_ENV] =
g_param_spec_object ("environment",
"Environment",
@@ -733,7 +718,6 @@ ide_runner_init (IdeRunner *self)
priv->env = ide_environment_new ();
priv->flags = 0;
- priv->tty_fd = -1;
}
/**
@@ -1184,27 +1168,6 @@ ide_runner_set_clear_env (IdeRunner *self,
}
}
-void
-ide_runner_set_tty (IdeRunner *self,
- int tty_fd)
-{
- IDE_ENTRY;
-
- g_return_if_fail (IDE_IS_RUNNER (self));
- g_return_if_fail (tty_fd >= -1);
-
- if (IDE_RUNNER_GET_CLASS (self)->set_tty)
- {
- IDE_RUNNER_GET_CLASS (self)->set_tty (self, tty_fd);
- return;
- }
-
- g_warning ("%s does not support setting a TTY fd",
- G_OBJECT_TYPE_NAME (self));
-
- IDE_EXIT;
-}
-
/**
* ide_runner_set_pty:
* @self: a #IdeRunner
@@ -1221,23 +1184,32 @@ void
ide_runner_set_pty (IdeRunner *self,
VtePty *pty)
{
- int child_fd = -1;
+ IdeRunnerPrivate *priv = ide_runner_get_instance_private (self);
g_return_if_fail (IDE_IS_RUNNER (self));
g_return_if_fail (!pty || VTE_IS_PTY (pty));
- if (pty != NULL)
- {
- int parent_fd = vte_pty_get_fd (pty);
+ g_set_object (&priv->pty, pty);
+}
- if (parent_fd != -1)
- child_fd = ide_pty_intercept_create_slave (parent_fd, TRUE);
- }
+/**
+ * ide_runner_get_pty:
+ * @self: a #IdeRunner
+ *
+ * Gets the #VtePty that was assigned.
+ *
+ * Returns: (nullable) (transfer none): a #VtePty or %NULL
+ *
+ * Since: 3.34
+ */
+VtePty *
+ide_runner_get_pty (IdeRunner *self)
+{
+ IdeRunnerPrivate *priv = ide_runner_get_instance_private (self);
- ide_runner_set_tty (self, child_fd);
+ g_return_val_if_fail (IDE_IS_RUNNER (self), NULL);
- if (child_fd != -1)
- close (child_fd);
+ return priv->pty;
}
static gint
@@ -1476,3 +1448,30 @@ ide_runner_set_build_target (IdeRunner *self,
if (g_set_object (&priv->build_target, build_target))
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BUILD_TARGET]);
}
+
+gboolean
+ide_runner_get_disable_pty (IdeRunner *self)
+{
+ IdeRunnerPrivate *priv = ide_runner_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_RUNNER (self), FALSE);
+
+ return priv->disable_pty;
+}
+
+void
+ide_runner_set_disable_pty (IdeRunner *self,
+ gboolean disable_pty)
+{
+ IdeRunnerPrivate *priv = ide_runner_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_RUNNER (self));
+
+ disable_pty = !!disable_pty;
+
+ if (disable_pty != priv->disable_pty)
+ {
+ priv->disable_pty = disable_pty;
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DISABLE_PTY]);
+ }
+}
diff --git a/src/libide/foundry/ide-runner.h b/src/libide/foundry/ide-runner.h
index 99698eaa8..737a2da3a 100644
--- a/src/libide/foundry/ide-runner.h
+++ b/src/libide/foundry/ide-runner.h
@@ -52,8 +52,6 @@ struct _IdeRunnerClass
gboolean (*run_finish) (IdeRunner *self,
GAsyncResult *result,
GError **error);
- void (*set_tty) (IdeRunner *self,
- int tty_fd);
IdeSubprocessLauncher *(*create_launcher) (IdeRunner *self);
void (*fixup_launcher) (IdeRunner *self,
IdeSubprocessLauncher *launcher);
@@ -132,11 +130,13 @@ void ide_runner_set_run_on_host (IdeRunner *self,
IDE_AVAILABLE_IN_3_32
void ide_runner_set_pty (IdeRunner *self,
VtePty *pty);
-IDE_AVAILABLE_IN_3_32
-void ide_runner_set_tty (IdeRunner *self,
- int tty_fd);
-IDE_AVAILABLE_IN_3_32
-gint ide_runner_steal_tty (IdeRunner *self);
+IDE_AVAILABLE_IN_3_34
+VtePty *ide_runner_get_pty (IdeRunner *self);
+IDE_AVAILABLE_IN_3_34
+gboolean ide_runner_get_disable_pty (IdeRunner *self);
+IDE_AVAILABLE_IN_3_34
+void ide_runner_set_disable_pty (IdeRunner *self,
+ gboolean disable_pty);
IDE_AVAILABLE_IN_3_32
IdeBuildTarget *ide_runner_get_build_target (IdeRunner *self);
IDE_AVAILABLE_IN_3_32
diff --git a/src/libide/terminal/ide-terminal-page.c b/src/libide/terminal/ide-terminal-page.c
index 504810647..973d7f0d9 100644
--- a/src/libide/terminal/ide-terminal-page.c
+++ b/src/libide/terminal/ide-terminal-page.c
@@ -230,9 +230,6 @@ gbp_terminal_respawn (IdeTerminalPage *self,
vte_terminal_set_pty (terminal, pty);
- if (-1 == (tty_fd = ide_vte_pty_create_slave (pty)))
- IDE_GOTO (cleanup);
-
if (self->runtime != NULL &&
!ide_runtime_contains_program_in_path (self->runtime, shell, NULL))
{
@@ -260,8 +257,7 @@ gbp_terminal_respawn (IdeTerminalPage *self,
{
IdeEnvironment *env = ide_runner_get_environment (runner);
- /* set_tty() will dup() the fd */
- ide_runner_set_tty (runner, tty_fd);
+ ide_runner_set_pty (runner, pty);
ide_environment_setenv (env, "TERM", "xterm-256color");
ide_environment_setenv (env, "INSIDE_GNOME_BUILDER", PACKAGE_VERSION);
@@ -281,6 +277,10 @@ gbp_terminal_respawn (IdeTerminalPage *self,
}
}
+ if (-1 == (tty_fd = ide_vte_pty_create_slave (pty)))
+ IDE_GOTO (cleanup);
+
+
/* dup() is safe as it will inherit O_CLOEXEC */
if (-1 == (stdout_fd = dup (tty_fd)) || -1 == (stderr_fd = dup (tty_fd)))
IDE_GOTO (cleanup);
diff --git a/src/plugins/gdb/gbp-gdb-debugger.c b/src/plugins/gdb/gbp-gdb-debugger.c
index 5fc516dad..70c249b84 100644
--- a/src/plugins/gdb/gbp-gdb-debugger.c
+++ b/src/plugins/gdb/gbp-gdb-debugger.c
@@ -2345,7 +2345,7 @@ gbp_gdb_debugger_prepare (IdeDebugger *debugger,
{
static const gchar *prepend_argv[] = { "gdb", "--interpreter=mi2", "--args" };
GbpGdbDebugger *self = (GbpGdbDebugger *)debugger;
- int tty_fd;
+ VtePty *pty;
IDE_ENTRY;
@@ -2360,12 +2360,21 @@ gbp_gdb_debugger_prepare (IdeDebugger *debugger,
dzl_signal_group_set_target (self->runner_signals, runner);
/*
- * We steal and remap the PTY fd into the process so that gdb does not get
- * the controlling terminal, but instead allow us to ask gdb to setup the
- * inferior with that same PTY.
+ * If there is a PTY device to display the contents of the inferior, then
+ * we will create a new FD for that from the PTY and save it to map into
+ * the inferior.
*/
- if (-1 != (tty_fd = ide_runner_steal_tty (runner)))
- self->mapped_fd = ide_runner_take_fd (runner, tty_fd, -1);
+ if ((pty = ide_runner_get_pty (runner)))
+ {
+ int master_fd = vte_pty_get_fd (pty);
+ int tty_fd = ide_pty_intercept_create_slave (master_fd, TRUE);
+
+ if (tty_fd != -1)
+ {
+ self->mapped_fd = ide_runner_take_fd (runner, tty_fd, -1);
+ ide_runner_set_disable_pty (runner, TRUE);
+ }
+ }
/* We need access to stdin/stdout for communicating with gdb */
ide_runner_set_flags (runner, G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE |
G_SUBPROCESS_FLAGS_STDERR_SILENCE);
@@ -2512,6 +2521,7 @@ gbp_gdb_debugger_init (GbpGdbDebugger *self)
self->parser = gdbwire_mi_parser_create (callbacks);
self->read_cancellable = g_cancellable_new ();
self->read_buffer = g_malloc (READ_BUFFER_LEN);
+ self->mapped_fd = -1;
g_queue_init (&self->cmdqueue);
diff --git a/src/plugins/terminal/gbp-terminal-workspace-addin.c
b/src/plugins/terminal/gbp-terminal-workspace-addin.c
index 1cb9a8332..14c170186 100644
--- a/src/plugins/terminal/gbp-terminal-workspace-addin.c
+++ b/src/plugins/terminal/gbp-terminal-workspace-addin.c
@@ -175,7 +175,6 @@ on_run_manager_run (GbpTerminalWorkspaceAddin *self,
{
IdeEnvironment *env;
VtePty *pty = NULL;
- int tty_fd;
g_autoptr(GDateTime) now = NULL;
g_autofree gchar *formatted = NULL;
g_autofree gchar *tmp = NULL;
@@ -239,11 +238,7 @@ on_run_manager_run (GbpTerminalWorkspaceAddin *self,
ide_terminal_page_set_pty (self->run_terminal, pty);
}
- if (-1 != (tty_fd = ide_vte_pty_create_slave (pty)))
- {
- ide_runner_set_tty (runner, tty_fd);
- close (tty_fd);
- }
+ ide_runner_set_pty (runner, pty);
env = ide_runner_get_environment (runner);
ide_environment_setenv (env, "TERM", "xterm-256color");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]