mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +00:00
pty: Fix signal handling (re: 1ca9286a
)
This applies the OpenSUSE changes to pty.c from: https://build.opensuse.org/package/view_file/shells/ksh/ksh93-builtin.dif src/cmd/builtin/pty.c: - Add a patch from OpenSUSE with a fix for signal handling. src/cmd/ksh93/tests/pty.sh: - Re-enable the process group exercise test. Resolves: https://github.com/ksh93/ksh/issues/61
This commit is contained in:
parent
70368c57d6
commit
5a2e7dae67
2 changed files with 81 additions and 43 deletions
|
@ -215,28 +215,65 @@ mkpty(int* master, int* slave)
|
|||
#endif
|
||||
#if !_lib_openpty
|
||||
char* sname;
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
sigset_t blckttou, oldset;
|
||||
(void)sigemptyset(&blckttou);
|
||||
(void)sigaddset(&blckttou, SIGTTOU);
|
||||
sigprocmask(SIG_BLOCK, &blckttou, &oldset);
|
||||
#endif
|
||||
/*
|
||||
* some systems hang hard during the handshake
|
||||
* if you know why then please let us know
|
||||
*/
|
||||
|
||||
alarm(4);
|
||||
if (tcgetattr(STDERR_FILENO, &tty) >= 0)
|
||||
ttyp = &tty;
|
||||
else
|
||||
alarm(6);
|
||||
if (tcgetattr(sffileno(sfstderr), &tty) < 0)
|
||||
{
|
||||
if (errno != ENOTTY)
|
||||
error(-1, "unable to get standard error terminal attributes");
|
||||
cfmakeraw(&tty);
|
||||
ttyp = 0;
|
||||
error(-1, "unable to get standard error terminal attributes");
|
||||
}
|
||||
tty.c_lflag |= ICANON | IEXTEN | ISIG | ECHO|ECHOE|ECHOK|ECHOKE;
|
||||
tty.c_oflag |= (ONLCR | OPOST);
|
||||
tty.c_oflag &= ~(OCRNL | ONLRET);
|
||||
tty.c_iflag |= BRKINT;
|
||||
tty.c_iflag &= ~IGNBRK;
|
||||
tty.c_lflag |= ISIG;
|
||||
tty.c_cc[VTIME] = 0;
|
||||
tty.c_cc[VMIN] = CMIN;
|
||||
#ifdef B115200
|
||||
cfsetispeed(&tty, B115200);
|
||||
cfsetospeed(&tty, B115200);
|
||||
#elif defined(B57600)
|
||||
cfsetispeed(&tty, B57600);
|
||||
cfsetospeed(&tty, B57600);
|
||||
#elif defined(B38400)
|
||||
cfsetispeed(&tty, B38400);
|
||||
cfsetospeed(&tty, B38400);
|
||||
#endif
|
||||
ttyp = &tty;
|
||||
#ifdef TIOCGWINSZ
|
||||
if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) >= 0)
|
||||
winp = &win;
|
||||
else
|
||||
if (ioctl(sffileno(sfstderr), TIOCGWINSZ, &win) < 0)
|
||||
{
|
||||
if (errno != ENOTTY)
|
||||
error(-1, "unable to get standard error window size");
|
||||
win.ws_row = 0;
|
||||
win.ws_col = 0;
|
||||
winp = 0;
|
||||
error(-1, "unable to get standard error window size");
|
||||
}
|
||||
if (win.ws_row < 24)
|
||||
win.ws_row = 24;
|
||||
if (win.ws_col < 80)
|
||||
win.ws_col = 80;
|
||||
winp = &win;
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
# if !_lib_openpty
|
||||
# undef _lib_openpty
|
||||
# define _lib_openpty 1
|
||||
# endif
|
||||
#endif
|
||||
#if _lib_openpty
|
||||
if (openpty(master, slave, NULL, ttyp, winp) < 0)
|
||||
|
@ -278,6 +315,9 @@ mkpty(int* master, int* slave)
|
|||
fcntl(*master, F_SETFD, FD_CLOEXEC);
|
||||
#if !O_cloexec
|
||||
fcntl(*slave, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||
#endif
|
||||
alarm(0);
|
||||
return 0;
|
||||
|
@ -317,9 +357,13 @@ process(Sfio_t* mp, Sfio_t* lp, int delay, int timeout)
|
|||
char* s;
|
||||
Sfio_t* ip;
|
||||
Sfio_t* sps[2];
|
||||
struct stat dst;
|
||||
struct stat fst;
|
||||
|
||||
ip = sfstdin;
|
||||
for (;;)
|
||||
if (!fstat(sffileno(ip), &dst) && !stat("/dev/null", &fst) && dst.st_dev == fst.st_dev && dst.st_ino == fst.st_ino)
|
||||
ip = 0;
|
||||
do
|
||||
{
|
||||
i = 0;
|
||||
t = timeout;
|
||||
|
@ -336,39 +380,39 @@ process(Sfio_t* mp, Sfio_t* lp, int delay, int timeout)
|
|||
{
|
||||
if (n < 0)
|
||||
error(ERROR_SYSTEM|2, "poll failed");
|
||||
if (t < 0)
|
||||
break;
|
||||
break;
|
||||
}
|
||||
else
|
||||
for (i = 0; i < n; i++)
|
||||
for (i = t = 0; i < n; i++)
|
||||
{
|
||||
if (!(sfvalue(sps[i]) & SF_READ))
|
||||
/*skip*/;
|
||||
else if (sps[i] == mp)
|
||||
{
|
||||
if (!(sfvalue(sps[i]) & SF_READ))
|
||||
/*skip*/;
|
||||
else if (sps[i] == mp)
|
||||
t++;
|
||||
if (!(s = (char*)sfreserve(mp, SF_UNBOUND, -1)))
|
||||
{
|
||||
if (!(s = (char*)sfreserve(mp, SF_UNBOUND, -1)))
|
||||
{
|
||||
sfclose(mp);
|
||||
mp = 0;
|
||||
}
|
||||
else if ((r = sfvalue(mp)) > 0 && (sfwrite(sfstdout, s, r) != r || sfsync(sfstdout)))
|
||||
{
|
||||
error(ERROR_SYSTEM|2, "output write failed");
|
||||
goto done;
|
||||
}
|
||||
sfclose(mp);
|
||||
mp = 0;
|
||||
}
|
||||
else
|
||||
else if ((r = sfvalue(mp)) > 0 && (sfwrite(sfstdout, s, r) != r || sfsync(sfstdout)))
|
||||
{
|
||||
if (!(s = sfgetr(ip, '\n', 1)))
|
||||
ip = 0;
|
||||
else if (sfputr(mp, s, '\r') < 0 || sfsync(mp))
|
||||
{
|
||||
error(ERROR_SYSTEM|2, "write failed");
|
||||
goto done;
|
||||
}
|
||||
error(ERROR_SYSTEM|2, "output write failed");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t++;
|
||||
if (!(s = sfgetr(ip, '\n', 1)))
|
||||
ip = 0;
|
||||
else if (sfputr(mp, s, '\r') < 0 || sfsync(mp))
|
||||
{
|
||||
error(ERROR_SYSTEM|2, "write failed");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (t);
|
||||
done:
|
||||
if (mp)
|
||||
sfclose(mp);
|
||||
|
|
|
@ -463,12 +463,7 @@ r echo repeat-3
|
|||
!
|
||||
fi
|
||||
|
||||
# Following test is disabled because a bug in pty causes it to fail on too
|
||||
# many operating systems. Apparently pty doesn't handle SIGTSTP correctly:
|
||||
# https://github.com/att/ast/issues/375
|
||||
# TODO: fix pty and re-enable this test.
|
||||
: <<\end_disabled
|
||||
# err_(don't count me)_exit #
|
||||
# err_exit #
|
||||
whence -q less &&
|
||||
TERM=vt100 tst $LINENO <<"!"
|
||||
L process/terminal group exercise
|
||||
|
@ -480,7 +475,6 @@ r Stopped
|
|||
w fg
|
||||
u yes-yes
|
||||
!
|
||||
end_disabled
|
||||
|
||||
# err_exit #
|
||||
# Test file name completion in vi mode
|
||||
|
|
Loading…
Reference in a new issue