1/* General tests for execpve.
2 Copyright (C) 2016-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <errno.h>
20#include <fcntl.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
24#include <wait.h>
25
26
27/* Nonzero if the program gets called via `exec'. */
28static int restart;
29
30
31#define CMDLINE_OPTIONS \
32 { "restart", no_argument, &restart, 1 },
33
34/* Prototype for our test function. */
35extern void do_prepare (int argc, char *argv[]);
36extern int do_test (int argc, char *argv[]);
37
38#include "../test-skeleton.c"
39
40#define EXECVPE_KEY "EXECVPE_ENV"
41#define EXECVPE_VALUE "execvpe_test"
42
43
44static int
45handle_restart (void)
46{
47 /* First check if only one variable is passed on execvpe. */
48 int env_count = 0;
49 for (char **e = environ; *e != NULL; ++e)
50 if (++env_count == INT_MAX)
51 {
52 printf (format: "Environment variable number overflow");
53 exit (EXIT_FAILURE);
54 }
55 if (env_count != 1)
56 {
57 printf (format: "Wrong number of environment variables");
58 exit (EXIT_FAILURE);
59 }
60
61 /* Check if the combinarion os "EXECVPE_ENV=execvpe_test" */
62 const char *env = getenv (EXECVPE_KEY);
63 if (env == NULL)
64 {
65 printf (format: "Test environment variable not found");
66 exit (EXIT_FAILURE);
67 }
68
69 if (strncmp (env, EXECVPE_VALUE, sizeof (EXECVPE_VALUE)))
70 {
71 printf (format: "Test environment variable with wrong value");
72 exit (EXIT_FAILURE);
73 }
74
75 return 0;
76}
77
78
79int
80do_test (int argc, char *argv[])
81{
82 pid_t pid;
83 int status;
84
85 /* We must have
86 - one or four parameters left if called initially
87 + path for ld.so optional
88 + "--library-path" optional
89 + the library path optional
90 + the application name
91
92 if --enable-hardcoded-path-in-tests is used, just
93 + the application name
94 */
95
96 if (restart)
97 {
98 if (argc != 1)
99 {
100 printf (format: "Wrong number of arguments (%d) in restart\n", argc);
101 exit (EXIT_FAILURE);
102 }
103
104 return handle_restart ();
105 }
106
107 if (argc != 2 && argc != 5)
108 {
109 printf (format: "Wrong number of arguments (%d)\n", argc);
110 exit (EXIT_FAILURE);
111 }
112
113 /* We want to test the `execvpe' function. To do this we restart the
114 program with an additional parameter. */
115 pid = fork ();
116 if (pid == 0)
117 {
118 /* This is the child. Construct the command line. */
119
120 /* We cast here to char* because the test itself does not modify neither
121 the argument nor the environment list. */
122 char *envs[] = { (char*)(EXECVPE_KEY "=" EXECVPE_VALUE), NULL };
123 if (argc == 5)
124 {
125 char *args[] = { argv[1], argv[2], argv[3], argv[4],
126 (char *) "--direct", (char *) "--restart", NULL };
127 execvpe (file: args[0], argv: args, envp: envs);
128 }
129 else
130 {
131 char *args[] = { argv[0],
132 (char *) "--direct", (char *) "--restart", NULL };
133 execvpe (file: args[0], argv: args, envp: envs);
134 }
135
136 puts (s: "Cannot exec");
137 exit (EXIT_FAILURE);
138 }
139 else if (pid == (pid_t) -1)
140 {
141 puts (s: "Cannot fork");
142 return 1;
143 }
144
145 /* Wait for the child. */
146 if (waitpid (pid: pid, stat_loc: &status, options: 0) != pid)
147 {
148 puts (s: "Wrong child");
149 return 1;
150 }
151
152 if (WTERMSIG (status) != 0)
153 {
154 puts (s: "Child terminated incorrectly");
155 return 1;
156 }
157 status = WEXITSTATUS (status);
158
159 return status;
160}
161

source code of glibc/posix/tst-execvpe5.c