mirror of
https://git.savannah.gnu.org/git/make.git
synced 2025-01-27 01:27:58 +00:00
[SV 57022] Avoid posix_spawn which fails asynchronously
Avoid using posix_spawn implementations that fail asynchronously when the spawned program can't be invoked: this means instead of getting an error such as "No such file or directory" we get just "Exit 127". Original implementation of the configure.ac macro provided by Martin Dorey <martin.dorey@hds.com> Original implementation of the regression tests provided by Dmitry Goncharov <dgoncharov@users.sf.net> * configure.ac: Test whether posix_spawn fails asynchronously. In a cross-compilation environment, assume that it does not. If we detect that it does, fall back to fork/exec. * tests/scripts/features/exec: Add regression tests for different shebang invocation methods.
This commit is contained in:
parent
564fb212a7
commit
e64674b718
2 changed files with 85 additions and 1 deletions
23
configure.ac
23
configure.ac
|
@ -371,7 +371,28 @@ AC_ARG_ENABLE([posix-spawn],
|
|||
AS_CASE([/$ac_cv_header_spawn/$ac_cv_func_posix_spawn/],
|
||||
[*/no/*], [make_cv_posix_spawn=no])
|
||||
|
||||
AS_CASE([/$make_cv_posix_spawn/$user_posix_spawn/],
|
||||
AS_IF([test "$make_cv_posix_spawn" = yes],
|
||||
AC_CACHE_CHECK([for posix_spawn that fails synchronously],
|
||||
[make_cv_synchronous_posix_spawn],
|
||||
[make_cv_synchronous_posix_spawn=no
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <spawn.h>
|
||||
#include <string.h>
|
||||
|
||||
extern char **environ;
|
||||
|
||||
int main() {
|
||||
char* path = strdup("./non-existent");
|
||||
char *argv[[2]];
|
||||
argv[[0]] = path;
|
||||
argv[[1]] = 0;
|
||||
return posix_spawn(0, path, 0, 0, argv, environ);
|
||||
}]])],
|
||||
[make_cv_synchronous_posix_spawn=no],
|
||||
[make_cv_synchronous_posix_spawn=yes],
|
||||
[make_cv_synchronous_posix_spawn="no (cross-compiling)"])]))
|
||||
|
||||
AS_CASE([/$user_posix_spawn/$make_cv_posix_spawn/$make_cv_synchronous_posix_spawn/],
|
||||
[*/no/*], [make_cv_posix_spawn=no],
|
||||
[AC_DEFINE(USE_POSIX_SPAWN, 1, [Define to 1 to use posix_spawn().])
|
||||
])
|
||||
|
|
63
tests/scripts/features/exec
Normal file
63
tests/scripts/features/exec
Normal file
|
@ -0,0 +1,63 @@
|
|||
# -*-perl-*-
|
||||
|
||||
use warnings;
|
||||
|
||||
my $description = "Test that make can execute binaries as well as scripts with"
|
||||
." various shabangs and without a shebang";
|
||||
my $details = "The various shells that this test uses are the default "
|
||||
."/bin/sh, $origENV{SHELL} and the perl interpreter that is "
|
||||
." executing this test program. The shells are used for the value"
|
||||
." of SHELL inside the test makefile and also as a shebang in the"
|
||||
." executed script. There is also a test which executes a script"
|
||||
." that has no shebang.";
|
||||
|
||||
# Only bother with this on UNIX systems
|
||||
$port_type eq 'UNIX' or return -1;
|
||||
|
||||
my $usersh = $origENV{SHELL};
|
||||
my $answer = 'hello, world';
|
||||
|
||||
my @shebangs = ('', '#!/bin/sh', "#!$usersh", "#!$perl_name");
|
||||
my @shells = ('', 'SHELL=/bin/sh', "SHELL=$usersh");
|
||||
|
||||
# tests [0-11]
|
||||
# Have a makefile with various SHELL= exec a shell program with varios
|
||||
# shebangs or without a shebang at all.
|
||||
my $stem = './exec.cmd';
|
||||
my $k = 0;
|
||||
for my $shebang (@shebangs) {
|
||||
for my $shell (@shells) {
|
||||
my $cmd = $k ? "$stem.$k" : $stem;
|
||||
++$k;
|
||||
unlink $cmd;
|
||||
open(CMD,"> $cmd");
|
||||
print CMD "$shebang\n";
|
||||
print CMD "printf \"$answer\\n\";\n";
|
||||
close(CMD);
|
||||
chmod 0700, $cmd;
|
||||
|
||||
run_make_test(q!
|
||||
all:; @$(CMD)
|
||||
!, "$shell CMD=$cmd", "$answer\n");
|
||||
|
||||
rmfiles($cmd);
|
||||
}
|
||||
}
|
||||
|
||||
# tests [12-14]
|
||||
# Exec a binary from a makefile that has SHELL=.
|
||||
for my $shell (@shells) {
|
||||
run_make_test(q!
|
||||
all:; @#PERL# -e 'printf "$(ANSWER)\n"';
|
||||
!, "$shell ANSWER='$answer'", "$answer\n");
|
||||
}
|
||||
|
||||
# test 15
|
||||
# Use perl as a shell.
|
||||
run_make_test(q!
|
||||
SHELL = #PERL#
|
||||
.SHELLFLAGS = -e
|
||||
all:; @printf "$(ANSWER)\n";
|
||||
!, "ANSWER='$answer'", "$answer\n");
|
||||
|
||||
1;
|
Loading…
Reference in a new issue