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

Replace safe FD fix with Solaris/ksh2020 version (re: 045fe6a1)

This pulls a new version of sh_iosafefd() from:
https://github.com/oracle/solaris-userland/blob/master/components/ksh93/patches/285-30771135.patch

It was written by Kurtis Rader for ksh2020:
https://github.com/att/ast/issues/198
https://github.com/att/ast/pull/199
It is presumably better than the Red Hat version and also comes
with more regression test cases (although it still doesn't fix
modernish BUG_CSUBSTDO, which remains in the TODO file).

This commit does not go along with other peripheral changes from
that patch, i.e. a different name and location of this function.

src/cmd/ksh93/sh/io.c:
- Replace sh_iosafefd() as above.

src/cmd/ksh93/tests/subshell.sh:
- Add and tweak tests from the patch.
This commit is contained in:
Martijn Dekker 2021-01-08 16:35:26 +00:00
parent 17ebfbf6a3
commit ab98ec65e4
2 changed files with 39 additions and 7 deletions

View file

@ -436,22 +436,28 @@ int sh_iovalidfd(Shell_t *shp, int fd)
return(1);
}
int sh_iosafefd(Shell_t* shp, int sfd)
/*
* Return the lowest numbered fd that is equal to or greater than
* the requested 'min_fd' and which is not currently in use.
*/
int sh_iosafefd(Shell_t* shp, int min_fd)
{
register int fd;
while(1)
{
for(fd=0; fd < shp->topfd; fd++)
if(fcntl(min_fd, F_GETFD) == -1)
{
if (filemap[fd].save_fd==sfd || filemap[fd].orig_fd==sfd || (fcntl(sfd, F_GETFD) != -1 || errno != EBADF))
for(fd = 0; fd < shp->topfd; fd++)
{
sfd++;
continue;
if (filemap[fd].save_fd == min_fd || filemap[fd].orig_fd == min_fd)
break;
}
if(fd == shp->topfd)
break;
}
break;
min_fd++;
}
return(sfd);
return(min_fd);
}
int sh_inuse(Shell_t *shp, int fd)

View file

@ -854,6 +854,32 @@ actual=${ get_value; }
actual=`get_value`
[[ $actual == "$expect" ]] || err_exit "\`Comsub\` failed to return output (expected '$expect', got '$actual')"
# more tests from https://github.com/oracle/solaris-userland/blob/master/components/ksh93/patches/285-30771135.patch
tmpfile=$tmp/1116072.dummy
touch "$tmpfile"
exp='return value'
function get_value
{
case=$1
(( case >= 1 )) && exec 3< $tmpfile
(( case >= 2 )) && exec 4< $tmpfile
(( case >= 3 )) && exec 6< $tmpfile
# To trigger the bug we have to spawn an external command.
$(whence -p true)
(( case >= 1 )) && exec 3<&-
(( case >= 2 )) && exec 4<&-
(( case >= 3 )) && exec 6<&-
print "$exp"
}
got=$(get_value 0)
[[ $got == "$exp" ]] || err_exit "failed to capture subshell output when closing fd: case 0"
got=$(get_value 1)
[[ $got == "$exp" ]] || err_exit "failed to capture subshell output when closing fd: case 1"
got=$(get_value 2)
[[ $got == "$exp" ]] || err_exit "failed to capture subshell output when closing fd: case 2"
got=$(get_value 3)
[[ $got == "$exp" ]] || err_exit "failed to capture subshell output when closing fd: case 3"
# ======
# https://bugzilla.redhat.com/1117404