Erlang/OTP Forums

Author Message

<  Erlang patches mailing list  ~  Patch for erl shell (unix/ttsl_drv.c) SIGWINCH handling (R12

Guest
Posted: Wed Jan 02, 2008 3:15 pm Reply with quote
Guest
Patrick Mahoney writes:
> This is an attempt to fix the problem described by Matthew
> Dempsky:
> http://erlang.org/pipermail/erlang-questions/2007-December/031962.html
>
> The erl shell in Unix does not properly handle terminal
> resize events which can result in a misplaced cursor and
> other confusion.
>
> This patch adds two functions to the file
> erts/emulator/drivers/unix/ttsl_drv.c
>
> winch() is registered as the handler for SIGWINCH which is
> received on terminal resize events. winch() sets a global
> flag "cols_needs_update = TRUE".
>
> update_cols() is run at the start of each function that uses
> the COL() or LINE() macros for calculating cursor positions,
> namely the del_chars(), write_buf(), and move_cursor()
> functions. It checks the "cols_needs_update" flag, and sets
> the "cols" global var to the number returned by
> ttysl_get_widow_size().
>
> If the terminal is resized after update_cols() but before
> use of the COL() macro, then we'll have the same incorrect
> cursor problems during that function.
>
> We don't run ttysl_get_window_size() from the SIGWINCH
> handler because it uses ioctl() which is not listed as a
> "safe" function for use in signal handlers in the signal(7)
> man page.
>
> That said, the solution would be more elegant if we did call
> ttysl_get_window_size() from the signal handler, avoiding
> the polling done by update_cols(). The ncurses source
> includes a simple test/view.c program that does use ioctl()
> in its SIGWINCH handler. It states "This uses functions
> that are 'unsafe', but it seems to work on SunOS and Linux."
> Doing this in erl works for me on Linux, but I have no idea
> on which platforms if may fail.

Calling ioctl() from a signal handler should work on any
proper *NIX, including Linux/Solaris/*BSD/AIX. I would however
worry about doing this in POSIX emulation environments.
I guess cygwin is the prime current example but I think
there also used to be one for VMS (if anyone cares).

But there is another reason for not blindly updating cols
from a signal handler: many procedures reference cols
multiple times, and an asynchronous change to cols would
break things. For example:

> @@ -598,6 +607,8 @@
> {
> int dc, dl;
>
> + update_cols();
> +
> dc = COL(to) - COL(from);
> dl = LINE(to) - LINE(from);
> if (dl > 0)

A change to cols between the assignments to dc and dl
would make them inconsistent, and a change to cols between
COL(to) and COL(from) would make dc bogus.

To poll at the beginning of each cols-sensitive output
procedure is probably the best short-term solution.
Longer-term someone needs to decide what SIGWINCH during
tty output means and how to handle it. Maybe ^L + redraw
is the proper thing to do.
_______________________________________________
erlang-patches mailing list
erlang-patches@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-patches
Post recived from mailinglist

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum