1 /*
2 * Copyright (c) International Business Machines Corp., 2007
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 * the GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 ***************************************************************************/
17 #include "libclone.h"
18
do_clone_tests(unsigned long clone_flags,int (* fn1)(void * arg),void * arg1,int (* fn2)(void * arg),void * arg2)19 int do_clone_tests(unsigned long clone_flags,
20 int (*fn1) (void *arg), void *arg1,
21 int (*fn2) (void *arg), void *arg2)
22 {
23 int ret;
24
25 ret = ltp_clone_quick(clone_flags | SIGCHLD, fn1, arg1);
26
27 if (ret == -1) {
28 return -1;
29 }
30 if (fn2)
31 ret = fn2(arg2);
32 else
33 ret = 0;
34
35 return ret;
36 }
37
do_unshare_tests(unsigned long clone_flags,int (* fn1)(void * arg),void * arg1,int (* fn2)(void * arg),void * arg2)38 int do_unshare_tests(unsigned long clone_flags,
39 int (*fn1) (void *arg), void *arg1,
40 int (*fn2) (void *arg), void *arg2)
41 {
42 int pid, ret = 0;
43 int retpipe[2];
44 char buf[2];
45
46 if (pipe(retpipe) == -1) {
47 perror("pipe");
48 return -1;
49 }
50 pid = fork();
51 if (pid == -1) {
52 perror("fork");
53 close(retpipe[0]);
54 close(retpipe[1]);
55 return -1;
56 }
57 if (pid == 0) {
58 close(retpipe[0]);
59 ret = tst_syscall(SYS_unshare, clone_flags);
60 if (ret == -1) {
61 if (write(retpipe[1], "0", 2) < 0) {
62 perror("unshare:write(retpipe[1], ..)");
63 }
64 close(retpipe[1]);
65 exit(1);
66 } else {
67 if (write(retpipe[1], "1", 2) < 0) {
68 perror("unshare:write(retpipe[1], ..)");
69 }
70 }
71 close(retpipe[1]);
72 ret = fn1(arg1);
73 exit(ret);
74 } else {
75 close(retpipe[1]);
76 if (read(retpipe[0], &buf, 2) < 0) {
77 perror("unshare:read(retpipe[0], ..)");
78 }
79 close(retpipe[0]);
80 if (*buf == '0')
81 return -1;
82 if (fn2)
83 ret = fn2(arg2);
84 }
85
86 return ret;
87 }
88
do_plain_tests(int (* fn1)(void * arg),void * arg1,int (* fn2)(void * arg),void * arg2)89 int do_plain_tests(int (*fn1) (void *arg), void *arg1,
90 int (*fn2) (void *arg), void *arg2)
91 {
92 int ret = 0, pid;
93
94 pid = fork();
95 if (pid == -1) {
96 perror("fork");
97 return -1;
98 }
99 if (pid == 0)
100 exit(fn1(arg1));
101 if (fn2)
102 ret = fn2(arg2);
103 return ret;
104 }
105
do_clone_unshare_test(int use_clone,unsigned long clone_flags,int (* fn1)(void * arg),void * arg1)106 int do_clone_unshare_test(int use_clone, unsigned long clone_flags,
107 int (*fn1) (void *arg), void *arg1)
108 {
109 switch (use_clone) {
110 case T_NONE:
111 return do_plain_tests(fn1, arg1, NULL, NULL);
112 case T_CLONE:
113 return do_clone_tests(clone_flags, fn1, arg1, NULL, NULL);
114 case T_UNSHARE:
115 return do_unshare_tests(clone_flags, fn1, arg1, NULL, NULL);
116 default:
117 printf("%s: bad use_clone option: %d\n", __FUNCTION__,
118 use_clone);
119 return -1;
120 }
121 }
122
123 /*
124 * Run fn1 in a unshared environmnent, and fn2 in the original context
125 */
do_clone_unshare_tests(int use_clone,unsigned long clone_flags,int (* fn1)(void * arg),void * arg1,int (* fn2)(void * arg),void * arg2)126 int do_clone_unshare_tests(int use_clone, unsigned long clone_flags,
127 int (*fn1) (void *arg), void *arg1,
128 int (*fn2) (void *arg), void *arg2)
129 {
130 switch (use_clone) {
131 case T_NONE:
132 return do_plain_tests(fn1, arg1, fn2, arg2);
133 case T_CLONE:
134 return do_clone_tests(clone_flags, fn1, arg1, fn2, arg2);
135 case T_UNSHARE:
136 return do_unshare_tests(clone_flags, fn1, arg1, fn2, arg2);
137 default:
138 printf("%s: bad use_clone option: %d\n", __FUNCTION__,
139 use_clone);
140 return -1;
141 }
142 }
143