[SV 56834] Support local PATH search with posix_spawnp

When using exec we install the child's environment before invoking
execlp(), so commands are found on the child's PATH.  posix_spawnp
searches on the parent's PATH, which we don't want.

Import gnulib's findprog-in module and use it to search the child's
PATH, then use posix_spawn() to run it.

Also, posix_spawn() does not fall back to trying sh on ENOEXEC, as
execlp() does, so implement that as well.

* bootstrap.conf: Add the findprog-in gnulib module
* src/job.c: Include findprog.h if we're using posix_spawn.
(start_job_command): Remove the handling of child->cmd_name,
(child_execute_job): and add it here.  Look up the command to be
run in the child's path and invoke it if found.  If it fails with
ENOEXEC then retry it as an argument to the default shell.
* tests/scripts/misc/general4: Test makefile PATH assignments.
* tests/scripts/features/targetvars: Ditto, for target variables.
This commit is contained in:
Paul Smith
2019-09-06 22:24:46 -04:00
parent ebe1d37104
commit 60905a8afb
4 changed files with 132 additions and 8 deletions

View File

@@ -255,6 +255,32 @@ a: ; @echo $(A)
!,
'', "hello; world\n");
# TEST #21: SV-56834 Ensure setting PATH in a target var works properly
mkdir('sd', 0775);
open(my $fh, '>', 'sd/foobar');
print $fh "exit 0";
close($fh);
chmod 0755, 'sd/foobar';
run_make_test(q!
all: PATH := sd
all: ; foobar
!,
'', "foobar\n");
# Don't use the general PATH if not found on the target path
$extraENV{PATH} = "$ENV{PATH}:sd";
run_make_test(q!
all: PATH := ..
all: ; foobar
!,
'', "foobar\n#MAKE#: foobar: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#;3: all] Error 127", 512);
unlink('sd/foobar');
rmdir ('sd');
# TEST #19: Test define/endef variables as target-specific vars
# run_make_test('

View File

@@ -79,4 +79,45 @@ all: ; \@echo hi
",
'', "hi\n");
# SV-56834 Ensure setting PATH in the makefile works properly
mkdir('sd', 0775);
open(my $fh, '>', 'sd/foobar');
print $fh "exit 0\n";
close($fh);
chmod 0755, 'sd/foobar';
run_make_test(q!
PATH := sd
all: ; foobar
!,
'', "foobar\n");
# Don't use the general PATH if not found on the target path
$extraENV{PATH} = "$ENV{PATH}:sd";
run_make_test(q!
PATH := ..
all: ; foobar
!,
'', "foobar\n#MAKE#: foobar: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#;3: all] Error 127", 512);
unlink('sd/foobar');
rmdir('sd');
# Ensure that local programs are not found if "." is not on the PATH
open(my $fh, '>', 'foobar');
print $fh "exit 0\n";
close($fh);
chmod 0755, 'foobar';
run_make_test(q!
PATH := ..
all: ; foobar
!,
'', "foobar\n#MAKE#: foobar: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#;3: all] Error 127", 512);
unlink('foobar');
1;