]>
Commit | Line | Data |
---|---|---|
581c785b | 1 | /* Copyright (C) 2002-2022 Free Software Foundation, Inc. |
3ca97e8f | 2 | This file is part of the GNU C Library. |
3ca97e8f UD |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Lesser General Public | |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
8 | ||
9 | The GNU C Library 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 GNU | |
12 | Lesser General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 | 15 | License along with the GNU C Library; if not, see |
5a82c748 | 16 | <https://www.gnu.org/licenses/>. */ |
3ca97e8f UD |
17 | |
18 | #include <stdlib.h> | |
f09542c5 AZ |
19 | #include <unistd.h> |
20 | #include <string.h> | |
21 | #include <signal.h> | |
22 | #include <paths.h> | |
3ca97e8f | 23 | |
f09542c5 AZ |
24 | #include <support/capture_subprocess.h> |
25 | #include <support/check.h> | |
26 | #include <support/temp_file.h> | |
27 | #include <support/support.h> | |
42dda89d | 28 | #include <support/xunistd.h> |
f09542c5 AZ |
29 | |
30 | static char *tmpdir; | |
31 | static long int namemax; | |
32 | ||
33 | static void | |
34 | do_prepare (int argc, char *argv[]) | |
35 | { | |
36 | tmpdir = support_create_temp_directory ("tst-system-"); | |
37 | /* Include the last '/0'. */ | |
38 | namemax = pathconf (tmpdir, _PC_NAME_MAX) + 1; | |
39 | TEST_VERIFY_EXIT (namemax != -1); | |
40 | } | |
41 | #define PREPARE do_prepare | |
42 | ||
43 | struct args | |
44 | { | |
45 | const char *command; | |
46 | int exit_status; | |
47 | int term_sig; | |
48 | const char *path; | |
49 | }; | |
50 | ||
51 | static void | |
52 | call_system (void *closure) | |
53 | { | |
54 | struct args *args = (struct args *) closure; | |
55 | int ret; | |
56 | ||
57 | if (args->path != NULL) | |
58 | TEST_COMPARE (setenv ("PATH", args->path, 1), 0); | |
59 | ret = system (args->command); | |
60 | if (args->term_sig == 0) | |
61 | { | |
62 | /* Expect regular termination. */ | |
63 | TEST_VERIFY (WIFEXITED (ret) != 0); | |
64 | TEST_COMPARE (WEXITSTATUS (ret), args->exit_status); | |
65 | } | |
66 | else | |
67 | { | |
68 | /* status_or_signal < 0. Expect termination by signal. */ | |
69 | TEST_VERIFY (WIFSIGNALED (ret) != 0); | |
70 | TEST_COMPARE (WTERMSIG (ret), args->term_sig); | |
71 | } | |
72 | } | |
3ca97e8f UD |
73 | |
74 | static int | |
75 | do_test (void) | |
76 | { | |
f09542c5 | 77 | TEST_VERIFY (system (NULL) != 0); |
3ca97e8f | 78 | |
f09542c5 AZ |
79 | { |
80 | char cmd[namemax]; | |
81 | memset (cmd, 'a', sizeof(cmd)); | |
82 | cmd[sizeof(cmd) - 1] = '\0'; | |
83 | ||
84 | struct support_capture_subprocess result; | |
85 | result = support_capture_subprocess (call_system, | |
86 | &(struct args) { | |
87 | cmd, 127, 0, tmpdir | |
88 | }); | |
89 | support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr); | |
90 | ||
4eda036f AZ |
91 | char *returnerr = xasprintf ("%s: execing %s failed: " |
92 | "No such file or directory", | |
f09542c5 AZ |
93 | basename(_PATH_BSHELL), cmd); |
94 | TEST_COMPARE_STRING (result.err.buffer, returnerr); | |
95 | free (returnerr); | |
96 | } | |
97 | ||
98 | { | |
99 | char cmd[namemax + 1]; | |
100 | memset (cmd, 'a', sizeof(cmd)); | |
101 | cmd[sizeof(cmd) - 1] = '\0'; | |
102 | ||
103 | struct support_capture_subprocess result; | |
104 | result = support_capture_subprocess (call_system, | |
105 | &(struct args) { | |
106 | cmd, 127, 0, tmpdir | |
107 | }); | |
108 | support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr); | |
109 | ||
4eda036f AZ |
110 | char *returnerr = xasprintf ("%s: execing %s failed: " |
111 | "File name too long", | |
f09542c5 AZ |
112 | basename(_PATH_BSHELL), cmd); |
113 | TEST_COMPARE_STRING (result.err.buffer, returnerr); | |
114 | free (returnerr); | |
115 | } | |
116 | ||
117 | { | |
118 | struct support_capture_subprocess result; | |
119 | result = support_capture_subprocess (call_system, | |
120 | &(struct args) { | |
4eda036f | 121 | "kill $$", 0, SIGTERM |
f09542c5 AZ |
122 | }); |
123 | support_capture_subprocess_check (&result, "system", 0, sc_allow_none); | |
124 | } | |
125 | ||
126 | { | |
127 | struct support_capture_subprocess result; | |
128 | result = support_capture_subprocess (call_system, | |
129 | &(struct args) { "echo ...", 0 }); | |
130 | support_capture_subprocess_check (&result, "system", 0, sc_allow_stdout); | |
131 | TEST_COMPARE_STRING (result.out.buffer, "...\n"); | |
132 | } | |
133 | ||
134 | { | |
135 | struct support_capture_subprocess result; | |
136 | result = support_capture_subprocess (call_system, | |
137 | &(struct args) { "exit 1", 1 }); | |
138 | support_capture_subprocess_check (&result, "system", 0, sc_allow_none); | |
139 | } | |
140 | ||
42dda89d AZ |
141 | { |
142 | struct stat64 st; | |
143 | xstat (_PATH_BSHELL, &st); | |
144 | mode_t mode = st.st_mode; | |
145 | xchmod (_PATH_BSHELL, mode & ~(S_IXUSR | S_IXGRP | S_IXOTH)); | |
146 | ||
147 | struct support_capture_subprocess result; | |
148 | result = support_capture_subprocess (call_system, | |
149 | &(struct args) { | |
150 | "exit 1", 127, 0 | |
151 | }); | |
152 | support_capture_subprocess_check (&result, "system", 0, sc_allow_none); | |
153 | ||
154 | xchmod (_PATH_BSHELL, st.st_mode); | |
155 | } | |
156 | ||
4eda036f | 157 | TEST_COMPARE (system (""), 0); |
f09542c5 AZ |
158 | |
159 | return 0; | |
160 | } | |
3ca97e8f | 161 | |
f09542c5 | 162 | #include <support/test-driver.c> |