Sir, The statements I had made earlier about tcsetattr failures in openpty are all false; since the pty slave is always a tty, ENOTTY failures won't happen. However... I have been experimenting on linux, and while trying to make the openbsd code work there [ since it is shorter ], I discovered that when stdin is not a tty, the openbsd script(1) does not write anything to the typescript or to stdout at all. It ultimately IS due to the openpty call, since stdin not a tty implies that tcgetattr and ioctl+TIOCGWINSZ fail, leading to all zero termios and winsize being applied to the slave by tcsetattr in openpty. Further, when stdin is not a tty, the parent process does not wait on the child pid, which, among other consequences, leads to data being written to stdout in incorrect order. I submitted a patch [ used different email ]. Please review the patch when you have time.
Thank you. Soumendra On 8/10/20, Soumendra Ganguly <[email protected]> wrote: > Yes. You are correct. In the back of my mind, I did want to leave a > small mark [ OCD ]. > > However, I was also trying to justify removing, from my own code, all > isatty instances that are immediately followed by tcgetattr [ again, > OCD ]. The fact that I understood the isatty situation correctly is > valuable enough for me. Thank you for taking the time to verify. > > If it ain't broke, don't fix it I guess? A change to the OpenBSD > script(1) source is not necessary unless some day someone decides to > make fdopenpty in src/lib/libutil/pty.c fail due to TCSAFLUSH and > TIOCSWINSZ failures. > > Also, I kind of did realize why isatty was avoiding ioctl. Thank you > for verifying anyway. I am truly impressed by how precise OpenBSD > codebase is. Who would not want to leave their mark on it? > > Officially "closing" this "issue". > > Soumendra > > Additional note: The replay feature in the other BSDs and util-linux > did have terminal post-processing related bugs in them [ now fixed ]. > > On 8/10/20, Theo de Raadt <[email protected]> wrote: >> Soumendra Ganguly <[email protected]> wrote: >> >>> based on the fact that tty operations should not be performed on stdin >>> if it is not a tty [ maybe it is a regular file ]. This observation >>> was made by [email protected]. I claim that only >>> >>> if (tcgetattr(STDIN_FILENO, &tt) == 0 && >>> ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == 0) >>> istty = 1; >>> >>> would have been sufficient because tcgetattr will fail with errno == >>> ENOTTY if stdin is not a tty. Am I wrong? This claim is true on >>> NetBSD/FreeBSD because their versions of isatty simply make a call to >>> tcgetattr to see it it succeeds. However, the OpenBSD version [ >>> /lib/libc/gen/isatty.c ] calls fcntl with F_ISATTY, which also, like >>> tcgetattr, sets errno to ENOTTY if the fd is not a tty [ sys_fcntl() >>> from /sys/kern/kern_descrip.c ]. >>> >>> Additional note: tcgetattr calls ioctl with TIOCGETA [ >>> /lib/libc/termios/tcgetattr.c and ttioctl() from /sys/kern/tty.c ]. >> >> isatty() using fcntl+F_ISATTY rather than ioctl was to permit >> pledge-heavy programs to eliminate all ioctl use. isatty() was the most >> significant hidden ioctl() system call use in some important programs, >> so I changed introduced F_ISATTY, changed libc isatty(), and then those >> specific programs could be avoid ioctl() usage and become simpler. >> >> But if I undestand correctly this program always does ioctl afterwards, >> and when those ioctl indicate ENOTTY, it does the right thing, so why >> bother calling isatty()? I doubt it can be pledged further, to entirely >> avoid ioctl, without increasing the complexity excessively, so why >> bother adding additional conditions? >> >> I've given up trying to follow all your proposals, because there are so >> many, and they are so mixed up. I have completely lost track of what >> problem you are trying to solve (you may see one real problem, but you >> keep jumping around with small nits which others don't see). I am >> started wondering if you are only doing this to leave your mark. Sorry, >> that's my take on it. I'm done. >> >
