From 1307af30ec3e2bfaeeca45a63fbc944791662226 Mon Sep 17 00:00:00 2001
From: Jonas Faklkevik <jonas.falkevik@gmail.com>
Date: Mon, 2 May 2011 20:10:05 +0200
Subject: Teach run_erl RUN_ERL_DISABLE_FLOWCNTRL for disabling flow control

Flow control can cause unwanted behaviour of the beam process,
if accidentally hit Ctrl-S (instead of Ctrl-D to detach) the
entire beam may be blocked.

Fix this problem by making it possible to turn off flow
control by setting the environment variable RUN_ERL_DISABLE_FLOWCNTRL.
---
 erts/doc/src/run_erl.xml |  8 ++++++++
 erts/etc/unix/run_erl.c  | 21 +++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/erts/doc/src/run_erl.xml b/erts/doc/src/run_erl.xml
index 7bf7f559c5..da08859c7b 100644
--- a/erts/doc/src/run_erl.xml
+++ b/erts/doc/src/run_erl.xml
@@ -144,6 +144,14 @@
       <item>The size (in bytes) of a log file before switching to a
        new log file. Default is 100000, minimum is 1000 and maximum is
        approximately 2^30.</item>
+      <tag>RUN_ERL_DISABLE_FLOWCNTRL</tag>
+      <item>If defined, disables input and output flow control for the pty opend by run_erl.
+       Useful if you want to remove any risk of accidentally blocking the flow control
+       by hit Ctrl-S (instead of Ctrl-D to detach).
+       Which may result in blocking of the entire beam process
+       and in the case of running heart as supervisor
+       even the heart process will be blocked when writing log message to terminal.
+       Leaving the heart process unable to do its work.</item>
     </taglist>
   </section>
 
diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c
index e97cc14fab..8db8e09bee 100644
--- a/erts/etc/unix/run_erl.c
+++ b/erts/etc/unix/run_erl.c
@@ -991,9 +991,7 @@ static int open_pty_master(char **ptyslave)
 static int open_pty_slave(char *name)
 {
   int sfd;
-#ifdef DEBUG
   struct termios tty_rmode;
-#endif
 
   if ((sfd = open(name, O_RDWR, 0)) < 0) {
     return -1;
@@ -1019,6 +1017,25 @@ static int open_pty_slave(char *name)
   }
 #endif
 
+  if (getenv("RUN_ERL_DISABLE_FLOWCNTRL")) {
+    if (tcgetattr(sfd, &tty_rmode) < 0) {
+      fprintf(stderr, "Cannot get terminal's current mode\n");
+      exit(-1);
+    }
+
+    tty_rmode.c_iflag &= ~IXOFF;
+    if (tcsetattr(sfd, TCSANOW, &tty_rmode) < 0) {
+      fprintf(stderr, "Cannot disable terminal's flow control on input\n");
+      exit(-1);
+    }
+
+    tty_rmode.c_iflag &= ~IXON;
+    if (tcsetattr(sfd, TCSANOW, &tty_rmode) < 0) {
+      fprintf(stderr, "Cannot disable terminal's flow control on output\n");
+      exit(-1);
+    }
+  }
+
 #ifdef DEBUG
   if (tcgetattr(sfd, &tty_rmode) < 0) {
     fprintf(stderr, "Cannot get terminals current mode\n");
-- 
cgit v1.2.3