* script input redirection / eof handling @ 2013-10-31 14:21 Phillip Susi 2013-12-02 12:36 ` Karel Zak 0 siblings, 1 reply; 9+ messages in thread From: Phillip Susi @ 2013-10-31 14:21 UTC (permalink / raw) To: util-linux -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I came across an old bug filed in debian about script being redirected from a file misbehaving. It seems that when the master ( input ) process hits eof, it exits immediately, orphaning the child ( output ) and user processes. I believe the correct thing to do is signal the eof to the user process and wait for the children to exit, but I'm not sure how to make a pty signal eof. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.17 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJScmdWAAoJEJrBOlT6nu75JIQH/1Eqt6gsG+vKGc8xpybIE6F7 UGgo8sLyn++PE3U6MZQcsWj2nHZ6p76uHOp4Kn1sk8xrb2zetueQTF1idtgJO7nS PKhwbfInD3ocSuEQB1HygMmKTKuXT9qYCBj18AT9ZQp7eQ5ocz+nvNnGHQuR4KPR /CsI0D0/BnTO32ayh6qgE1HtxD0sUY4K1Qw3MyyChINwFAU9q8p3Y9Lz5RqQTTZk 2j3kc6jDdNaGy1b6w1exhEMrhs7zC1LRvz5GhqM+ODVAN/YiMh4eKYH9a4OrYXru l8Df0gDWNRrQhqrJxvOMKph/DZO1sZEZP3ZG/kOXak/cpbHVy0MkGepP0qId91g= =ZaJO -----END PGP SIGNATURE----- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: script input redirection / eof handling 2013-10-31 14:21 script input redirection / eof handling Phillip Susi @ 2013-12-02 12:36 ` Karel Zak 2013-12-02 12:54 ` Karel Zak 0 siblings, 1 reply; 9+ messages in thread From: Karel Zak @ 2013-12-02 12:36 UTC (permalink / raw) To: Phillip Susi; +Cc: util-linux On Thu, Oct 31, 2013 at 10:21:10AM -0400, Phillip Susi wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > I came across an old bug filed in debian about script being redirected > from a file misbehaving. Do you mean something like: echo "ps uf" | script .. if yes, then it's pretty unexpected usage. The code expects that stdin is terminal. (For example it copy the current terminal attributes the new pseudo-terminal.) Unfortunately it does not check tcgetatt() return code so the problem is not visible. I'll fix it. > It seems that when the master ( input ) > process hits eof, it exits immediately, orphaning the child ( output ) > and user processes. Yep, I think it would be enough to add kill(0, SIGTERM); before done() in doinput() to avoid orphans. Karel -- Karel Zak <kzak@redhat.com> http://karelzak.blogspot.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: script input redirection / eof handling 2013-12-02 12:36 ` Karel Zak @ 2013-12-02 12:54 ` Karel Zak 2013-12-02 14:45 ` Phillip Susi 0 siblings, 1 reply; 9+ messages in thread From: Karel Zak @ 2013-12-02 12:54 UTC (permalink / raw) To: Phillip Susi; +Cc: util-linux On Mon, Dec 02, 2013 at 01:36:59PM +0100, Karel Zak wrote: > On Thu, Oct 31, 2013 at 10:21:10AM -0400, Phillip Susi wrote: > > -----BEGIN PGP SIGNED MESSAGE----- > > Hash: SHA1 > > > > I came across an old bug filed in debian about script being redirected > > from a file misbehaving. > > Do you mean something like: > > echo "ps uf" | script > > .. if yes, then it's pretty unexpected usage. The code expects that > stdin is terminal. (For example it copy the current terminal > attributes the new pseudo-terminal.) > > Unfortunately it does not check tcgetatt() return code so the problem > is not visible. I'll fix it. Note, that if you want to support this scenario (stdin is not a terminal) then send a patch ;-) I guess you have to initialize the terminal (see inlude/ttyutils.h, reset_virtual_console()) and use this dummy struct termios instead of the current 'tt'. > Yep, I think it would be enough to add > > kill(0, SIGTERM); > > before done() in doinput() to avoid orphans. This is probably not the best solution (because shell will print "Terminated" etc.), but it's definitely better than orphans. Karel -- Karel Zak <kzak@redhat.com> http://karelzak.blogspot.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: script input redirection / eof handling 2013-12-02 12:54 ` Karel Zak @ 2013-12-02 14:45 ` Phillip Susi 2013-12-02 17:02 ` Karel Zak 0 siblings, 1 reply; 9+ messages in thread From: Phillip Susi @ 2013-12-02 14:45 UTC (permalink / raw) To: Karel Zak; +Cc: util-linux -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 12/2/2013 7:54 AM, Karel Zak wrote: > Note, that if you want to support this scenario (stdin is not a > terminal) then send a patch ;-) It seems to work fine up until it hits eof, which can also happen on a tty and you'll get the same bad behavior, so I think refusing to run on a non tty isn't a proper fix. >> Yep, I think it would be enough to add >> >> kill(0, SIGTERM); >> >> before done() in doinput() to avoid orphans. You don't want to just make sure the children die, you want to make sure that the child sees the eof and capture any final output it may have. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.17 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJSnJz9AAoJEI5FoCIzSKrw6j0IAKZvkym0kJQfWghombuTnV1z 5FCcWPz3Jyo9V96X+fnD3cXpkkPjIM5ZUIBaRJubUYX65AKebXaXw+FkE9YyXsIR Jeegewp5IlSlF3zbZzCSUchI/gK0KCHv1yKe21xD20iGAy9MGApXBJszsOaREbU2 nG9mFYwviFDQnURBfwHxvS7Bf4S+6i1wgKeS58EqSeXpMpMDCimTw1/mv8MLnGdS 0nzCrPZvgRZcc2avYPSWYs8ZLtFgu5rDuJ7J9TfEuiEzGWCqlPXQYF1a6nHvpT0W KSdu+1bzsasdrEXFF6Iai2NvFndg9JXqiLCGfKdELbJayYPjwltOtl41PfalG/w= =2lT4 -----END PGP SIGNATURE----- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: script input redirection / eof handling 2013-12-02 14:45 ` Phillip Susi @ 2013-12-02 17:02 ` Karel Zak 2013-12-02 18:06 ` Phillip Susi 0 siblings, 1 reply; 9+ messages in thread From: Karel Zak @ 2013-12-02 17:02 UTC (permalink / raw) To: Phillip Susi; +Cc: util-linux On Mon, Dec 02, 2013 at 09:45:19AM -0500, Phillip Susi wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On 12/2/2013 7:54 AM, Karel Zak wrote: > > Note, that if you want to support this scenario (stdin is not a > > terminal) then send a patch ;-) > > It seems to work fine up until it hits eof, which can also happen on a well, it's nasty that the code ignores return codes and it call's tty ioctls/functions for non-tty file descriptors. > tty and you'll get the same bad behavior, so I think refusing to run > on a non tty isn't a proper fix. > > >> Yep, I think it would be enough to add > >> > >> kill(0, SIGTERM); > >> > >> before done() in doinput() to avoid orphans. > > You don't want to just make sure the children die, you want to make > sure that the child sees the eof and capture any final output it may have. never ending orphans suck... The possible solution (hack) to emulate end-of-file is by write "exit\n" to the master tty. For example patch below works for me (it also make it more robust for non-ttys). Karel diff --git a/term-utils/script.c b/term-utils/script.c index c18274c..8437ec8 100644 --- a/term-utils/script.c +++ b/term-utils/script.c @@ -107,6 +107,7 @@ int fflg = 0; int qflg = 0; int tflg = 0; int forceflg = 0; +int isterm; int die; int resized; @@ -230,9 +231,6 @@ main(int argc, char **argv) { die_if_link(fname); } - if (!isatty(STDIN_FILENO)) - errx(EXIT_FAILURE, _("The stdin is not a terminal.")); - if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { warn(_("cannot open %s"), fname); fail(); @@ -314,11 +312,21 @@ doinput(void) { else if (cc < 0 && errno == EINTR && resized) { /* transmit window change information to the child */ - ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&win); - ioctl(slave, TIOCSWINSZ, (char *)&win); + if (isterm) { + ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&win); + ioctl(slave, TIOCSWINSZ, (char *)&win); + } resized = 0; - } - else + } else if (cc == 0 && errno == 0) { + /* end-of-file, probably "foo | script" */ + strcpy(ibuf, "exit\n"); + if (write(master, ibuf, 5) < 0) { + warn (_("write failed")); + fail(); + } + pause(); /* wait for SIGCHLD */ + break; + } else break; } @@ -473,6 +481,9 @@ void fixtty(void) { struct termios rtt; + if (!isterm) + return; + rtt = tt; cfmakeraw(&rtt); rtt.c_lflag &= ~ECHO; @@ -503,7 +514,8 @@ done(void) { master = -1; } else { - tcsetattr(STDIN_FILENO, TCSADRAIN, &tt); + if (isterm) + tcsetattr(STDIN_FILENO, TCSADRAIN, &tt); if (!qflg) printf(_("Script done, file is %s\n"), fname); #ifdef HAVE_LIBUTEMPTER @@ -524,9 +536,19 @@ done(void) { void getmaster(void) { #if defined(HAVE_LIBUTIL) && defined(HAVE_PTY_H) - tcgetattr(STDIN_FILENO, &tt); - ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&win); - if (openpty(&master, &slave, NULL, &tt, &win) < 0) { + int rc; + + isterm = isatty(STDIN_FILENO); + + if (isterm) { + if (tcgetattr(STDIN_FILENO, &tt) != 0) + err(EXIT_FAILURE, _("failed to get terminal attributes")); + ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) &win); + rc = openpty(&master, &slave, NULL, &tt, &win); + } else + rc = openpty(&master, &slave, NULL, NULL, NULL); + + if (rc < 0) { warn(_("openpty failed")); fail(); } @@ -534,6 +556,8 @@ getmaster(void) { char *pty, *bank, *cp; struct stat stb; + isterm = isatty(STDIN_FILENO); + pty = &line[strlen("/dev/ptyp")]; for (bank = "pqrs"; *bank; bank++) { line[strlen("/dev/pty")] = *bank; @@ -552,9 +576,11 @@ getmaster(void) { ok = access(line, R_OK|W_OK) == 0; *tp = 'p'; if (ok) { - tcgetattr(STDIN_FILENO, &tt); - ioctl(STDIN_FILENO, TIOCGWINSZ, - (char *)&win); + if (isterm) { + tcgetattr(STDIN_FILENO, &tt); + ioctl(STDIN_FILENO, TIOCGWINSZ, + (char *)&win); + } return; } close(master); @@ -577,8 +603,10 @@ getslave(void) { warn(_("cannot open %s"), line); fail(); } - tcsetattr(slave, TCSANOW, &tt); - ioctl(slave, TIOCSWINSZ, (char *)&win); + if (isterm) { + tcsetattr(slave, TCSANOW, &tt); + ioctl(slave, TIOCSWINSZ, (char *)&win); + } #endif setsid(); ioctl(slave, TIOCSCTTY, 0); ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: script input redirection / eof handling 2013-12-02 17:02 ` Karel Zak @ 2013-12-02 18:06 ` Phillip Susi 2013-12-02 22:36 ` Karel Zak 2013-12-02 23:25 ` Karel Zak 0 siblings, 2 replies; 9+ messages in thread From: Phillip Susi @ 2013-12-02 18:06 UTC (permalink / raw) To: Karel Zak; +Cc: util-linux -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 12/2/2013 12:02 PM, Karel Zak wrote: > never ending orphans suck... Yes, but the idea is not to orphan them in the first place and wait for them to terminate instead. > The possible solution (hack) to emulate end-of-file is by write > "exit\n" to the master tty. For example patch below works for me > (it also make it more robust for non-ttys). That only works if the program on the other end knows what "exit" means, which is basically only true if it's a shell. Surely there must be a proper way to signal EOF over a pty? Can you use shutdown() on a pty? -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.17 (MingW32) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBAgAGBQJSnMwNAAoJEI5FoCIzSKrwwvYH+wRd0hXZwZKhElWgpLIjWNOO 82ulPzt1Cld085qllaG8VvO0CSN3JERHD5Eo8iB+YIuI32lNO2dGuGw0MwYJ72cn whUEqT7BNcnDCDqhPba/ZYcGJ8mCp+3+58BDth8NPu+nma7d6V0n4sAbqO+w6uCS VZOO9qo2cKYGqs7E2YYWLHBadMGkyLjpDd9j7ZsLxEe6ezb1vFLxSmJQ3CiNLz+i q2okm0GUipkhMAMCC8zuV1GnUf5sJuSx6QiSkIE5Mok9d8HqOtXTt8F7URAa+YVC tBtM7dMIfXEQCJil16hTn+KdgiAtNE4BaGkyevW2kohwmKQgKU51/CHlofWGK1s= =6Ihg -----END PGP SIGNATURE----- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: script input redirection / eof handling 2013-12-02 18:06 ` Phillip Susi @ 2013-12-02 22:36 ` Karel Zak 2013-12-02 23:25 ` Karel Zak 1 sibling, 0 replies; 9+ messages in thread From: Karel Zak @ 2013-12-02 22:36 UTC (permalink / raw) To: Phillip Susi; +Cc: util-linux On Mon, Dec 02, 2013 at 01:06:05PM -0500, Phillip Susi wrote: > That only works if the program on the other end knows what "exit" yep, fingers have been faster than brain.. (I forgot we have --command). > means, which is basically only true if it's a shell. Surely there > must be a proper way to signal EOF over a pty? Can you use shutdown() > on a pty? I'm going to play with that tomorrow. Karel -- Karel Zak <kzak@redhat.com> http://karelzak.blogspot.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: script input redirection / eof handling 2013-12-02 18:06 ` Phillip Susi 2013-12-02 22:36 ` Karel Zak @ 2013-12-02 23:25 ` Karel Zak 2013-12-03 12:55 ` Karel Zak 1 sibling, 1 reply; 9+ messages in thread From: Karel Zak @ 2013-12-02 23:25 UTC (permalink / raw) To: Phillip Susi; +Cc: util-linux On Mon, Dec 02, 2013 at 01:06:05PM -0500, Phillip Susi wrote: > That only works if the program on the other end knows what "exit" > means, which is basically only true if it's a shell. Surely there > must be a proper way to signal EOF over a pty? Can you use shutdown() > on a pty? Oh, now it reminds me... in include/ttyutils.h we have macros to generate tty control chars, for example ^C char eof = DEF_EOF; if (write(master, &eof, 1) < 0) { warn (_("write failed")); fail(); } pause(); is what we need. Karel -- Karel Zak <kzak@redhat.com> http://karelzak.blogspot.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: script input redirection / eof handling 2013-12-02 23:25 ` Karel Zak @ 2013-12-03 12:55 ` Karel Zak 0 siblings, 0 replies; 9+ messages in thread From: Karel Zak @ 2013-12-03 12:55 UTC (permalink / raw) To: Phillip Susi; +Cc: util-linux On Tue, Dec 03, 2013 at 12:25:13AM +0100, Karel Zak wrote: > On Mon, Dec 02, 2013 at 01:06:05PM -0500, Phillip Susi wrote: > > That only works if the program on the other end knows what "exit" > > means, which is basically only true if it's a shell. Surely there > > must be a proper way to signal EOF over a pty? Can you use shutdown() > > on a pty? > > Oh, now it reminds me... in include/ttyutils.h we have macros to > generate tty control chars, for example ^C > > char eof = DEF_EOF; > > if (write(master, &eof, 1) < 0) { > warn (_("write failed")); > fail(); > } > pause(); > > is what we need. It was more tricky than I have originally expected, but it seems it works. (It seems that it is not enough to send EOF, you have to be sure that someone already listens on slave side.) Karel -- Karel Zak <kzak@redhat.com> http://karelzak.blogspot.com ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-12-03 12:55 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-10-31 14:21 script input redirection / eof handling Phillip Susi 2013-12-02 12:36 ` Karel Zak 2013-12-02 12:54 ` Karel Zak 2013-12-02 14:45 ` Phillip Susi 2013-12-02 17:02 ` Karel Zak 2013-12-02 18:06 ` Phillip Susi 2013-12-02 22:36 ` Karel Zak 2013-12-02 23:25 ` Karel Zak 2013-12-03 12:55 ` Karel Zak
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox