[gnome-builder] foundry: allow specifying child TTY fd directly



commit 789a673f4860d066202faf7d5a64717b96195aa2
Author: Christian Hergert <chergert redhat com>
Date:   Sat Apr 27 16:13:20 2019 -0700

    foundry: allow specifying child TTY fd directly

 src/libide/foundry/ide-runner.c | 53 +++++++++++++++++++++++++++++++----------
 src/libide/foundry/ide-runner.h |  3 +++
 2 files changed, 44 insertions(+), 12 deletions(-)
---
diff --git a/src/libide/foundry/ide-runner.c b/src/libide/foundry/ide-runner.c
index d79d586de..069463c5a 100644
--- a/src/libide/foundry/ide-runner.c
+++ b/src/libide/foundry/ide-runner.c
@@ -56,6 +56,7 @@ typedef struct
   GSubprocessFlags flags;
 
   VtePty *pty;
+  gint child_fd;
 
   guint clear_env : 1;
   guint failed : 1;
@@ -253,26 +254,34 @@ 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->pty != NULL && !priv->disable_pty)
+  if (!priv->disable_pty && (priv->child_fd != -1 || priv->pty != NULL))
     {
-      gint master_fd;
-      gint tty_fd;
+      if (priv->child_fd == -1)
+        {
+          gint master_fd;
+          gint tty_fd;
+
+          g_assert (priv->pty != NULL);
+
+          master_fd = vte_pty_get_fd (priv->pty);
 
-      master_fd = vte_pty_get_fd (priv->pty);
-      tty_fd = ide_pty_intercept_create_slave (master_fd, TRUE);
+          errno = 0;
+          if (-1 == (tty_fd = ide_pty_intercept_create_slave (master_fd, TRUE)))
+            g_critical ("Failed to create TTY device: %s", g_strerror (errno));
 
-      IDE_TRACE_MSG ("Setting TTY fd to %d", tty_fd);
+          g_assert (tty_fd == -1 || isatty (tty_fd));
+
+          ide_runner_take_tty_fd (self, tty_fd);
+        }
 
       if (!(priv->flags & G_SUBPROCESS_FLAGS_STDIN_PIPE))
-        ide_subprocess_launcher_take_stdin_fd (launcher, dup (tty_fd));
+        ide_subprocess_launcher_take_stdin_fd (launcher, dup (priv->child_fd));
 
       if (!(priv->flags & (G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDOUT_SILENCE)))
-        ide_subprocess_launcher_take_stdout_fd (launcher, dup (tty_fd));
+        ide_subprocess_launcher_take_stdout_fd (launcher, dup (priv->child_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);
+        ide_subprocess_launcher_take_stderr_fd (launcher, dup (priv->child_fd));
     }
 
   /*
@@ -472,6 +481,12 @@ ide_runner_finalize (GObject *object)
   g_clear_object (&priv->subprocess);
   g_clear_object (&priv->build_target);
 
+  if (priv->child_fd != -1)
+    {
+      close (priv->child_fd);
+      priv->child_fd = -1;
+    }
+
   if (priv->fd_mapping != NULL)
     {
       for (guint i = 0; i < priv->fd_mapping->len; i++)
@@ -716,7 +731,7 @@ ide_runner_init (IdeRunner *self)
   g_queue_init (&priv->argv);
 
   priv->env = ide_environment_new ();
-
+  priv->child_fd = -1;
   priv->flags = 0;
 }
 
@@ -1475,3 +1490,17 @@ ide_runner_set_disable_pty (IdeRunner *self,
       g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DISABLE_PTY]);
     }
 }
+
+void
+ide_runner_take_tty_fd (IdeRunner *self,
+                        gint       tty_fd)
+{
+  IdeRunnerPrivate *priv = ide_runner_get_instance_private (self);
+
+  g_return_if_fail (IDE_IS_RUNNER (self));
+  g_return_if_fail (tty_fd > -1);
+
+  if (priv->child_fd != -1)
+    close (priv->child_fd);
+  priv->child_fd = tty_fd;
+}
diff --git a/src/libide/foundry/ide-runner.h b/src/libide/foundry/ide-runner.h
index 737a2da3a..f933a04d3 100644
--- a/src/libide/foundry/ide-runner.h
+++ b/src/libide/foundry/ide-runner.h
@@ -127,6 +127,9 @@ gboolean           ide_runner_get_run_on_host  (IdeRunner            *self);
 IDE_AVAILABLE_IN_3_32
 void               ide_runner_set_run_on_host  (IdeRunner            *self,
                                                 gboolean              run_on_host);
+IDE_AVAILABLE_IN_3_34
+void               ide_runner_take_tty_fd      (IdeRunner            *self,
+                                                gint                  tty_fd);
 IDE_AVAILABLE_IN_3_32
 void               ide_runner_set_pty          (IdeRunner            *self,
                                                 VtePty               *pty);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]