]>
Commit | Line | Data |
---|---|---|
688903eb | 1 | /* Copyright (C) 2017-2018 Free Software Foundation, Inc. |
43ffc53a AS |
2 | This file is part of the GNU C Library. |
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 | |
15 | License along with the GNU C Library; if not, see | |
16 | <http://www.gnu.org/licenses/>. */ | |
17 | ||
18 | #include <unistd.h> | |
19 | #include <errno.h> | |
20 | #include <fcntl.h> | |
21 | #include <sys/wait.h> | |
22 | ||
23 | #include <support/check.h> | |
24 | ||
25 | /* Try executing "/bin/sh -c true", using FD opened on /bin/sh. */ | |
26 | static int | |
27 | try_fexecve (int fd) | |
28 | { | |
29 | pid_t pid = fork (); | |
30 | ||
31 | if (pid == 0) | |
32 | { | |
33 | static const char *const argv[] = { | |
34 | "/bin/sh", "-c", "true", NULL | |
35 | }; | |
36 | fexecve (fd, (char *const *) argv, environ); | |
37 | _exit (errno); | |
38 | } | |
39 | if (pid < 0) | |
40 | FAIL_RET ("fork failed: %m"); | |
41 | ||
42 | pid_t termpid; | |
43 | int status; | |
44 | termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)); | |
45 | if (termpid == -1) | |
46 | FAIL_RET ("waitpid failed: %m"); | |
47 | if (termpid != pid) | |
48 | FAIL_RET ("waitpid returned %ld != %ld", | |
49 | (long int) termpid, (long int) pid); | |
50 | if (!WIFEXITED (status)) | |
51 | FAIL_RET ("child hasn't exited normally"); | |
52 | ||
53 | /* If fexecve is unimplemented mark this test as UNSUPPORTED. */ | |
54 | if (WEXITSTATUS (status) == ENOSYS) | |
55 | FAIL_UNSUPPORTED ("fexecve is unimplemented"); | |
56 | ||
57 | if (WEXITSTATUS (status) != 0) | |
58 | { | |
59 | errno = WEXITSTATUS (status); | |
60 | FAIL_RET ("fexecve failed: %m"); | |
61 | } | |
62 | return 0; | |
63 | } | |
64 | ||
65 | static int | |
66 | do_test (void) | |
67 | { | |
68 | int fd; | |
69 | int ret; | |
70 | ||
71 | fd = open ("/bin/sh", O_RDONLY); | |
72 | if (fd < 0) | |
73 | FAIL_UNSUPPORTED ("/bin/sh cannot be opened: %m"); | |
74 | ret = try_fexecve (fd); | |
75 | close (fd); | |
76 | ||
77 | #ifdef O_PATH | |
78 | fd = open ("/bin/sh", O_RDONLY | O_PATH); | |
79 | if (fd < 0) | |
80 | FAIL_UNSUPPORTED ("/bin/sh cannot be opened (O_PATH): %m"); | |
81 | ret |= try_fexecve (fd); | |
82 | close (fd); | |
83 | #endif | |
84 | ||
85 | return ret; | |
86 | } | |
87 | ||
88 | #include <support/test-driver.c> |