1 /* Test of posix_spawnp() function.
2 Copyright (C) 2020-2021 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <https://www.gnu.org/licenses/>. */
26 #include <sys/types.h>
31 #define DATA_FILENAME "test-posix_spawn-script.tmp"
36 unlink (DATA_FILENAME);
38 /* Check an invocation of an executable script.
39 This should only be supported if the script has a '#!' marker; otherwise
40 it is unsecure: <https://sourceware.org/bugzilla/show_bug.cgi?id=13134>.
41 POSIX says that the execlp() and execvp() functions support executing
43 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html>,
44 but this is considered an antiquated feature. */
47 posix_spawn_file_actions_t actions;
48 ASSERT (posix_spawn_file_actions_init (&actions) == 0);
49 ASSERT (posix_spawn_file_actions_addopen (&actions, STDOUT_FILENO,
51 O_RDWR | O_CREAT | O_TRUNC, 0600)
57 for (i = 0; i < 2; i++)
59 const char *prog_path =
60 (i == 0 ? SRCDIR "executable-script" : SRCDIR "executable-script.sh");
61 const char *prog_argv[2] = { prog_path, NULL };
63 int err = posix_spawnp (&child, prog_path, &actions, NULL,
64 (char **) prog_argv, environ);
70 perror ("posix_spawn");
76 while (waitpid (child, &status, 0) != child)
78 if (!WIFEXITED (status))
80 fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
83 int exitstatus = WEXITSTATUS (status);
84 if (exitstatus != 127)
86 fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
93 #if defined _WIN32 && !defined __CYGWIN__
94 /* On native Windows, scripts - even with '#!' marker - are not executable.
95 Only .bat and .cmd files are. */
96 fprintf (stderr, "Skipping test: scripts are not executable on this platform.\n");
100 const char *prog_path = SRCDIR "executable-shell-script";
101 const char *prog_argv[2] = { prog_path, NULL };
103 int err = posix_spawnp (&child, prog_path, &actions, NULL,
104 (char **) prog_argv, environ);
108 perror ("posix_spawn");
112 posix_spawn_file_actions_destroy (&actions);
114 /* Wait for child. */
116 while (waitpid (child, &status, 0) != child)
118 if (!WIFEXITED (status))
120 fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
123 int exitstatus = WEXITSTATUS (status);
126 fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
130 /* Check the contents of the data file. */
131 FILE *fp = fopen (DATA_FILENAME, "rb");
134 perror ("cannot open data file");
138 int nread = fread (buf, 1, sizeof (buf), fp);
139 if (!(nread == 11 && memcmp (buf, "Halle Potta", 11) == 0))
141 fprintf (stderr, "data file wrong: has %d bytes, expected %d bytes\n", nread, 11);
146 perror ("cannot close data file");
152 /* Clean up data file. */
153 unlink (DATA_FILENAME);