• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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