1 /*
2 * Copyright (c) International Business Machines Corp., 2001
3 * Copyright (c) 2015 Cyril Hrubis <chrubis@suse.cz>
4 *
5 * 07/2001 Ported by Wayne Boyer
6 * 04/2008 Roy Lee <roylee@andestech.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /*
24 * Attempt to execve(2) a file which is being opened by another process for
25 * writing fails with ETXTBSY.
26 */
27
28 #ifndef _GNU_SOURCE
29 #define _GNU_SOURCE
30 #endif
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <libgen.h>
36 #include <stdio.h>
37
38 #include "test.h"
39 #include "safe_macros.h"
40
41 #define TEST_APP "execve_child"
42
43 char *TCID = "execve04";
44 int TST_TOTAL = 1;
45
46 static void setup(void);
47 static void cleanup(void);
48 static void do_child(void);
49
main(int ac,char ** av)50 int main(int ac, char **av)
51 {
52 int lc;
53 pid_t pid;
54 char *argv[2] = {TEST_APP, NULL};
55 char *env[1] = {NULL};
56
57 tst_parse_opts(ac, av, NULL, NULL);
58
59 #ifdef UCLINUX
60 maybe_run_child(&do_child, "");
61 #endif
62
63 setup();
64
65 for (lc = 0; TEST_LOOPING(lc); lc++) {
66 if ((pid = FORK_OR_VFORK()) == -1) {
67 tst_brkm(TBROK, cleanup, "fork failed");
68 } else if (pid == 0) {
69 #ifdef UCLINUX
70 if (self_exec(av[0], "") < 0)
71 tst_brkm(TBROK, cleanup, "self_exec failed");
72 #else
73 do_child();
74 #endif
75 }
76
77 TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
78
79 TEST(execve(TEST_APP, argv, env));
80
81 if (TEST_ERRNO != ETXTBSY)
82 tst_resm(TFAIL | TTERRNO, "execve succeeded, expected failure");
83 else
84 tst_resm(TPASS | TTERRNO, "execve failed as expected");
85
86 TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
87 SAFE_WAIT(cleanup, NULL);
88 }
89
90 cleanup();
91 tst_exit();
92 }
93
setup(void)94 void setup(void)
95 {
96 char path[PATH_MAX];
97
98 if (tst_get_path(TEST_APP, path, sizeof(path))) {
99 tst_brkm(TBROK, NULL,
100 "Couldn't found "TEST_APP" binary in $PATH");
101 }
102
103 tst_tmpdir();
104
105 TST_CHECKPOINT_INIT(tst_rmdir);
106
107 SAFE_CP(tst_rmdir, path, ".");
108 }
109
cleanup(void)110 static void cleanup(void)
111 {
112 tst_rmdir();
113 }
114
do_child(void)115 static void do_child(void)
116 {
117 int fd;
118
119 #ifdef UCLINUX
120 TST_CHECKPOINT_INIT(NULL);
121 #endif
122
123 if ((fd = open(TEST_APP, O_WRONLY)) == -1) {
124 perror("open failed");
125 exit(1);
126 }
127
128 TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(NULL, 0);
129
130 exit(0);
131 }
132