[erlang-patches] Patrick Mahoney's SIGWINCH patch

Matthew Dempsky <>
Fri Apr 18 05:48:36 CEST 2008


This patch was not included in R12B-2 either, and I've still received
no feedback from the developers regarding this patch.  Are there any
concerns barring its consideration?

Upon further review, I did notice that cols_needs_update was not
properly marked as volatile in the original diff, so I've changed
corrected that and included the updated diff below.

I'd really like to see this included upstream. :-)


On Thu, Feb 7, 2008 at 12:00 AM, Matthew Dempsky <> wrote:
> I noticed that Patrick Mahoney's SIGWINCH patch[1] was not included in
>  R12B-1.  Is it possible for it to be included in R12B-2?  Are there
>  any issues that need to be resolved for it to be acceptable for
>  inclusion?
>
>  [1] http://www.erlang.org/pipermail/erlang-patches/2007-December/000205.html


--- erts/emulator/drivers/unix/ttsl_drv.c.orig	2007-12-18
04:57:58.000000000 -0700
+++ erts/emulator/drivers/unix/ttsl_drv.c	2007-12-31 12:13:30.000000000 -0700
@@ -58,6 +58,7 @@
 static char *capbuf;
 static char *up, *down, *left, *right;
 static int cols, xn;
+static volatile int cols_needs_update = FALSE;

 /* The various opcodes. */
 #define OP_PUTC 0
@@ -114,6 +115,7 @@
 static int move_right(int);
 static int move_up(int);
 static int move_down(int);
+static void update_cols(void);

 /* Terminal setting functions. */
 static int tty_init(int,int,int,int);
@@ -122,6 +124,7 @@
 static int ttysl_control(ErlDrvData, unsigned int, char *, int, char **, int);
 static RETSIGTYPE suspend(int);
 static RETSIGTYPE cont(int);
+static RETSIGTYPE winch(int);

 /* Define the driver table entry. */
 struct erl_drv_entry ttsl_driver_entry = {
@@ -200,6 +203,7 @@

     setlocale(LC_CTYPE, "");	/* Set international environment */
     sys_sigset(SIGCONT, cont);
+    sys_sigset(SIGWINCH, winch);

     driver_select(port, (ErlDrvEvent)(Uint)ttysl_fd, DO_READ, 1);
     ttysl_port = port;
@@ -262,6 +266,7 @@
 	  close(ttysl_fd);
 	driver_select(ttysl_port, (ErlDrvEvent)(Uint)ttysl_fd, DO_READ, 0);
 	sys_sigset(SIGCONT, SIG_DFL);
+	sys_sigset(SIGWINCH, SIG_DFL);
     }
     ttysl_port = (ErlDrvPort)-1;
     ttysl_fd = -1;
@@ -432,6 +437,8 @@
     int i, l, r;
     byte *c;

+    update_cols();
+
     /* Step forward or backwards over n logical characters. */
     c = step_over_chars(n);

@@ -553,6 +560,8 @@
  */
 static int write_buf(byte *s, int n)
 {
+    update_cols();
+
     while (n > 0) {
 	if (isprint(*s)) {
 	    outc(*s);
@@ -598,6 +607,8 @@
 {
     int dc, dl;

+    update_cols();
+
     dc = COL(to) - COL(from);
     dl = LINE(to) - LINE(from);
     if (dl > 0)
@@ -704,6 +715,27 @@
       tputs(down, 1, outc);
     return TRUE;
 }
+
+/*
+ * Updates cols if terminal has resized (SIGWINCH). Should be called
+ * at the start of any function that uses the COL or LINE macros. If
+ * the terminal is resized after calling this function but before use
+ * of the macros, then we may write to the wrong screen location.
+ *
+ * We cannot call this from the SIGWINCH handler because it uses
+ * ioctl() which is not a safe function as listed in the signal(7)
+ * man page.
+ */
+static void update_cols(void)
+{
+    Uint32 width, height;
+
+    if (cols_needs_update) {
+        cols_needs_update = FALSE;
+        ttysl_get_window_size(&width, &height);
+        cols = width;
+    }
+}
 		

 /*
@@ -830,3 +862,7 @@
     }
 }

+static RETSIGTYPE winch(int sig)
+{
+    cols_needs_update = TRUE;
+}



More information about the erlang-patches mailing list