mirror of
https://https.git.savannah.gnu.org/git/gnulib.git
synced 2026-04-28 06:33:36 +00:00
Done through
sed -e 's/memcmp \([(][^()]*[)]\) == 0/memeq \1/g' \
-e 's/memcmp \([(][^()]*[(][^()]*[)][^()]*[)]\) == 0/memeq \1/g'
* tests/**/*.[hc]: Use memeq instead of memcmp ... == 0.
* modules/*-tests (Dependencies): Add memeq.
155 lines
4.6 KiB
C
155 lines
4.6 KiB
C
/* Test of posix_spawn() function.
|
|
Copyright (C) 2020-2026 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.h>
|
|
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
|
|
#include "macros.h"
|
|
|
|
#define DATA_FILENAME "test-posix_spawn-script.tmp"
|
|
|
|
int
|
|
main ()
|
|
{
|
|
unlink (DATA_FILENAME);
|
|
|
|
/* 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/PR13134>.
|
|
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. */
|
|
pid_t child;
|
|
|
|
posix_spawn_file_actions_t actions;
|
|
ASSERT (posix_spawn_file_actions_init (&actions) == 0);
|
|
ASSERT (posix_spawn_file_actions_addopen (&actions, STDOUT_FILENO,
|
|
DATA_FILENAME,
|
|
O_RDWR | O_CREAT | O_TRUNC, 0600)
|
|
== 0);
|
|
|
|
for (size_t i = 0; i < 2; i++)
|
|
{
|
|
const char *prog_path =
|
|
(i == 0 ? SRCDIR "executable-script" : SRCDIR "executable-script.sh");
|
|
const char *prog_argv[2] = { prog_path, NULL };
|
|
|
|
int err = posix_spawn (&child, prog_path, &actions, NULL,
|
|
(char **) prog_argv, environ);
|
|
if (err != ENOEXEC)
|
|
{
|
|
if (err != 0)
|
|
{
|
|
errno = err;
|
|
perror ("posix_spawn");
|
|
return 1;
|
|
}
|
|
|
|
/* Wait for child. */
|
|
int status = 0;
|
|
while (waitpid (child, &status, 0) != child)
|
|
;
|
|
if (!WIFEXITED (status))
|
|
{
|
|
fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
|
|
return 1;
|
|
}
|
|
int exitstatus = WEXITSTATUS (status);
|
|
if (exitstatus != 127)
|
|
{
|
|
fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
#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 *prog_path = SRCDIR "executable-shell-script";
|
|
const char *prog_argv[2] = { prog_path, NULL };
|
|
|
|
int err = posix_spawn (&child, prog_path, &actions, NULL,
|
|
(char **) prog_argv, environ);
|
|
if (err != 0)
|
|
{
|
|
errno = err;
|
|
perror ("posix_spawn");
|
|
return 1;
|
|
}
|
|
|
|
posix_spawn_file_actions_destroy (&actions);
|
|
|
|
/* Wait for child. */
|
|
int status = 0;
|
|
while (waitpid (child, &status, 0) != child)
|
|
;
|
|
if (!WIFEXITED (status))
|
|
{
|
|
fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
|
|
return 1;
|
|
}
|
|
int exitstatus = WEXITSTATUS (status);
|
|
if (exitstatus != 0)
|
|
{
|
|
fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
|
|
return 1;
|
|
}
|
|
|
|
/* Check the contents of the data file. */
|
|
FILE *fp = fopen (DATA_FILENAME, "rb");
|
|
if (fp == NULL)
|
|
{
|
|
perror ("cannot open data file");
|
|
return 1;
|
|
}
|
|
char buf[1024];
|
|
int nread = fread (buf, 1, sizeof (buf), fp);
|
|
if (!(nread == 11 && memeq (buf, "Halle Potta", 11)))
|
|
{
|
|
fprintf (stderr, "data file wrong: has %d bytes, expected %d bytes\n", nread, 11);
|
|
return 1;
|
|
}
|
|
if (fclose (fp))
|
|
{
|
|
perror ("cannot close data file");
|
|
return 1;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* Clean up data file. */
|
|
unlink (DATA_FILENAME);
|
|
|
|
return test_exit_status;
|
|
}
|