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