mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-13 03:32:24 +00:00
{edit,fault}.c: improve SIGWINCH and SIGINT handling
The fault.c and edit.c changes in this commit were inspired by changes in the 93v- beta but take a slightly different approach: mainly, the code to update $COLUMNS and $LINES is put in its own function instead of duplicated in sh_chktrap() and ed_setup(). src/cmd/ksh93/sh/fault.c: - Move code to update $COLUMNS and $LINES to a new sh_update_columns_lines() function so it can be reused. - Fix compile error on systems without SIGWINCH. src/cmd/ksh93/edit/edit.c: - ed_setup(): Call sh_update_columns_lines() instead of issuing SIGWINCH to self. - Change two sh_fault(SIGINT) calls to issuing the signal to the current process using kill(2). sh_fault() is now never called directly (as in the 93v- beta). src/cmd/ksh93/sh/main.c: sh_main(): - On non-interactive, call sh_update_columns_lines() and set the signal handler for SIGWINCH to sh_fault(), causing $COLUMNS and $LINES to be kept up to date when the terminal window is resized (this is handled elsewhere for interactive shells). This change makes ksh act like mksh, bash and zsh. (Previously, ksh required setting a dummy SIGWINCH trap to get auto-updated $COLUMNS and $LINES in scripts, as this set the SIGWINCH signal handler to sh_fault(). This persisted even after unsetting the trap again, so that was inconsistent behaviour.) src/cmd/ksh93/include/shell.h: - Don't define sh.winch on systems without SIGWINCH. src/cmd/ksh93/sh.1: - Update and tweak the COLUMNS and LINES variable documentation. - Move them up to the section of variables that are set by the shell (which AT&T should have done before).
This commit is contained in:
parent
416a412d71
commit
372d704bfb
8 changed files with 70 additions and 42 deletions
6
NEWS
6
NEWS
|
@ -3,6 +3,12 @@ For full details, see the git log at: https://github.com/ksh93/ksh/tree/1.0
|
|||
|
||||
Any uppercase BUG_* names are modernish shell bug IDs.
|
||||
|
||||
2022-07-01:
|
||||
|
||||
- In scripts, $COLUMNS and $LINES are now kept up to date in scripts at
|
||||
initialization and when the window size changes (previously, this
|
||||
required setting a dummy trap for the SIGWINCH signal in the script).
|
||||
|
||||
2022-06-28:
|
||||
|
||||
- Fixed a bug that caused the <#((num)) or >#((num)) arithmetic seek
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/***********************************************************************
|
||||
* *
|
||||
* This software is part of the ast package *
|
||||
* Copyright (c) 1982-2012 AT&T Intellectual Property *
|
||||
* Copyright (c) 1982-2014 AT&T Intellectual Property *
|
||||
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
|
||||
* and is licensed under the *
|
||||
* Eclipse Public License, Version 1.0 *
|
||||
|
@ -591,16 +591,8 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
|
|||
#else
|
||||
ep->e_multiline = sh_isoption(SH_MULTILINE) && sh_isoption(SH_VI);
|
||||
#endif
|
||||
sh_update_columns_lines();
|
||||
#ifdef SIGWINCH
|
||||
if(!(sh.sigflag[SIGWINCH]&SH_SIGFAULT))
|
||||
{
|
||||
signal(SIGWINCH,sh_fault);
|
||||
sh.sigflag[SIGWINCH] |= SH_SIGFAULT;
|
||||
}
|
||||
pp = sh.st.trapcom[SIGWINCH];
|
||||
sh.st.trapcom[SIGWINCH] = 0;
|
||||
sh_fault(SIGWINCH);
|
||||
sh.st.trapcom[SIGWINCH] = pp;
|
||||
sh.winch = 0;
|
||||
#endif
|
||||
#if SHOPT_EDPREDICT
|
||||
|
@ -888,6 +880,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
|
|||
{
|
||||
if(sh.trapnote&(SH_SIGSET|SH_SIGTRAP))
|
||||
goto done;
|
||||
#ifdef SIGWINCH
|
||||
#if SHOPT_ESH || SHOPT_VSH
|
||||
#if SHOPT_ESH && SHOPT_VSH
|
||||
if(sh.winch && sh_isstate(SH_INTERACTIVE) && (sh_isoption(SH_VI) || sh_isoption(SH_EMACS) || sh_isoption(SH_GMACS)))
|
||||
|
@ -941,6 +934,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
|
|||
}
|
||||
#endif /* SHOPT_ESH || SHOPT_VSH */
|
||||
sh.winch = 0;
|
||||
#endif /* SIGWINCH */
|
||||
/* an interrupt that should be ignored */
|
||||
errno = 0;
|
||||
if(!waitevent || (rv=(*waitevent)(fd,-1L,0))>=0)
|
||||
|
@ -1016,7 +1010,7 @@ static int putstack(Edit_t *ep,char string[], register int nbyte, int type)
|
|||
{
|
||||
/*** user break key ***/
|
||||
ep->e_lookahead = 0;
|
||||
sh_fault(SIGINT);
|
||||
kill(sh.current_pid,SIGINT);
|
||||
siglongjmp(ep->e_env, UINTR);
|
||||
}
|
||||
# endif /* CBREAK */
|
||||
|
@ -1072,7 +1066,7 @@ static int putstack(Edit_t *ep,char string[], register int nbyte, int type)
|
|||
{
|
||||
/*** user break key ***/
|
||||
ep->e_lookahead = 0;
|
||||
sh_fault(SIGINT);
|
||||
kill(sh.current_pid,SIGINT);
|
||||
siglongjmp(ep->e_env, UINTR);
|
||||
}
|
||||
# endif /* CBREAK */
|
||||
|
|
|
@ -117,6 +117,7 @@ struct checkpt
|
|||
|
||||
extern noreturn void sh_done(int);
|
||||
extern void sh_fault(int);
|
||||
extern void sh_update_columns_lines(void);
|
||||
extern void sh_sigclear(int);
|
||||
extern void sh_sigdone(void);
|
||||
extern void sh_siginit(void);
|
||||
|
|
|
@ -313,7 +313,9 @@ struct Shell_s
|
|||
char funload;
|
||||
char used_pos; /* used positional parameter */
|
||||
char universe;
|
||||
#ifdef SIGWINCH
|
||||
char winch;
|
||||
#endif
|
||||
short arithrecursion; /* current arithmetic recursion level */
|
||||
char indebug; /* set when in debug trap */
|
||||
unsigned char ignsig; /* ignored signal in subshell */
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */
|
||||
#define SH_RELEASE_SVER "1.0.0-beta.2" /* semantic version number: https://semver.org */
|
||||
#define SH_RELEASE_DATE "2022-06-28" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_DATE "2022-07-01" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_CPYR "(c) 2020-2022 Contributors to ksh " SH_RELEASE_FORK
|
||||
|
||||
/* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */
|
||||
|
|
|
@ -1804,6 +1804,17 @@ is restored when the function returns.
|
|||
Set to a value that identifies the version of this shell.
|
||||
.TP
|
||||
.B
|
||||
.SM COLUMNS
|
||||
Width of the terminal window in character positions.
|
||||
Updated automatically at initialization and on receiving a
|
||||
.B SIGWINCH
|
||||
signal.
|
||||
The shell uses the value to define the width of the edit window
|
||||
for the shell edit modes and for printing
|
||||
.B select
|
||||
lists.
|
||||
.TP
|
||||
.B
|
||||
.SM KSH_VERSION
|
||||
A name reference to
|
||||
.BR .sh.version .
|
||||
|
@ -1814,6 +1825,19 @@ The current line number within the script or
|
|||
function being executed.
|
||||
.TP
|
||||
.B
|
||||
.SM LINES
|
||||
Height of the terminal window in lines.
|
||||
Updated automatically at initialization and on receiving a
|
||||
.B SIGWINCH
|
||||
signal.
|
||||
The shell uses the value to determine the column length for printing
|
||||
.B select
|
||||
lists: they are printed vertically until about two thirds of
|
||||
.B
|
||||
.SM LINES
|
||||
lines are filled.
|
||||
.TP
|
||||
.B
|
||||
.SM OLDPWD
|
||||
The previous working directory set by the
|
||||
.B cd
|
||||
|
@ -1891,14 +1915,6 @@ The search path for the
|
|||
command.
|
||||
.TP
|
||||
.B
|
||||
.SM COLUMNS
|
||||
If this variable is set,
|
||||
the value is used to define the width of the edit window
|
||||
for the shell edit modes and for printing
|
||||
.B select
|
||||
lists.
|
||||
.TP
|
||||
.B
|
||||
.SM EDITOR
|
||||
If the
|
||||
.B
|
||||
|
@ -2117,17 +2133,6 @@ This variable determines the locale category for the
|
|||
decimal point character.
|
||||
.TP
|
||||
.B
|
||||
.SM LINES
|
||||
If this variable is set,
|
||||
the value is used to determine the column length for printing
|
||||
.B select
|
||||
lists.
|
||||
Select lists will print vertically until about two-thirds of
|
||||
.B
|
||||
.SM LINES
|
||||
lines are filled.
|
||||
.TP
|
||||
.B
|
||||
.SM MAIL
|
||||
If this variable is set to the name of a mail file
|
||||
.I and\^
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/***********************************************************************
|
||||
* *
|
||||
* This software is part of the ast package *
|
||||
* Copyright (c) 1982-2012 AT&T Intellectual Property *
|
||||
* Copyright (c) 1982-2014 AT&T Intellectual Property *
|
||||
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
|
||||
* and is licensed under the *
|
||||
* Eclipse Public License, Version 1.0 *
|
||||
|
@ -75,14 +75,8 @@ void sh_fault(register int sig)
|
|||
#ifdef SIGWINCH
|
||||
if(sig==SIGWINCH)
|
||||
{
|
||||
int rows=0, cols=0;
|
||||
int32_t v;
|
||||
astwinsize(2,&rows,&cols);
|
||||
if(v = cols)
|
||||
nv_putval(COLUMNS, (char*)&v, NV_INT32|NV_RDONLY);
|
||||
if(v = rows)
|
||||
nv_putval(LINES, (char*)&v, NV_INT32|NV_RDONLY);
|
||||
sh.winch++;
|
||||
sh_update_columns_lines();
|
||||
sh.winch = 1;
|
||||
}
|
||||
#endif /* SIGWINCH */
|
||||
trap = sh.st.trapcom[sig];
|
||||
|
@ -102,7 +96,11 @@ void sh_fault(register int sig)
|
|||
}
|
||||
goto done;
|
||||
}
|
||||
if(sh.subshell && trap && sig!=SIGINT && sig!=SIGQUIT && sig!=SIGWINCH && sig!=SIGCONT)
|
||||
if(sh.subshell && trap && sig!=SIGINT && sig!=SIGQUIT
|
||||
#ifdef SIGWINCH
|
||||
&& sig!=SIGWINCH
|
||||
#endif
|
||||
&& sig!=SIGCONT)
|
||||
{
|
||||
sh.exitval = SH_EXITSIG|sig;
|
||||
sh_subfork();
|
||||
|
@ -228,6 +226,20 @@ done:
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* update $COLUMNS and $LINES
|
||||
*/
|
||||
void sh_update_columns_lines(void)
|
||||
{
|
||||
int rows=0, cols=0;
|
||||
int32_t v;
|
||||
astwinsize(2,&rows,&cols);
|
||||
if(v = cols)
|
||||
nv_putval(COLUMNS, (char*)&v, NV_INT32|NV_RDONLY);
|
||||
if(v = rows)
|
||||
nv_putval(LINES, (char*)&v, NV_INT32|NV_RDONLY);
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize signal handling
|
||||
*/
|
||||
|
|
|
@ -353,6 +353,14 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
sh_onoption(SH_EMACS);
|
||||
#endif /* SHOPT_ESH */
|
||||
}
|
||||
#ifdef SIGWINCH
|
||||
else
|
||||
{
|
||||
/* keep $COLUMNS and $LINES up to date even for scripts that don't trap SIGWINCH */
|
||||
sh_update_columns_lines();
|
||||
signal(SIGWINCH,sh_fault);
|
||||
}
|
||||
#endif
|
||||
/* (Re)set PS4 and IFS, but don't export these now even if allexport is on. */
|
||||
i = (sh_isoption(SH_ALLEXPORT) != 0);
|
||||
sh_offoption(SH_ALLEXPORT);
|
||||
|
|
Loading…
Reference in a new issue