1 /* 2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24 * Mountain View, CA 94043, or: 25 * 26 * http://www.sgi.com 27 * 28 * For further information regarding this notice, see: 29 * 30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 31 * 32 * 33 * OS Test - Silicon Graphics, Inc. 34 * TEST IDENTIFIER : fork01 35 * EXECUTED BY : anyone 36 * TEST TITLE : Basic test for fork(2) 37 * PARENT DOCUMENT : frktds02 38 * TEST CASE TOTAL : 2 39 * WALL CLOCK TIME : 1 40 * CPU TYPES : ALL 41 * AUTHOR : Kathy Olmsted 42 * CO-PILOT : Steve Shaw 43 * DATE STARTED : 06/17/92 44 * INITIAL RELEASE : UNICOS 7.0 45 * TEST CASES 46 * 1.) fork returns without error 47 * 2.) fork returns the pid of the child 48 * INPUT SPECIFICATIONS 49 * The standard options for system call tests are accepted. 50 * (See the parse_opts(3) man page). 51 * OUTPUT SPECIFICATIONS 52 * DURATION 53 * Terminates - with frequency and infinite modes. 54 * SIGNALS 55 * Uses SIGUSR1 to pause before test if option set. 56 * (See the parse_opts(3) man page). 57 * RESOURCES 58 * None 59 * ENVIRONMENTAL NEEDS 60 * No run-time environmental needs. 61 * SPECIAL PROCEDURAL REQUIREMENTS 62 * None 63 * INTERCASE DEPENDENCIES 64 * None 65 * DETAILED DESCRIPTION 66 * Setup: 67 * Setup signal handling. 68 * Pause for SIGUSR1 if option specified. 69 * Test: 70 * Loop if the proper options are given. 71 * fork() 72 * Check return code, if system call failed (return=-1) 73 * Log the errno and Issue a FAIL message. 74 * Otherwise, Issue a PASS message. 75 * CHILD: 76 * determine PID 77 * write to PID to a file and close the file 78 * exit 79 * PARENT: 80 * wait for child to exit 81 * read child PID from file 82 * compare child PID to fork() return code and report 83 * results 84 * 85 * Cleanup: 86 * Print errno log and/or timing stats if options given 87 */ 88 89 #include <errno.h> 90 #include <string.h> 91 #include <signal.h> 92 #include <fcntl.h> 93 #include <stdlib.h> 94 #include <sys/types.h> 95 #include <sys/wait.h> 96 #include "test.h" 97 98 #define KIDEXIT 42 99 static void setup(); 100 static void cleanup(); 101 102 #define LINE_SZ 20 103 #define FILENAME "childpid" 104 105 char *TCID = "fork01"; 106 int TST_TOTAL = 2; 107 108 /* 109 * child_pid - the child side of the test 110 * determine the PID and write to a file 111 */ 112 static void child_pid(void) 113 { 114 115 int fildes; 116 char tmp_line[LINE_SZ]; 117 118 fildes = creat(FILENAME, 0700); 119 sprintf(tmp_line, "%d\n", getpid()); 120 write(fildes, tmp_line, LINE_SZ); 121 close(fildes); 122 123 } 124 125 /* 126 * parent_pid - the parent side of the test 127 * read the value determined by the child 128 * compare and report results 129 */ 130 static void parent_pid(void) 131 { 132 133 int fildes; 134 char tmp_line[LINE_SZ]; 135 pid_t child_id; 136 137 fildes = open(FILENAME, O_RDWR); 138 if (fildes == -1) { 139 tst_brkm(TBROK, cleanup, 140 "parent open failed. errno: %d (%s)\n", 141 errno, strerror(errno)); 142 } else { 143 if (read(fildes, tmp_line, LINE_SZ) == 0) { 144 tst_brkm(TBROK, cleanup, 145 "fork(): parent failed to read PID from file errno: %d (%s)", 146 errno, strerror(errno)); 147 } else { 148 child_id = atoi(tmp_line); 149 if (TEST_RETURN != child_id) { 150 tst_resm(TFAIL, 151 "child reported a pid of %d. parent received %ld from fork()", 152 child_id, TEST_RETURN); 153 } else { 154 tst_resm(TPASS, 155 "child pid and fork() return agree: %d", 156 child_id); 157 } 158 } 159 close(fildes); 160 } 161 } 162 163 int main(int ac, char **av) 164 { 165 int lc; 166 int fails; 167 int kid_status, wait_status; 168 169 tst_parse_opts(ac, av, NULL, NULL); 170 171 setup(); 172 173 for (lc = 0; TEST_LOOPING(lc); lc++) { 174 tst_count = 0; 175 fails = 0; 176 177 TEST(fork()); 178 if (TEST_RETURN == -1) { 179 tst_resm(TFAIL, "fork() Failed, errno=%d : %s", 180 TEST_ERRNO, strerror(TEST_ERRNO)); 181 tst_resm(TBROK, "unable to continue"); 182 } 183 if (TEST_RETURN == 0) { 184 /* child */ 185 child_pid(); 186 exit(KIDEXIT); 187 } else { 188 /* parent */ 189 tst_resm(TPASS, "fork() returned %ld", 190 TEST_RETURN); 191 /* wait for the child to complete */ 192 wait_status = waitpid(TEST_RETURN, &kid_status, 0); 193 194 if (wait_status == TEST_RETURN) { 195 if (kid_status != KIDEXIT << 8) { 196 tst_resm(TBROK, 197 "incorrect child status returned on wait(): %d", 198 kid_status); 199 fails++; 200 } 201 } else { 202 tst_resm(TBROK, 203 "wait() for child status failed with %d errno: %d : %s", 204 wait_status, errno, 205 strerror(errno)); 206 fails++; 207 } 208 if (fails == 0) { 209 /* verification tests */ 210 parent_pid(); 211 } 212 } /* TEST_RETURN */ 213 } 214 215 cleanup(); 216 tst_exit(); 217 } 218 219 static void setup(void) 220 { 221 222 tst_sig(FORK, DEF_HANDLER, cleanup); 223 224 TEST_PAUSE; 225 226 tst_tmpdir(); 227 } 228 229 static void cleanup(void) 230 { 231 232 tst_rmdir(); 233 234 } 235