1 /* 2 * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved. 3 * Copyright (c) 2012 Wanlong Gao <gaowanlong@cn.fujitsu.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 * You should have received a copy of the GNU General Public License along 14 * with this program; if not, write the Free Software Foundation, Inc., 15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 * 17 */ 18 /* 19 * Check for equality of pid of child & return value of clone(2) 20 * Test: 21 * Open a pipe. 22 * Loop if the proper options are given. 23 * Call clone(2) called without SIGCHLD 24 * 25 * CHILD: 26 * writes the pid to pipe 27 * PARENT: 28 * reads child'd pid from pipe 29 * if child's pid == return value from clone(2) 30 * Test passed 31 * else 32 * test failed 33 */ 34 35 #if defined UCLINUX && !__THROW 36 /* workaround for libc bug */ 37 #define __THROW 38 #endif 39 40 #include <errno.h> 41 #include <sched.h> 42 #include <sys/wait.h> 43 #include "test.h" 44 45 #include "clone_platform.h" 46 47 static void setup(void); 48 static void cleanup(void); 49 static int child_fn(); 50 51 static int pfd[2]; 52 53 char *TCID = "clone03"; 54 int TST_TOTAL = 1; 55 56 int main(int ac, char **av) 57 { 58 59 int lc; 60 void *child_stack; 61 char buff[10]; 62 int child_pid, status; 63 64 tst_parse_opts(ac, av, NULL, NULL); 65 66 setup(); 67 68 /* Allocate stack for child */ 69 child_stack = malloc(CHILD_STACK_SIZE); 70 if (child_stack == NULL) 71 tst_brkm(TBROK, cleanup, "Cannot allocate stack for child"); 72 73 for (lc = 0; TEST_LOOPING(lc); lc++) { 74 tst_count = 0; 75 76 if ((pipe(pfd)) == -1) 77 tst_brkm(TBROK | TERRNO, cleanup, "pipe failed"); 78 79 TEST(ltp_clone(SIGCHLD, child_fn, NULL, CHILD_STACK_SIZE, 80 child_stack)); 81 82 if (TEST_RETURN == -1) 83 tst_brkm(TFAIL | TTERRNO, cleanup, "clone() failed"); 84 85 /* close write end from parent */ 86 if ((close(pfd[1])) == -1) 87 tst_brkm(TBROK | TERRNO, cleanup, 88 "close(pfd[1]) failed"); 89 90 /* Read pid from read end */ 91 if ((read(pfd[0], buff, sizeof(buff))) == -1) 92 tst_brkm(TBROK | TERRNO, cleanup, 93 "read from pipe failed"); 94 95 /* Close read end from parent */ 96 if ((close(pfd[0])) == -1) 97 tst_resm(TWARN | TERRNO, "close(pfd[0]) failed"); 98 99 /* Get child's pid from pid string */ 100 child_pid = atoi(buff); 101 102 if (TEST_RETURN == child_pid) 103 tst_resm(TPASS, "Test passed"); 104 else 105 tst_resm(TFAIL, "Test failed"); 106 107 if ((wait(&status)) == -1) 108 tst_brkm(TBROK | TERRNO, cleanup, 109 "wait failed, status: %d", status); 110 } 111 112 free(child_stack); 113 114 cleanup(); 115 tst_exit(); 116 } 117 118 static void setup(void) 119 { 120 tst_sig(FORK, DEF_HANDLER, cleanup); 121 TEST_PAUSE; 122 } 123 124 static void cleanup(void) 125 { 126 } 127 128 static int child_fn(void) 129 { 130 char pid[10]; 131 132 /* Close read end from child */ 133 if ((close(pfd[0])) == -1) 134 perror("close(pfd[0]) failed"); 135 136 sprintf(pid, "%d", getpid()); 137 138 /* Write pid string to pipe */ 139 if ((write(pfd[1], pid, sizeof(pid))) == -1) 140 perror("write to pipe failed"); 141 142 /* Close write end of pipe from child */ 143 if ((close(pfd[1])) == -1) 144 perror("close(pfd[1]) failed"); 145 146 exit(1); 147 } 148