1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 03:32:24 +00:00

Fix truncating of files with <>;file combined with <#pattern

The issue with truncating files was caused by out-of-sync streams.
Details and discussion: https://github.com/att/ast/issues/61

src/cmd/ksh93/sh/io.c: sh_iorestore():
- To be safe, sync all streams before restoring file descriptors.

src/cmd/ksh93/tests/io.sh:
- Add two regression tests for truncating files with this
  combination of redirections.
- The second test, which invokes a -c script, is disabled for now
  as this triggers another corner case bug involving the SH_NOFORK
  optimisaton for -c scripts. That fix is for another commit.

(cherry picked from commit 18fb64840365c2ff4608188e5487bd79d08f67d1)
This commit is contained in:
Martijn Dekker 2020-05-20 23:42:00 +02:00
parent a638e724d0
commit e999f6b169
4 changed files with 32 additions and 1 deletions

6
NEWS
View file

@ -4,6 +4,12 @@ For full details, see the git log at:
Any uppercase BUG_* names are modernish shell bug IDs.
2020-05-21:
- Fix truncating of files with the combined redirections '<>;file' and
'<#pattern'. The bug was caused by out-of-sync streams.
Details and discussion: https://github.com/att/ast/issues/61
2020-05-20:
- Fix BUG_ISSETLOOP. Expansions like ${var+set} remained static when used

View file

@ -17,4 +17,4 @@
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#define SH_RELEASE "93u+m 2020-05-20"
#define SH_RELEASE "93u+m 2020-05-21"

View file

@ -1749,6 +1749,11 @@ void sh_iorestore(Shell_t *shp, int last, int jmpval)
register int origfd, savefd, fd;
int flag = (last&IOSUBSHELL);
last &= ~IOSUBSHELL;
/*
* There was an issue with truncating files (see 'ftruncate' below) that was caused by
* out-of-sync streams. So, to be safe, sync all streams before restoring file descriptors.
*/
sfsync(NULL);
for (fd = shp->topfd - 1; fd >= last; fd--)
{
if(!flag && filemap[fd].subshell)

View file

@ -502,4 +502,24 @@ done {n}< /dev/null
n=$( exec {n}< /dev/null; print -r -- $n)
[[ -r /dev/fd/$n ]] && err_exit "file descriptor n=$n left open after subshell"
# ======
# Truncating a file using <> and >#num
# https://github.com/att/ast/issues/61
for ((i=1; i<=10; i++)) do print "$i"; done | tee "$tmp/nums2" > "$tmp/nums1"
expect=$'1\n2\n3\n4'
(1<>;"$tmp/nums1" >#5)
actual=$(cat "$tmp/nums1")
[[ "$actual" = "$expect" ]] || err_exit "Failed to truncate file in subshell \
(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
: <<\INACTIVE # TODO: the >#5 is optimised away by a '-c' optimisation corner case bug
"$SHELL" -c '1<>;"$1/nums2" >#5' x "$tmp"
actual=$(cat "$tmp/nums2")
[[ "$actual" = "$expect" ]] || err_exit "Failed to truncate file in -c script \
(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
INACTIVE
# ======
exit $((Errors<125?Errors:125))