execute-tests: Fix compilation error on AIX in 32-bit mode.
[gnulib.git] / tests / test-execute-child.c
blob16ccff7d60440e66f23ea0595ee6a1b4d316ce76
1 /* Child program invoked by test-execute-main.
2 Copyright (C) 2009-2020 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)
7 any later version.
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/>. */
17 /* If the user's config.h happens to include <sys/stat.h>, let it include only
18 the system's <sys/stat.h> here. */
19 #define __need_system_sys_stat_h
20 #include <config.h>
22 /* Get the original definition of fstat. It might be defined as a macro.
23 Also, 'stat' might be defined as a macro. */
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #undef __need_system_sys_stat_h
28 /* Return non-zero if FD is opened to a device. */
29 static int
30 is_device (int fd)
32 struct stat st;
33 return
34 #if defined _WIN32 && ! defined __CYGWIN__
35 _fstat (fd, &st) >= 0
36 #else
37 fstat (fd, &st) >= 0
38 #endif
39 && !S_ISREG (st.st_mode);
42 /* Now include the other header files. */
43 #include <fcntl.h>
44 #include <signal.h>
45 #include <stdint.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <unistd.h>
51 #if defined _WIN32 && ! defined __CYGWIN__
52 /* Get declarations of the native Windows API functions. */
53 # define WIN32_LEAN_AND_MEAN
54 # include <windows.h>
55 /* Get _get_osfhandle, _isatty, _chdir, _getcwd. */
56 # include <io.h>
57 #endif
59 /* In this file, we use only system functions, no overrides from gnulib. */
60 #undef atoi
61 #undef fcntl
62 #undef fflush
63 #undef fgetc
64 #undef fprintf
65 #undef fputs
66 #undef getcwd
67 #undef isatty
68 #undef raise
69 #undef read
70 #undef sprintf
71 #undef strcmp
72 #undef strlen
73 #undef write
75 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
76 static void __cdecl
77 gl_msvc_invalid_parameter_handler (const wchar_t *expression,
78 const wchar_t *function,
79 const wchar_t *file,
80 unsigned int line,
81 uintptr_t dummy)
84 #endif
86 /* Return non-zero if FD is open. */
87 static int
88 is_open (int fd)
90 #if defined _WIN32 && ! defined __CYGWIN__
91 /* On native Windows, the initial state of unassigned standard file
92 descriptors is that they are open but point to an
93 INVALID_HANDLE_VALUE, and there is no fcntl. */
94 return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
95 #else
96 # ifndef F_GETFL
97 # error Please port fcntl to your platform
98 # endif
99 return 0 <= fcntl (fd, F_GETFL);
100 #endif
104 main (int argc, char *argv[])
106 if (argc == 1)
107 /* Check an invocation without arguments. Check the exit code. */
108 return 40;
110 int test = atoi (argv[1]);
111 switch (test)
113 case 2:
114 /* Check argument passing. */
115 return !(argc == 12
116 && strcmp (argv[2], "abc def") == 0
117 && strcmp (argv[3], "abc\"def\"ghi") == 0
118 && strcmp (argv[4], "xyz\"") == 0
119 && strcmp (argv[5], "abc\\def\\ghi") == 0
120 && strcmp (argv[6], "xyz\\") == 0
121 && strcmp (argv[7], "???") == 0
122 && strcmp (argv[8], "***") == 0
123 && strcmp (argv[9], "") == 0
124 && strcmp (argv[10], "foo") == 0
125 && strcmp (argv[11], "") == 0);
126 #if !(defined _WIN32 && !defined __CYGWIN__)
127 case 3:
128 /* Check SIGPIPE handling with ignore_sigpipe = false. */
129 case 4:
130 /* Check SIGPIPE handling with ignore_sigpipe = true. */
131 raise (SIGPIPE);
132 return 71;
133 #endif
134 case 5:
135 /* Check other signal. */
136 raise (SIGINT);
137 return 71;
138 case 6:
139 /* Check stdin is inherited. */
140 return !(fgetc (stdin) == 'F' && fgetc (stdin) == 'o');
141 case 7:
142 /* Check null_stdin = true. */
143 return !(fgetc (stdin) == EOF);
144 case 8:
145 /* Check stdout is inherited, part 1 (regular file). */
146 return !(fputs ("bar", stdout) != EOF && fflush (stdout) == 0);
147 case 9:
148 /* Check stdout is inherited, part 2 (device). */
149 case 10:
150 /* Check null_stdout = true. */
151 return !is_device (STDOUT_FILENO);
152 case 11:
153 /* Check stderr is inherited, part 1 (regular file). */
154 return !(fputs ("bar", stderr) != EOF && fflush (stderr) == 0);
155 case 12:
156 /* Check stderr is inherited, part 2 (device). */
157 case 13:
158 /* Check null_stderr = true. */
159 return !is_device (STDERR_FILENO);
160 case 14:
161 case 15:
162 /* Check file descriptors >= 3 can be inherited. */
163 case 16:
164 /* Check file descriptors >= 3 with O_CLOEXEC bit are not inherited. */
165 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
166 /* Avoid exceptions from within _get_osfhandle. */
167 _set_invalid_parameter_handler (gl_msvc_invalid_parameter_handler);
168 #endif
170 char buf[300];
171 buf[0] = '\0';
172 char *p = buf;
173 int fd;
174 for (fd = 0; fd < 20; fd++)
175 #ifdef __NetBSD__
176 if (fd != 3)
177 #endif
178 if (is_open (fd))
180 sprintf (p, "%d ", fd);
181 p += strlen (p);
183 const char *expected = (test < 16 ? "0 1 2 10 " : "0 1 2 ");
184 if (strcmp (buf, expected) == 0)
185 return 0;
186 else
188 fprintf (stderr, "Test case %d: %s\n", test, buf); fflush (stderr);
189 return 1;
192 case 17:
193 /* Check that file descriptors >= 3, open for reading, can be inherited,
194 including the file position. */
196 char buf[6];
197 int n = read (10, buf, sizeof (buf));
198 return !(n == 4 && memcmp (buf, "obar", 4) == 0);
200 case 18:
201 /* Check that file descriptors >= 3, open for writing, can be inherited,
202 including the file position. */
204 int n = write (10, "bar", 3);
205 return !(n == 3);
207 case 19:
208 /* Check that file descriptors >= 3, when inherited, preserve their
209 isatty() property, part 1 (regular file). */
210 case 20:
211 /* Check that file descriptors >= 3, when inherited, preserve their
212 isatty() property, part 2 (character devices). */
214 #if defined _WIN32 && ! defined __CYGWIN__
215 return 4 + 2 * (_isatty (10) != 0) + (_isatty (11) != 0);
216 #else
217 return 4 + 2 * (isatty (10) != 0) + (isatty (11) != 0);
218 #endif
220 case 21:
221 /* Check execution in a different directory. */
223 char cwd[1024];
224 #if defined _WIN32 && ! defined __CYGWIN__
225 if (_chdir ("..") != 0)
226 return 1;
227 if (_getcwd (cwd, sizeof (cwd)) == NULL)
228 return 2;
229 #else
230 if (chdir ("..") != 0)
231 return 1;
232 if (getcwd (cwd, sizeof (cwd)) == NULL)
233 return 2;
234 #endif
235 return (argc == 3 && strcmp (argv[2], cwd) == 0 ? 0 : 3);
237 default:
238 abort ();