Messages in this thread Patches in this message | | | Date | Mon, 6 Oct 2008 14:07:08 +0200 | From | Adam Tlałka <> | Subject | [PATCH 0/0] SIGWINCH problem with terminal apps |
| |
Welcome,
I've observed then very often a X11 terminal app is not getting proper window sizes afer terminal resize operation. This could be seen with mc, jed, vim or other curses and not curses aware apps.
I wrote a simple program which just does nothing but uses SIGWINCH handler so I can observe values reported by ioctl(1,TIOCGWINS,&ws) call inside my signal handler. What is interesting that from time to time it obtain unchanged values. It means values which were valid just before terminal resize.
In drivers/char/vt.c and drivers/char/tty_io.c variables vc->vc_tty->winsize and tty->winsize , real_tty->winsize are updated after kill_pgrp(pgrp, SIGWINCH, 1) calls. I am not very familiar with mutex design and how it corresponds to kill_pgrp() kernel function but it seems that locking is not working here as we expect. An app can read tty winsize data through ioctl() call in SIGWINCH handler and obtain uchanged values.
So as a quick solution I made patches which move mentioned updates before kill_pgrp() calls. As I tested modified kernel there is no observed effect now. So I send patchs.
There are some places where kill_pgrp() call is used and some variable is changed after it. It should be considered if this code is always working properly or some race scheduler condition exists.
Signed-off-by: Adam Tla/lka <atlka@pg.gda.pl>
-- Adam Tlałka mailto:atlka@pg.gda.pl ^v^ ^v^ ^v^ System & Network Administration Group - - - ~~~~~~ Computer Center, Gdańsk University of Technology, Poland --- drivers/char/tty_io_orig.c 2008-10-06 11:03:39.000000000 +0200 +++ drivers/char/tty_io.c 2008-10-06 11:20:54.000000000 +0200 @@ -3021,6 +3021,9 @@ static int tiocswinsz(struct tty_struct rpgrp = get_pid(real_tty->pgrp); spin_unlock_irqrestore(&tty->ctrl_lock, flags); + tty->winsize = tmp_ws; + real_tty->winsize = tmp_ws; + if (pgrp) kill_pgrp(pgrp, SIGWINCH, 1); if (rpgrp != pgrp && rpgrp) @@ -3028,9 +3031,6 @@ static int tiocswinsz(struct tty_struct put_pid(pgrp); put_pid(rpgrp); - - tty->winsize = tmp_ws; - real_tty->winsize = tmp_ws; done: mutex_unlock(&tty->termios_mutex); return 0;--- drivers/char/vt_orig.c 2008-10-06 11:01:26.000000000 +0200 +++ drivers/char/vt.c 2008-10-06 11:59:48.000000000 +0200 @@ -921,11 +921,11 @@ int vc_resize(struct vc_data *vc, unsign if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col)) pgrp = get_pid(vc->vc_tty->pgrp); spin_unlock_irq(&vc->vc_tty->ctrl_lock); + *cws = ws; if (pgrp) { kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); put_pid(pgrp); } - *cws = ws; mutex_unlock(&vc->vc_tty->termios_mutex); } | |