mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
Merge branch '117_sigwinch'
* 117_sigwinch: Ticket #117: refactoring of SIGWINCH hangling.
This commit is contained in:
commit
af65483e97
@ -104,8 +104,7 @@ mc_global_t mc_global = {
|
||||
.disable_colors = FALSE,
|
||||
.ugly_line_drawing = FALSE,
|
||||
.old_mouse = FALSE,
|
||||
.alternate_plus_minus = FALSE,
|
||||
.winch_flag = 0
|
||||
.alternate_plus_minus = FALSE
|
||||
},
|
||||
|
||||
.vfs =
|
||||
|
@ -275,9 +275,6 @@ typedef struct
|
||||
/* If true, use + and \ keys normally and select/unselect do if M-+ / M-\.
|
||||
and M-- and keypad + / - */
|
||||
gboolean alternate_plus_minus;
|
||||
|
||||
/* Set if the window has changed it's size */
|
||||
SIG_ATOMIC_VOLATILE_T winch_flag;
|
||||
} tty;
|
||||
|
||||
struct
|
||||
|
@ -16,7 +16,8 @@ TTY_SRC = \
|
||||
color.c color.h \
|
||||
key.c key.h keyxdef.c \
|
||||
mouse.c mouse.h \
|
||||
tty.c tty.h tty-internal.h \
|
||||
tty-internal.c tty-internal.h \
|
||||
tty.c tty.h \
|
||||
win.c win.h
|
||||
|
||||
if HAVE_TEXTMODE_X11_SUPPORT
|
||||
|
@ -2028,7 +2028,7 @@ tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block)
|
||||
}
|
||||
}
|
||||
|
||||
if (!block || mc_global.tty.winch_flag != 0)
|
||||
if (!block || tty_got_winch ())
|
||||
{
|
||||
time_addr = &time_out;
|
||||
time_out.tv_sec = 0;
|
||||
@ -2048,7 +2048,7 @@ tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block)
|
||||
{
|
||||
if (redo_event)
|
||||
return EV_MOUSE;
|
||||
if (!block || mc_global.tty.winch_flag != 0)
|
||||
if (!block || tty_got_winch ())
|
||||
return EV_NONE;
|
||||
vfs_timeout_handler ();
|
||||
}
|
||||
|
104
lib/tty/tty-internal.c
Normal file
104
lib/tty/tty-internal.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
Internal stuff of the terminal controlling library.
|
||||
|
||||
Copyright (C) 2019
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
Andrew Borodin <aborodin@vmail.ru>, 2019.
|
||||
|
||||
This file is part of the Midnight Commander.
|
||||
|
||||
The Midnight Commander is free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
The Midnight Commander is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Source: internal stuff of the terminal controlling library.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
|
||||
#include "tty-internal.h"
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/* pipe to handle SIGWINCH */
|
||||
int sigwinch_pipe[2];
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
tty_create_winch_pipe (void)
|
||||
{
|
||||
int fd_flags;
|
||||
|
||||
if (pipe (sigwinch_pipe) == -1)
|
||||
{
|
||||
perror (_("Cannot create pipe for SIGWINCH"));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* If we read from an empty pipe, then read(2) will block until data is available.
|
||||
* If we write to a full pipe, then write(2) blocks until sufficient data has been read
|
||||
* from the pipe to allow the write to complete..
|
||||
* Therefore, use nonblocking I/O.
|
||||
*/
|
||||
|
||||
fd_flags = fcntl (sigwinch_pipe[0], F_GETFL, NULL);
|
||||
if (fd_flags != -1)
|
||||
{
|
||||
fd_flags |= O_NONBLOCK | O_CLOEXEC;
|
||||
fd_flags = fcntl (sigwinch_pipe[0], F_SETFL, fd_flags);
|
||||
}
|
||||
if (fd_flags == -1)
|
||||
{
|
||||
perror (_("Cannot configure write end of SIGWINCH pipe"));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fd_flags = fcntl (sigwinch_pipe[1], F_GETFL, NULL);
|
||||
if (fd_flags != -1)
|
||||
{
|
||||
fd_flags |= O_NONBLOCK | O_CLOEXEC;
|
||||
fd_flags = fcntl (sigwinch_pipe[1], F_SETFL, fd_flags);
|
||||
}
|
||||
if (fd_flags == -1)
|
||||
{
|
||||
perror (_("Cannot configure read end of SIGWINCH pipe"));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
@ -30,11 +30,17 @@ extern gboolean mouse_enabled;
|
||||
extern char *smcup;
|
||||
extern char *rmcup;
|
||||
|
||||
/* pipe to handle SIGWINCH */
|
||||
extern int sigwinch_pipe[2];
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
void tty_create_winch_pipe (void);
|
||||
|
||||
char *mc_tty_normalize_from_utf8 (const char *);
|
||||
void tty_init_xterm_support (gboolean is_xterm);
|
||||
int tty_lowlevel_getch (void);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
#endif /* MC_TTY_INTERNAL_H */
|
||||
|
@ -102,6 +102,8 @@ tty_setup_sigwinch (void (*handler) (int))
|
||||
#endif /* SA_RESTART */
|
||||
sigaction (SIGWINCH, &act, &oact);
|
||||
#endif /* SIGWINCH */
|
||||
|
||||
tty_create_winch_pipe ();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -109,9 +111,12 @@ tty_setup_sigwinch (void (*handler) (int))
|
||||
static void
|
||||
sigwinch_handler (int dummy)
|
||||
{
|
||||
ssize_t n = 0;
|
||||
|
||||
(void) dummy;
|
||||
|
||||
mc_global.tty.winch_flag = 1;
|
||||
n = write (sigwinch_pipe[1], "", 1);
|
||||
(void) n;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -139,6 +139,7 @@ static void
|
||||
tty_setup_sigwinch (void (*handler) (int))
|
||||
{
|
||||
(void) SLsignal (SIGWINCH, handler);
|
||||
tty_create_winch_pipe ();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -146,9 +147,13 @@ tty_setup_sigwinch (void (*handler) (int))
|
||||
static void
|
||||
sigwinch_handler (int dummy)
|
||||
{
|
||||
ssize_t n = 0;
|
||||
|
||||
(void) dummy;
|
||||
|
||||
mc_global.tty.winch_flag = 1;
|
||||
n = write (sigwinch_pipe[1], "", 1);
|
||||
(void) n;
|
||||
|
||||
(void) SLsignal (SIGWINCH, sigwinch_handler);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@ -164,6 +165,29 @@ tty_got_interrupt (void)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
gboolean
|
||||
tty_got_winch (void)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
ssize_t n;
|
||||
|
||||
/* merge all SIGWINCH events raised to this moment */
|
||||
do
|
||||
{
|
||||
char x[16];
|
||||
|
||||
/* read multiple events at a time */
|
||||
n = read (sigwinch_pipe[0], &x, sizeof (x));
|
||||
if (n > 0)
|
||||
ret = TRUE;
|
||||
}
|
||||
while (n > 0 || (n == -1 && errno == EINTR));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
tty_print_one_hline (gboolean single)
|
||||
{
|
||||
|
@ -80,6 +80,8 @@ extern void tty_enable_interrupt_key (void);
|
||||
extern void tty_disable_interrupt_key (void);
|
||||
extern gboolean tty_got_interrupt (void);
|
||||
|
||||
extern gboolean tty_got_winch (void);
|
||||
|
||||
extern void tty_reset_prog_mode (void);
|
||||
extern void tty_reset_shell_mode (void);
|
||||
|
||||
|
@ -338,7 +338,8 @@ mc_refresh (void)
|
||||
if (mc_global.we_are_background)
|
||||
return;
|
||||
#endif /* ENABLE_BACKGROUND */
|
||||
if (mc_global.tty.winch_flag == 0)
|
||||
|
||||
if (!tty_got_winch ())
|
||||
tty_refresh ();
|
||||
else
|
||||
{
|
||||
@ -355,8 +356,6 @@ dialog_change_screen_size (void)
|
||||
{
|
||||
GList *d;
|
||||
|
||||
mc_global.tty.winch_flag = 0;
|
||||
|
||||
tty_change_screen_size ();
|
||||
|
||||
#ifdef HAVE_SLANG
|
||||
|
@ -519,7 +519,7 @@ frontend_dlg_run (WDialog * h)
|
||||
{
|
||||
int d_key;
|
||||
|
||||
if (mc_global.tty.winch_flag != 0)
|
||||
if (tty_got_winch ())
|
||||
dialog_change_screen_size ();
|
||||
|
||||
if (is_idle ())
|
||||
|
@ -531,8 +531,7 @@ toggle_panels (void)
|
||||
* 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 = 0;
|
||||
was_sigwinch = tty_got_winch ();
|
||||
|
||||
#ifdef ENABLE_SUBSHELL
|
||||
if (mc_global.tty.use_subshell)
|
||||
@ -555,7 +554,7 @@ toggle_panels (void)
|
||||
update_xterm_title_path ();
|
||||
}
|
||||
|
||||
if (was_sigwinch != 0 || mc_global.tty.winch_flag != 0)
|
||||
if (was_sigwinch != 0 || tty_got_winch ())
|
||||
dialog_change_screen_size ();
|
||||
else
|
||||
repaint_screen ();
|
||||
|
@ -207,7 +207,7 @@ write_all (int fd, const void *buf, size_t count)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
if (mc_global.tty.winch_flag != 0)
|
||||
if (tty_got_winch ())
|
||||
tty_change_screen_size ();
|
||||
|
||||
continue;
|
||||
@ -545,7 +545,7 @@ feed_subshell (int how, gboolean fail_on_error)
|
||||
/* Despite using SA_RESTART, we still have to check for this */
|
||||
if (errno == EINTR)
|
||||
{
|
||||
if (mc_global.tty.winch_flag != 0)
|
||||
if (tty_got_winch ())
|
||||
tty_change_screen_size ();
|
||||
|
||||
continue; /* try all over again */
|
||||
@ -1211,7 +1211,7 @@ read_subshell_prompt (void)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
if (mc_global.tty.winch_flag != 0)
|
||||
if (tty_got_winch ())
|
||||
tty_change_screen_size ();
|
||||
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user