[gnome-builder] pty: use blocking mode for external PTY slave FDs



commit 5f68339b08f7f48c51b547bee0686e78202a8bda
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jan 29 21:17:49 2018 -0800

    pty: use blocking mode for external PTY slave FDs
    
    We need non-blocking for the slave FD used internally in our proxy, but we
    do not need non-blocking mode for the slave FD passed to the subprocess.
    Otherwise, we can get write errors from applications that are not prepared
    to handle non-blocking stdin/stdout/stderr.
    
    This fixes and closes #358

 src/libide/buildsystem/ide-build-pipeline.c |  2 +-
 src/libide/terminal/ide-terminal-util.c     |  2 +-
 src/libide/util/ptyintercept.c              | 16 +++++++++++-----
 src/libide/util/ptyintercept.h              |  3 ++-
 4 files changed, 15 insertions(+), 8 deletions(-)
---
diff --git a/src/libide/buildsystem/ide-build-pipeline.c b/src/libide/buildsystem/ide-build-pipeline.c
index 7136af5f3..e046ff776 100644
--- a/src/libide/buildsystem/ide-build-pipeline.c
+++ b/src/libide/buildsystem/ide-build-pipeline.c
@@ -2517,7 +2517,7 @@ ide_build_pipeline_attach_pty (IdeBuildPipeline      *self,
   if (self->pty_slave == -1)
     {
       pty_fd_t master_fd = pty_intercept_get_fd (&self->intercept);
-      self->pty_slave = pty_intercept_create_slave (master_fd);
+      self->pty_slave = pty_intercept_create_slave (master_fd, TRUE);
     }
 
   if (self->pty_slave == -1)
diff --git a/src/libide/terminal/ide-terminal-util.c b/src/libide/terminal/ide-terminal-util.c
index 5f37d38b1..2446da967 100644
--- a/src/libide/terminal/ide-terminal-util.c
+++ b/src/libide/terminal/ide-terminal-util.c
@@ -38,5 +38,5 @@ ide_vte_pty_create_slave (VtePty *pty)
   if (master_fd == PTY_FD_INVALID)
     return PTY_FD_INVALID;
 
-  return pty_intercept_create_slave (master_fd);
+  return pty_intercept_create_slave (master_fd, TRUE);
 }
diff --git a/src/libide/util/ptyintercept.c b/src/libide/util/ptyintercept.c
index 2756287d8..69b16c41f 100644
--- a/src/libide/util/ptyintercept.c
+++ b/src/libide/util/ptyintercept.c
@@ -80,6 +80,7 @@ _pty_intercept_set_raw (pty_fd_t fd)
 /**
  * pty_intercept_create_slave:
  * @master_fd: a pty master
+ * @blocking: use %FALSE to set O_NONBLOCK
  *
  * This creates a new slave to the PTY master @master_fd.
  *
@@ -90,9 +91,11 @@ _pty_intercept_set_raw (pty_fd_t fd)
  *   Upon error, %PTY_FD_INVALID (-1) is returned.
  */
 pty_fd_t
-pty_intercept_create_slave (pty_fd_t master_fd)
+pty_intercept_create_slave (pty_fd_t master_fd,
+                            gboolean blocking)
 {
   g_auto(pty_fd_t) ret = PTY_FD_INVALID;
+  gint extra = blocking ? 0 : O_NONBLOCK;
 #ifdef HAVE_PTSNAME_R
   char name[256];
 #else
@@ -116,7 +119,7 @@ pty_intercept_create_slave (pty_fd_t master_fd)
     return PTY_FD_INVALID;
 #endif
 
-  ret =  open (name, O_RDWR | O_CLOEXEC | O_NONBLOCK);
+  ret = open (name, O_RDWR | O_CLOEXEC | extra);
 
   if (ret == PTY_FD_INVALID && errno == EINVAL)
     {
@@ -137,8 +140,11 @@ pty_intercept_create_slave (pty_fd_t master_fd)
             return PTY_FD_INVALID;
         }
 
-      if (!g_unix_set_fd_nonblocking (ret, TRUE, NULL))
-        return PTY_FD_INVALID;
+      if (!blocking)
+        {
+          if (!g_unix_set_fd_nonblocking (ret, TRUE, NULL))
+            return PTY_FD_INVALID;
+        }
     }
 
   return pty_fd_steal (&ret);
@@ -455,7 +461,7 @@ pty_intercept_init (pty_intercept_t *self,
   memset (self, 0, sizeof *self);
   self->magic = PTY_INTERCEPT_MAGIC;
 
-  slave_fd = pty_intercept_create_slave (fd);
+  slave_fd = pty_intercept_create_slave (fd, FALSE);
   if (slave_fd == PTY_FD_INVALID)
     return FALSE;
 
diff --git a/src/libide/util/ptyintercept.h b/src/libide/util/ptyintercept.h
index 3138863dd..23b238027 100644
--- a/src/libide/util/ptyintercept.h
+++ b/src/libide/util/ptyintercept.h
@@ -77,7 +77,8 @@ pty_fd_clear (pty_fd_t *fd)
 G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (pty_fd_t, pty_fd_clear)
 
 pty_fd_t pty_intercept_create_master (void);
-pty_fd_t pty_intercept_create_slave  (pty_fd_t                  master_fd);
+pty_fd_t pty_intercept_create_slave  (pty_fd_t                  master_fd,
+                                      gboolean                  blocking);
 gboolean pty_intercept_init          (pty_intercept_t          *self,
                                       pty_fd_t                  fd,
                                       GMainContext             *main_context);


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