1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Fix BUG_PUTIOERR: Check for and report I/O error in output builtins

This allows scripts to check for a nonzero exit status on the
'print', 'printf' and 'echo' builtins and prevent possible infinite
loops if SIGPIPE is ignored.

sfsync() was already returning a negative value on I/O error, so
all we need to do is add a check. The stream buffer will need to be
filled before an I/O error can be detected, but this is the same on
other shells. See manual page: src/lib/libast/man/sfio.3

Ref.: https://github.com/att/ast/issues/1093
      https://github.com/att/ast/pull/1363

src/cmd/ksh93/bltins/print.c: b_print():
- Make sure an error result from sfsync() is reflected in the
  output builtin's exit status (exitval).
- Write an I/O error message (e_io) if the exit status is nonzero.

src/cmd/ksh93/data/msg.c, src/cmd/ksh93/include/io.h:
- Add the e_io[] error message.

src/cmd/ksh93/tests/builtins.sh:
- Add I/O error regression test, checking for the correct error
  message and exit status. All three output builtins use the same
  b_print() function so we only need to test one.

src/cmd/ksh93/tests/basic.sh,
src/cmd/ksh93/tests/coprocess.sh:
- Redirect stderr on a few 'print' commands to /dev/null; these
  now issue an expected I/O error. This does not cause failures.

NEWS, TODO:
- Update.

(cherry picked from commit 9011fa933552e483dab460f7dd1593d64e059d94)
This commit is contained in:
Martijn Dekker 2020-05-16 16:04:35 +02:00
parent 846ad93272
commit 93e15a3035
8 changed files with 45 additions and 13 deletions

View file

@ -336,9 +336,11 @@ skip2:
* https://github.com/att/ast/issues/425
*/
if(!sflag && sffileno(outfile)!=sffileno(sfstderr))
sfsync(outfile);
if (sfsync(outfile) < 0)
exitval = 1;
sfpool(sfstderr,pool,SF_WRITE);
exitval = pdata.err;
if (pdata.err)
exitval = 1;
}
else if(vflag)
{
@ -353,7 +355,10 @@ skip2:
{
/* echo style print */
if(nflag && !argv[0])
sfsync((Sfio_t*)0);
{
if (sfsync((Sfio_t*)0) < 0)
exitval = 1;
}
else if(sh_echolist(shp,outfile,rflag,argv) && !nflag)
sfputc(outfile,'\n');
}
@ -365,8 +370,11 @@ skip2:
else if(n&SF_SHARE)
{
sfset(outfile,SF_SHARE|SF_PUBLIC,1);
sfsync(outfile);
if (sfsync(outfile) < 0)
exitval = 1;
}
if (exitval)
errormsg(SH_DICT, 2, e_io);
return(exitval);
}