1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 19:52:20 +00:00

emacs.c: fix 2 causes of crash

Hopefully this will deal with ksh crashing in macOS Terminal.app
once and for all. Trigger: press Command-F to open the find bar,
then press Esc to close it, then press Esc again. Result: crash
somewhere random in the job control code.

Turns out macOS Terminal.app apparently (and wrongly) sends <Esc>
followed by <Ctrl+L> to the terminal, which ksh takes as a sequence
for clearing the screen. The related crash ultimately traced back
to the code for that in emacs.c. The other crash was in the code
for double-ESC file name completion.

This commit also fixes a non-robust invocation of the 'tput'
command by using the direct path found in $(getconf PATH).

src/cmd/ksh93/features/cmds:
- Remove unused tests for the presence of commands
  (newgrp,test,id,wc,cut,logname,pfexec).
- Replace 'cmd tput' test by 'pth tput' which will find its path
  in $(getconf PATH) and store that path as the macro value.
- Add two tests to determine if 'tput' supports terminfo and/or
  termcap codes. (FreeBSD still requires old termcap codes.)

src/cmd/ksh93/edit/emacs.c: escape():
- Fix a crash in the code for double-ESC completion. Check if the
  cursor is on a non-zero position; this caused a bus error
  (invalid address access) in the subsequent ed_expand call.
- For <Esc><Ctrl+L> (clear screen), fix the strange crash in macOS
  Terminal by not using sh_trap() to invoke "tput clear", which
  causes ksh itself to invoke that command. ksh apparently doesn't
  cope with doing this while SIGWINCH (window size change signal)
  is sent by Terminal. The fix is to just use the C standard
  system(3) function to invoke tput. This invokes tput via /bin/sh,
  but what the hey. (Note that ksh also ran any function or alias
  called 'tput' instead of the real command, and that is now also
  fixed.)
- Use the new _pth_tput test result to invoke tput with the
  hardcoded default system path, increasing robustness.

src/cmd/ksh93/edit/edit.c: ed_setup():
- Use the new _pth_tput test result to invoke tput with the
  hardcoded default system path, increasing robustness.
- When getting the escape code for "cursor up", use the new
  _tput_terminfo and _tput_termcap test results to determine which
  kind of command code to send. This fixes it on FreeBSD.
This commit is contained in:
Martijn Dekker 2021-02-03 17:09:08 +00:00
parent f5eaf217ed
commit 7ff6b73bdb
3 changed files with 43 additions and 7 deletions

View file

@ -765,13 +765,17 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
ep->e_eol = reedit;
if(ep->e_multiline)
{
#ifdef _cmd_tput
#if defined(_pth_tput) && (_tput_terminfo || _tput_termcap)
char *term;
if(!ep->e_term)
ep->e_term = nv_search("TERM",shp->var_tree,0);
if(ep->e_term && (term=nv_getval(ep->e_term)) && strlen(term)<sizeof(ep->e_termname) && strcmp(term,ep->e_termname))
{
sh_trap(".sh.subscript=$(tput cuu1 2>/dev/null)",0);
#if _tput_terminfo
sh_trap(".sh.subscript=$(" _pth_tput " cuu1 2>/dev/null)",0);
#elif _tput_termcap
sh_trap(".sh.subscript=$(" _pth_tput " up 2>/dev/null)",0);
#endif
if(pp=nv_getval(SH_SUBSCRNOD))
strncpy(CURSOR_UP,pp,sizeof(CURSOR_UP)-1);
nv_unset(SH_SUBSCRNOD);

View file

@ -1001,7 +1001,9 @@ static int escape(register Emacs_t* ep,register genchar *out,int count)
case '*': /* filename expansion */
case '=': /* escape = - list all matching file names */
ep->mark = cur;
if(ed_expand(ep->ed,(char*)out,&cur,&eol,i,count) < 0)
if(cur<1)
beep();
else if(ed_expand(ep->ed,(char*)out,&cur,&eol,i,count) < 0)
{
if(ep->ed->e_tabcount==1)
{
@ -1063,10 +1065,9 @@ static int escape(register Emacs_t* ep,register genchar *out,int count)
cur = i;
draw(ep,UPDATE);
return(-1);
#ifdef _cmd_tput
#ifdef _pth_tput
case cntl('L'): /* clear screen */
sh_trap("tput clear", 0);
system(_pth_tput " clear");
draw(ep,REFRESH);
return(-1);
#endif

View file

@ -1,4 +1,35 @@
cmd newgrp,test,id,wc,cut,logname,universe,pfexec,tput
cmd universe
pth ed fail{
echo '#define _pth_ed "ed" /* ed not found on standard PATH */'
}end
pth tput
tput_terminfo note{ does tput support terminfo codes }end run{
case ${_pth_tput-} in
\"/*/tput\")
tput=`echo "${_pth_tput}" | sed 's/^"//; s/"$//'`
if "$tput" sgr0 >/dev/null 2>&1 &&
"$tput" cuu1 >/dev/null 2>&1
then echo '#define _tput_terminfo 1 /* tput supports terminfo codes */'
else echo '#define _tput_terminfo 0 /* tput does not support terminfo codes */'
exit 1
fi ;;
*) exit 1 ;;
esac
}end
tput_termcap note{ does tput support termcap codes }end run{
case ${_pth_tput-} in
\"/*/tput\")
tput=`echo "${_pth_tput}" | sed 's/^"//; s/"$//'`
if "$tput" me >/dev/null 2>&1 &&
"$tput" up >/dev/null 2>&1
then echo '#define _tput_termcap 1 /* tput supports termcap codes */'
else echo '#define _tput_termcap 0 /* tput does not support termcap codes */'
exit 1
fi ;;
*) exit 1 ;;
esac
}end