1 /******************************************************************************/ 2 /* Copyright (c) Crackerjack Project., 2007 */ 3 /* */ 4 /* This program is free software; you can redistribute it and/or modify */ 5 /* it under the terms of the GNU General Public License as published by */ 6 /* the Free Software Foundation; either version 2 of the License, or */ 7 /* (at your option) any later version. */ 8 /* */ 9 /* This program 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 */ 12 /* the GNU General Public License for more details. */ 13 /* */ 14 /* You should have received a copy of the GNU General Public License */ 15 /* along with this program; if not, write to the Free Software */ 16 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 17 /* */ 18 /******************************************************************************/ 19 /******************************************************************************/ 20 /* */ 21 /* File: unshare02.c */ 22 /* */ 23 /* Description: This tests the unshare error() syscall */ 24 /* */ 25 /* Usage: <for command-line> */ 26 /* unshare02 [-c n] [-e][-i n] [-I x] [-p x] [-t] */ 27 /* where, -c n : Run n copies concurrently. */ 28 /* -e : Turn on errno logging. */ 29 /* -i n : Execute test n times. */ 30 /* -I x : Execute test for x seconds. */ 31 /* -P x : Pause for x seconds between iterations. */ 32 /* -t : Turn on syscall timing. */ 33 /* */ 34 /* Total Tests: 2 */ 35 /* */ 36 /* Test Name: unshare02 */ 37 /* History: Porting from Crackerjack to LTP is done by */ 38 /* Manas Kumar Nayak maknayak (at) in.ibm.com> */ 39 /******************************************************************************/ 40 41 #define _GNU_SOURCE 42 43 #include <stdio.h> 44 #include <sys/wait.h> 45 #include <sys/types.h> 46 #include <sched.h> 47 #include <limits.h> 48 #include <unistd.h> 49 #include <sys/types.h> 50 #include <sys/syscall.h> 51 #include <errno.h> 52 #include <pwd.h> 53 #include <grp.h> 54 #include <string.h> 55 #include <sys/param.h> 56 #include <stdio.h> 57 58 #include "test.h" 59 #include "safe_macros.h" 60 #include "config.h" 61 62 char *TCID = "unshare02"; 63 int testno; 64 int TST_TOTAL = 2; 65 66 #ifdef HAVE_UNSHARE 67 68 /* Extern Global Functions */ 69 /******************************************************************************/ 70 /* */ 71 /* Function: cleanup */ 72 /* */ 73 /* Description: Performs all one time clean up for this test on successful */ 74 /* completion, premature exit or failure. Closes all temporary */ 75 /* files, removes all temporary directories exits the test with */ 76 /* appropriate TEST_RETURNurn code by calling tst_exit() function. */ 77 /* */ 78 /* Input: None. */ 79 /* */ 80 /* Output: None. */ 81 /* */ 82 /* Return: On failure - Exits calling tst_exit(). Non '0' TEST_RETURNurn code. */ 83 /* On success - Exits calling tst_exit(). With '0' TEST_RETURNurn code. */ 84 /* */ 85 /******************************************************************************/ 86 void cleanup(void) 87 { 88 89 tst_rmdir(); 90 91 /* Exit with appropriate TEST_RETURNurn code. */ 92 93 } 94 95 /* Local Functions */ 96 /******************************************************************************/ 97 /* */ 98 /* Function: setup */ 99 /* */ 100 /* Description: Performs all one time setup for this test. This function is */ 101 /* typically used to capture signals, create temporary dirs */ 102 /* and temporary files that may be used in the course of this */ 103 /* test. */ 104 /* */ 105 /* Input: None. */ 106 /* */ 107 /* Output: None. */ 108 /* */ 109 /* Return: On failure - Exits by calling cleanup(). */ 110 /* On success - TEST_RETURNurns 0. */ 111 /* */ 112 /******************************************************************************/ 113 void setup(void) 114 { 115 /* Capture signals if any */ 116 /* Create temporary directories */ 117 TEST_PAUSE; 118 tst_tmpdir(); 119 } 120 121 int main(int ac, char **av) 122 { 123 pid_t pid1; 124 int lc; 125 int rval; 126 127 tst_parse_opts(ac, av, NULL, NULL); 128 129 setup(); 130 131 for (lc = 0; TEST_LOOPING(lc); ++lc) { 132 tst_count = 0; 133 for (testno = 0; testno < TST_TOTAL; ++testno) { 134 135 TEST(pid1 = fork()); //call to fork() 136 if (TEST_RETURN == -1) { 137 tst_brkm(TFAIL | TTERRNO, cleanup, 138 "fork() failed."); 139 } else if (TEST_RETURN == 0) { 140 TEST_RETURN = unshare(-1); 141 if (TEST_RETURN == 0) { 142 printf("Call unexpectedly succeeded\n"); 143 rval = 1; 144 } else if (TEST_RETURN == -1) { 145 if (errno == EINVAL) { 146 printf("Got EINVAL\n"); 147 rval = 0; 148 } else if (errno == ENOSYS) { 149 rval = 1; 150 } else { 151 perror("unshare failed"); 152 rval = 2; 153 } 154 } 155 exit(rval); 156 } else { 157 SAFE_WAIT(cleanup, &rval); 158 if (rval != 0 && WIFEXITED(rval)) { 159 switch (WEXITSTATUS(rval)) { 160 case 1: 161 tst_brkm(TBROK, cleanup, 162 "unshare call unsupported " 163 "in kernel"); 164 break; 165 case 2: 166 tst_brkm(TFAIL, cleanup, 167 "unshare call failed"); 168 break; 169 } 170 } 171 } 172 173 TEST(pid1 = fork()); //call to fork() 174 if (pid1 == -1) { 175 tst_brkm(TFAIL | TTERRNO, cleanup, 176 "fork() failed."); 177 } else if (TEST_RETURN == 0) { 178 TEST_RETURN = unshare(0); 179 if (TEST_RETURN == 0) { 180 tst_resm(TPASS, "Call succeeded"); 181 rval = 0; 182 } else if (TEST_RETURN == -1) { 183 if (errno == ENOSYS) 184 rval = 1; 185 else { 186 perror("unshare failed"); 187 rval = 2; 188 } 189 } 190 exit(rval); 191 } else { 192 SAFE_WAIT(cleanup, &rval); 193 if (rval != 0 && WIFEXITED(rval)) { 194 switch (WEXITSTATUS(rval)) { 195 case 1: 196 tst_brkm(TBROK, cleanup, 197 "unshare call unsupported " 198 "in kernel"); 199 break; 200 case 2: 201 tst_brkm(TFAIL, cleanup, 202 "unshare call failed"); 203 break; 204 } 205 } 206 } 207 208 } 209 } 210 cleanup(); 211 tst_exit(); 212 } 213 #else 214 int main(void) 215 { 216 tst_brkm(TCONF, NULL, "unshare is undefined."); 217 } 218 #endif 219