Hash :
427249c6
Author :
Date :
2024-10-22T22:08:24
execute, spawn-pipe: Support DLL dependencies of Windows executables. Reported by Michele Locati <michele@locati.it>. * lib/windows-path.h: New file. * lib/windows-path.c: New file. * lib/windows-spawn.h (compose_envblock): Add new_PATH parameter. (spawnpvech): Add dll_dirs parameter. Call extended_PATH. * lib/windows-spawn.c: Include windows-path.h. (compose_envblock): Add new_PATH parameter. * modules/windows-spawn (Description): Now applies to Cygwin as well. (Files): Add lib/windows-path.h, lib/windows-path.c. (configure.ac): Define GL_COND_OBJ_WINDOWS_PATH. (Makefile.am): Conditionally compile windows-path.c. (Include): Add windows-path.h. * lib/spawni.c (__spawni): Update compose_envblock call. * lib/execute.h (execute): Add dll_dirs parameter. * lib/execute.c: Include windows-path.h. (execute): Add dll_dirs parameter. Pass it down to spawnpvech. Call extended_environ. * lib/spawn-pipe.h (create_pipe_out, create_pipe_in, create_pipe_bidi): Add dll_dirs parameter. * lib/spawn-pipe.c: Include windows-path.h. (create_pipe): Add dll_dirs parameter. Pass it down to spawnpvech. Call extended_environ. (create_pipe_bidi, create_pipe_in, create_pipe_out): Add dll_dirs parameter. * lib/javaexec.c (execute_java_class): Update execute invocations. * lib/cygpath.c (execute_and_read_line): Update create_pipe_in invocation. * lib/javaversion.c (execute_and_read_line): Likewise. * lib/csharpcomp.c (compile_csharp_using_mono, compile_csharp_using_dotnet, compile_csharp_using_sscli): Update execute, create_pipe_in invocations. * lib/csharpexec.c (execute_csharp_using_mono, execute_csharp_using_dotnet, execute_csharp_using_sscli): Likewise. * lib/javacomp.c (compile_using_envjavac, compile_using_javac, execute_and_read_line, is_javac_present): Likewise. * lib/pipe-filter-gi.c (pipe_filter_gi_create): Update create_pipe_bidi invocation. * lib/pipe-filter-ii.c (pipe_filter_ii_execute): Likewise. * tests/test-execute-main.c (main): Update execute invocations. * tests/test-execute-script.c (main): Likewise. * tests/test-spawn-pipe-main.c (main): Update create_pipe_bidi invocation. * tests/test-spawn-pipe-script.c (main): Update create_pipe_in invocations. * NEWS: Mention the changes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
/* Test of create_pipe_in/wait_subprocess.
Copyright (C) 2020-2024 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
#include "spawn-pipe.h"
#include "wait-process.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "macros.h"
int
main ()
{
/* Check an invocation of an executable script.
This should only be supported if the script has a '#!' marker; otherwise
it is unsecure: <https://sourceware.org/bugzilla/show_bug.cgi?id=13134>.
POSIX says that the execlp() and execvp() functions support executing
shell scripts
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html>,
but this is considered an antiquated feature. */
int fd[1];
pid_t pid;
{
size_t i;
for (i = 0; i < 2; i++)
{
const char *progname =
(i == 0 ? "executable-script" : "executable-script.sh");
const char *prog_path =
(i == 0 ? SRCDIR "executable-script" : SRCDIR "executable-script.sh");
const char *prog_argv[2] = { prog_path, NULL };
pid = create_pipe_in (progname, prog_argv[0], prog_argv, NULL, NULL,
NULL, false, true, false, fd);
if (pid >= 0)
{
/* Wait for child. */
ASSERT (wait_subprocess (pid, progname, true, true, true, false,
NULL)
== 127);
}
else
{
ASSERT (pid == -1);
ASSERT (errno == ENOEXEC);
}
}
}
#if defined _WIN32 && !defined __CYGWIN__
/* On native Windows, scripts - even with '#!' marker - are not executable.
Only .bat and .cmd files are. */
if (test_exit_status != EXIT_SUCCESS)
return test_exit_status;
fprintf (stderr, "Skipping test: scripts are not executable on this platform.\n");
return 77;
#else
{
const char *progname = "executable-shell-script";
const char *prog_path = SRCDIR "executable-shell-script";
const char *prog_argv[2] = { prog_path, NULL };
pid = create_pipe_in (progname, prog_argv[0], prog_argv, NULL, NULL,
NULL, false, true, false, fd);
ASSERT (pid >= 0);
ASSERT (fd[0] > STDERR_FILENO);
/* Get child's output. */
char buffer[1024];
FILE *fp = fdopen (fd[0], "r");
ASSERT (fp != NULL);
ASSERT (fread (buffer, 1, sizeof (buffer), fp) == 11);
/* Check the result. */
ASSERT (memcmp (buffer, "Halle Potta", 11) == 0);
/* Wait for child. */
ASSERT (wait_subprocess (pid, progname, true, false, true, true, NULL) == 0);
ASSERT (fclose (fp) == 0);
}
return test_exit_status;
#endif
}