Skip to content

Commit 7e6bbf8

Browse files
committed
Fix another comsub regression (rhbz#1116508) (re: 970069a)
Another Red Hat patch of a patch. With the new comsub mechanism, functions could sometimes return the wrong exit status when invoked from a command substitution. Original patch: https://src.fedoraproject.org/rpms/ksh/blob/642af4d6/f/ksh-20120801-fununset.patch I have determined that the extra setexit() in the Red Hat patch, which copies the current exit status to $?, is not needed, as the code for running functions already sets $? on termination. I've added extra regression tests to prove this. By the way, the setexit() macro is defined like this in defs.h: #define exitset() (sh.savexit=sh.exitval) That's more evidence (see also 3654ee7) that it does not matter whether you address the shell's status struct via a pointer. That macro is used in places that use shp pointers. But, that aside... src/cmd/ksh93/sh/subshell.c: sh_subshell(): - When waiting within a command substitution for a forked process to end, save & restore sh.exitval (the exit status of the command currently being run) so that job_wait() cannot override it. src/cmd/ksh93/tests/functions.sh: - Add tests based in part on the reproducer from rhbz#1116508.
1 parent 95225e1 commit 7e6bbf8

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

‎src/cmd/ksh93/sh/subshell.c‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,9 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
662662
job.bktick_waitall = 0;
663663
if(comsub!=1 && shp->spid)
664664
{
665+
int e = shp->exitval;
665666
job_wait(shp->spid);
667+
shp->exitval = e;
666668
if(shp->pipepid==shp->spid)
667669
shp->spid = 0;
668670
shp->pipepid = 0;

‎src/cmd/ksh93/tests/functions.sh‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,5 +1275,36 @@ $SHELL <<- \EOF
12751275
EOF
12761276
[[ $? == 2 ]] && err_exit 'Over-shifting in a POSIX function does not terminate the script if the function call has a redirection'
12771277
1278+
# ======
1279+
# https://bugzilla.redhat.com/1116508
1280+
expect=$'13/37/1/1'
1281+
actual=$(
1282+
foo() {
1283+
print foo | read
1284+
return 13
1285+
}
1286+
out=$(foo)
1287+
print -n $?/
1288+
foo() {
1289+
print foo | read
1290+
ls /dev/null
1291+
return 37
1292+
}
1293+
out=$(foo)
1294+
print -n $?/
1295+
foo() {
1296+
print foo | ! read
1297+
}
1298+
out=$(foo)
1299+
print -n $?/
1300+
foo() {
1301+
! true
1302+
}
1303+
out=$(foo)
1304+
print -n $?
1305+
)
1306+
[[ $actual == "$expect" ]] || err_exit "wrong exit status from function invoked by command substitution" \
1307+
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
1308+
12781309
# ======
12791310
exit $((Errors<125?Errors:125))

0 commit comments

Comments
 (0)