1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * NAME 22 * pipe10.c 23 * 24 * DESCRIPTION 25 * Check that parent can open a pipe and have a child read from it 26 * 27 * ALGORITHM 28 * Parent opens pipe, child reads. Passes if child can read all the 29 * characters written by the parent. 30 * 31 * USAGE: <for command-line> 32 * pipe10 [-c n] [-f] [-i n] [-I x] [-P x] [-t] 33 * where, -c n : Run n copies concurrently. 34 * -f : Turn off functionality Testing. 35 * -i n : Execute test n times. 36 * -I x : Execute test for x seconds. 37 * -P x : Pause for x seconds between iterations. 38 * -t : Turn on syscall timing. 39 * 40 * HISTORY 41 * 07/2001 Ported by Wayne Boyer 42 * 43 * RESTRICTIONS 44 * None 45 */ 46 #include <errno.h> 47 #include <unistd.h> 48 #include <sys/wait.h> 49 #include <string.h> 50 #include "test.h" 51 52 char *TCID = "pipe10"; 53 int TST_TOTAL = 1; 54 55 void setup(void); 56 void cleanup(void); 57 58 ssize_t do_read(int fd, void *buf, size_t count) 59 { 60 ssize_t n; 61 62 do { 63 n = read(fd, buf, count); 64 } while (n < 0 && errno == EINTR); 65 66 return n; 67 } 68 69 int main(int ac, char **av) 70 { 71 int lc; 72 73 int fd[2]; /* fds for pipe read/write */ 74 char wrbuf[BUFSIZ], rebuf[BUFSIZ]; 75 int red, written; /* no of chars read and */ 76 /* written to pipe */ 77 int length, greater, forkstat; 78 int retval = 0, status, e_code; 79 80 tst_parse_opts(ac, av, NULL, NULL); 81 82 setup(); 83 84 for (lc = 0; TEST_LOOPING(lc); lc++) { 85 86 /* reset tst_count in case we are looping */ 87 tst_count = 0; 88 89 TEST(pipe(fd)); 90 91 if (TEST_RETURN == -1) { 92 retval = 1; 93 tst_resm(TFAIL, "pipe creation failed"); 94 continue; 95 } 96 97 strcpy(wrbuf, "abcdefghijklmnopqrstuvwxyz"); 98 length = strlen(wrbuf) + 1; 99 100 written = write(fd[1], wrbuf, length); 101 102 /* did write write at least some chars */ 103 if ((written < 0) || (written > length)) { 104 tst_brkm(TBROK, cleanup, "write to pipe failed"); 105 } 106 107 forkstat = FORK_OR_VFORK(); 108 109 if (forkstat == -1) { 110 tst_brkm(TBROK, cleanup, "fork() failed"); 111 } 112 113 if (forkstat == 0) { /* child */ 114 red = do_read(fd[0], rebuf, written); 115 116 /* did read , get at least some chars */ 117 if ((red < 0) || (red > written)) { 118 tst_brkm(TBROK, cleanup, "read pipe failed"); 119 } 120 121 greater = strcmp(rebuf, wrbuf); 122 123 /* are the strings written and read equal */ 124 if (greater == 0) { 125 tst_resm(TPASS, "functionality is correct"); 126 } else { 127 retval = 1; 128 tst_resm(TFAIL, "read & write strings do " 129 "not match"); 130 } 131 exit(retval); 132 } else { /* parent */ 133 /* wait for the child to finish */ 134 wait(&status); 135 /* make sure the child returned a good exit status */ 136 e_code = status >> 8; 137 if (e_code != 0) { 138 tst_resm(TFAIL, "Failures reported above"); 139 } 140 } 141 } 142 cleanup(); 143 144 tst_exit(); 145 } 146 147 /* 148 * setup() - performs all ONE TIME setup for this test. 149 */ 150 void setup(void) 151 { 152 153 tst_sig(FORK, DEF_HANDLER, cleanup); 154 155 TEST_PAUSE; 156 } 157 158 /* 159 * cleanup() - performs all ONE TIME cleanup for this test at 160 * completion or premature exit. 161 */ 162 void cleanup(void) 163 { 164 } 165