Skip to content

Commit

Permalink
Replace safe FD fix with Solaris/ksh2020 version (re: 045fe6a)
Browse files Browse the repository at this point in the history
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:
att#198
att#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.
  • Loading branch information
McDutchie committed Jan 8, 2021
1 parent 17ebfbf commit ab98ec6
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
20 changes: 13 additions & 7 deletions src/cmd/ksh93/sh/io.c
Expand Up @@ -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)
Expand Down
26 changes: 26 additions & 0 deletions src/cmd/ksh93/tests/subshell.sh
Expand Up @@ -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

Expand Down

0 comments on commit ab98ec6

Please sign in to comment.