close01.c revision cfb2c9599640d03969b2a14fabb185faef065834
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20/* 21 * NAME 22 * close01.c 23 * 24 * DESCRIPTION 25 * Test that closing a regular file and a pipe works correctly 26 * 27 * ALGORITHM 28 * Creat a file, and dup() a fildes 29 * Open a pipe 30 * call close() using the TEST macro 31 * if the call fails 32 * issue a FAIL message and continue 33 * else if STD_FUNCTIONAL_TEST 34 * attempt to close the file/pipe again 35 * if there is an error 36 * issue a PASS message 37 * else 38 * issue a FAIL message 39 * else 40 * issue a PASS message 41 * 42 * 43 * USAGE: <for command-line> 44 * close01 [-c n] [-f] [-i n] [-I x] [-P x] [-t] 45 * where, -c n : Run n copies concurrently. 46 * -f : Turn off functionality Testing. 47 * -i n : Execute test n times. 48 * -I x : Execute test for x seconds. 49 * -P x : Pause for x seconds between iterations. 50 * -t : Turn on syscall timing. 51 * 52 * HISTORY 53 * 07/2001 Ported by Wayne Boyer 54 * 55 * RESTRICTIONS 56 * None 57 */ 58 59#include <stdio.h> 60#include <errno.h> 61#include <fcntl.h> 62#include <sys/stat.h> 63#include "test.h" 64#include "usctest.h" 65 66void cleanup(void); 67void setup(void); 68 69char *TCID = "close01"; 70int TST_TOTAL = 2; 71extern int Tst_count; 72 73char fname[40] = ""; 74 75int fild, newfd, pipefildes[2]; 76 77struct test_case_t { 78 int *fd; 79 char *type; 80} TC[] = { 81 /* file descriptor for a regular file */ 82 {&newfd, "file"}, 83 84 /* file descriptor for a pipe */ 85 {&pipefildes[0], "pipe"} 86}; 87 88int 89main(int ac, char **av) 90{ 91 92 int i; 93 int lc; /* loop counter */ 94 char *msg; /* message returned from parse_opts */ 95 96 /* parse standard options */ 97 if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){ 98 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); 99 /*NOTREACHED*/ 100 } 101 102 setup(); /* global setup */ 103 104 /* The following loop checks looping state if -i option given */ 105 for (lc = 0; TEST_LOOPING(lc); lc++) { 106 107 /* reset Tst_count in case we are looping */ 108 Tst_count = 0; 109 110 /* set up the file and pipe for the test */ 111 if ((fild = creat(fname, 0777)) == -1) { 112 tst_brkm(TBROK, cleanup, "can't open file %s", fname); 113 } 114 115 if ((newfd = dup(fild)) == -1) { 116 tst_brkm(TBROK, cleanup, "can't dup the file des"); 117 } 118 119 if (pipe(pipefildes) == -1) { 120 tst_brkm(TBROK, cleanup, "can't open pipe"); 121 } 122 123 /* loop through the test cases */ 124 125 for (i = 0; i < TST_TOTAL; i++) { 126 127 TEST(close(*TC[i].fd)); 128 129 if (TEST_RETURN == -1) { 130 tst_resm(TFAIL, "call failed unexpectedly"); 131 continue; 132 } 133 134 if (STD_FUNCTIONAL_TEST) { 135 /* attempt to close the fd again */ 136 if (close(*TC[i].fd) == -1) { 137 tst_resm(TPASS, "%s appears closed", 138 TC[i].type); 139 } else { 140 tst_resm(TFAIL, "%s close succeeded on" 141 "second attempt", TC[i].type); 142 } 143 } else { 144 tst_resm(TPASS, "call succeeded"); 145 } 146 } 147 148 } 149 cleanup(); 150 151 return 0; 152 /*NOTREACHED*/ 153} 154 155/* 156 * setup() - performs all ONE TIME setup for this test 157 */ 158void 159setup(void) 160{ 161 int mypid; 162 163 /* capture signals */ 164 tst_sig(FORK, DEF_HANDLER, cleanup); 165 166 umask(0); 167 168 /* Pause if that option was specified */ 169 TEST_PAUSE; 170 171 /* make a temp directory and cd to it */ 172 tst_tmpdir(); 173 174 mypid = getpid(); 175 sprintf(fname, "fname.%d\n", mypid); 176} 177 178/* 179 * cleanup() - performs all the ONE TIME cleanup for this test at completion 180 * or premature exit. 181 */ 182void 183cleanup(void) 184{ 185 /* 186 * print timing status if that option was specified. 187 * print errno log if that option was specified 188 */ 189 close(fild); 190 191 TEST_CLEANUP; 192 193 /* Remove tmp dir and all files in it */ 194 tst_rmdir(); 195 196 /* exit with return code appropriate for results */ 197 tst_exit(); 198} 199