Skip to content

Commit

Permalink
pty: Fix signal handling (re: 1ca9286)
Browse files Browse the repository at this point in the history
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: #61
  • Loading branch information
McDutchie committed Jan 24, 2021
1 parent 70368c5 commit 5a2e7da
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 43 deletions.
116 changes: 80 additions & 36 deletions src/cmd/builtin/pty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
8 changes: 1 addition & 7 deletions src/cmd/ksh93/tests/pty.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -480,7 +475,6 @@ r Stopped
w fg
u yes-yes
!
end_disabled

# err_exit #
# Test file name completion in vi mode
Expand Down

0 comments on commit 5a2e7da

Please sign in to comment.