mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix bug on closed stdout; improve BUG_PUTIOERR fix (re: 93e15a30
)
Stéphane Chazelas reported: > As noted in this austin-group-l discussion[*] (relevant to this > issue): > > $ ksh93u+m -c 'pwd; echo "$?" >&2; echo test; echo "$?" >&2' >&- > 0 > 1 > /home/chazelas > > when stdout is closed, pwd does claim it succeeds (by returning a > 0 exit status), while echo doesn't (not really relevant to the > problem here, only to show it doesn't affect all builtins), and > the output that pwd failed to write earlier ends up being written > on stderr here instead of stdout upon exit (presumably) because > of that >&2 redirection. > > strace shows ksh93 attempting write(1, "/home/chazelas\n", 15) 6 > times (1, the last one, successful). > > It gets even weirder when redirecting to a file: > > $ ksh93u+m -c 'pwd; echo "$?" >&2; echo test; echo "$?" > file' >&- > 0 > $ cat file > 1 > 1 > ome/chazelas In my testing, the problem does not occur when closing stdout at the start of the -c script itself (using redirect >&- or exec >&-); it only occurs if stdout was closed before initialising the shell. That made me suspect that the problem had to do with an inconsistent file descriptor state in the shell. ksh uses internal sh_open() and sh_close() functions, among others, to maintain that state. src/cmd/ksh93/sh/main.c: sh_main(): - If the shell is initialised with stdin, stdout or stderr closed, then make the shell's file descriptor state tables reflect that fact by calling sh_close() for the closed file descriptors. This commit also improves the BUG_PUTIOERR fix from93e15a30
. Error checking after sfsync() is not sufficient. For instance, on FreeBSD, the following did not produce a non-zero exit status: ksh -c 'echo hi' >/dev/full even though this did: ksh -c 'echo hi >/dev/full' Reliable error checking requires not only checking the result of every SFIO command that writes output, but also synching the buffer at the end of the operation and checking the result of that. src/cmd/ksh93/bltins/print.c: - Make exitval variable global to allow functions called by b_print() to set a nonzero exit status. - Check the result of all SFIO output commands that write output. - b_print(): Always sfsync() at the end, except if the s (history) flag was given. This allows getting rid of the sfsync() call that required the workaround introduced in846ad932
. [*] https://www.mail-archive.com/austin-group-l@opengroup.org/msg08056.html Resolves: https://github.com/ksh93/ksh/issues/314
This commit is contained in:
parent
a3abad203a
commit
09a8a279f2
5 changed files with 56 additions and 20 deletions
|
@ -344,6 +344,10 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
sh_accbegin(error_info.id);
|
||||
#endif /* SHOPT_ACCT */
|
||||
}
|
||||
/* If the shell is init'ed with std{in,out,err} closed, make the shell's FD state reflect that. */
|
||||
for(i=0; i<=2; i++)
|
||||
if(fcntl(i,F_GETFD,NiL)==-1 && errno==EBADF) /* closed at OS level? */
|
||||
sh_close(i); /* update shell FD state */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue