From 794145090deddc3acae2666ffbc57c38cd76a669 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Tue, 30 Oct 2012 14:56:02 +0400 Subject: [PATCH] Fixups of SIGWINCH handling. Signed-off-by: Andrew Borodin --- lib/tty/tty-ncurses.c | 5 +++++ lib/tty/tty-slang.c | 21 +++++++-------------- lib/widget/dialog-switch.c | 10 +++++++--- src/execute.c | 15 ++++++++++++++- src/subshell.c | 26 +++++++++++++++++--------- 5 files changed, 50 insertions(+), 27 deletions(-) diff --git a/lib/tty/tty-ncurses.c b/lib/tty/tty-ncurses.c index 1b88e7ae1..0c3887202 100644 --- a/lib/tty/tty-ncurses.c +++ b/lib/tty/tty-ncurses.c @@ -254,6 +254,11 @@ tty_change_screen_size (void) #endif } #endif /* defined(TIOCGWINSZ) || NCURSES_VERSION_MAJOR >= 4 */ + +#ifdef ENABLE_SUBSHELL + if (mc_global.tty.use_subshell) + tty_resize (mc_global.tty.subshell_pty); +#endif } /* --------------------------------------------------------------------------------------------- */ diff --git a/lib/tty/tty-slang.c b/lib/tty/tty-slang.c index 3554bc507..1fc866400 100644 --- a/lib/tty/tty-slang.c +++ b/lib/tty/tty-slang.c @@ -36,7 +36,6 @@ #include #include /* size_t */ #include -#include #ifdef HAVE_SYS_IOCTL_H #include #endif @@ -131,22 +130,14 @@ static const struct /* *INDENT-ON* */ }; +/* --------------------------------------------------------------------------------------------- */ /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ static void tty_setup_sigwinch (void (*handler) (int)) { -#ifdef SIGWINCH - struct sigaction act, oact; - act.sa_handler = handler; - sigemptyset (&act.sa_mask); - act.sa_flags = 0; -#ifdef SA_RESTART - act.sa_flags |= SA_RESTART; -#endif /* SA_RESTART */ - sigaction (SIGWINCH, &act, &oact); -#endif /* SIGWINCH */ + (void) SLsignal (SIGWINCH, handler); } /* --------------------------------------------------------------------------------------------- */ @@ -157,6 +148,7 @@ sigwinch_handler (int dummy) (void) dummy; mc_global.tty.winch_flag = TRUE; + (void) SLsignal (SIGWINCH, sigwinch_handler); } /* --------------------------------------------------------------------------------------------- */ @@ -382,9 +374,10 @@ tty_change_screen_size (void) SLtt_get_screen_size (); SLsmg_reinit_smg (); - do_enter_ca_mode (); - tty_keypad (TRUE); - tty_nodelay (FALSE); +#ifdef ENABLE_SUBSHELL + if (mc_global.tty.use_subshell) + tty_resize (mc_global.tty.subshell_pty); +#endif } /* --------------------------------------------------------------------------------------------- */ diff --git a/lib/widget/dialog-switch.c b/lib/widget/dialog-switch.c index 3f9a9f07b..945548087 100644 --- a/lib/widget/dialog-switch.c +++ b/lib/widget/dialog-switch.c @@ -35,6 +35,9 @@ #include "lib/global.h" #include "lib/tty/tty.h" /* LINES, COLS */ #include "lib/tty/color.h" /* tty_set_normal_attrs() */ +#ifdef HAVE_SLANG +#include "lib/tty/win.h" /* do_enter_ca_mode() */ +#endif #include "lib/widget.h" #include "lib/event.h" @@ -367,9 +370,10 @@ dialog_change_screen_size (void) tty_change_screen_size (); -#ifdef ENABLE_SUBSHELL - if (mc_global.tty.use_subshell) - tty_resize (mc_global.tty.subshell_pty); +#ifdef HAVE_SLANG + do_enter_ca_mode (); + tty_keypad (TRUE); + tty_nodelay (FALSE); #endif /* Inform all suspending dialogs */ diff --git a/src/execute.c b/src/execute.c index c4f08ff87..e41d76ce6 100644 --- a/src/execute.c +++ b/src/execute.c @@ -319,6 +319,8 @@ toggle_panels (void) vfs_path_t **new_dir_p; #endif /* ENABLE_SUBSHELL */ + gboolean was_sigwinch = FALSE; + channels_down (); disable_mouse (); if (clear_before_exec) @@ -388,6 +390,13 @@ toggle_panels (void) if (mc_global.tty.alternate_plus_minus) application_keypad_mode (); + /* HACK: + * Save sigwinch flag that will be reset in mc_refresh() called via update_panels(). + * There is some problem with screen redraw in ncurses-based mc in this situation. + */ + was_sigwinch = mc_global.tty.winch_flag; + mc_global.tty.winch_flag = FALSE; + #ifdef ENABLE_SUBSHELL if (mc_global.tty.use_subshell) { @@ -408,7 +417,11 @@ toggle_panels (void) update_panels (UP_OPTIMIZE, UP_KEEPSEL); update_xterm_title_path (); } - repaint_screen (); + + if (was_sigwinch || mc_global.tty.winch_flag) + dialog_change_screen_size (); + else + repaint_screen (); } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/subshell.c b/src/subshell.c index 515db44c7..ebab09f91 100644 --- a/src/subshell.c +++ b/src/subshell.c @@ -194,12 +194,13 @@ write_all (int fd, const void *buf, size_t count) { if (errno == EINTR) { + if (mc_global.tty.winch_flag) + tty_change_screen_size (); + continue; } - else - { - return written > 0 ? written : ret; - } + + return written > 0 ? written : ret; } count -= ret; written += ret; @@ -501,10 +502,14 @@ feed_subshell (int how, int fail_on_error) if (select (maxfdp + 1, &read_set, NULL, NULL, wptr) == -1) { - /* Despite using SA_RESTART, we still have to check for this */ if (errno == EINTR) + { + if (mc_global.tty.winch_flag) + tty_change_screen_size (); + continue; /* try all over again */ + } tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); fprintf (stderr, "select (FD_SETSIZE, &read_set...): %s\r\n", unix_error_string (errno)); @@ -1001,12 +1006,15 @@ read_subshell_prompt (void) if (rc == -1) { if (errno == EINTR) - continue; - else { - fprintf (stderr, "select (FD_SETSIZE, &tmp...): %s\r\n", unix_error_string (errno)); - exit (EXIT_FAILURE); + if (mc_global.tty.winch_flag) + tty_change_screen_size (); + + continue; } + + fprintf (stderr, "select (FD_SETSIZE, &tmp...): %s\r\n", unix_error_string (errno)); + exit (EXIT_FAILURE); } bytes = read (mc_global.tty.subshell_pty, pty_buffer, sizeof (pty_buffer)); -- 2.11.4.GIT