getdents02.c revision 74948ad801d4aba1c872652580b8b331e41aefca
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 * getdents02.c 23 * 24 * DESCRIPTION 25 * getdents02 - check that we get a failure with a bad file descriptor 26 * 27 * ALGORITHM 28 * loop if that option was specified 29 * issue the system call using a bad file descriptor 30 * check the errno value 31 * issue a PASS message if we get EBADF - errno 9 32 * otherwise, the tests fails 33 * issue a FAIL message 34 * break any remaining tests 35 * call cleanup 36 * 37 * USAGE: <for command-line> 38 * getdents02 [-c n] [-e] [-i n] [-I x] [-P x] [-t] 39 * where, -c n : Run n copies concurrently. 40 * -e : Turn on errno logging. 41 * -i n : Execute test n times. 42 * -I x : Execute test for x seconds. 43 * -P x : Pause for x seconds between iterations. 44 * -t : Turn on syscall timing. 45 * 46 * HISTORY 47 * 03/2001 - Written by Wayne Boyer 48 * 49 * RESTRICTIONS 50 * none 51 */ 52 53#include "getdents.h" 54#include "test.h" 55#include "usctest.h" 56 57#include <errno.h> 58#include <fcntl.h> 59#include <linux/types.h> 60#include <linux/dirent.h> 61#include <linux/unistd.h> 62#include <unistd.h> 63 64void cleanup(void); 65void setup(void); 66 67char *TCID = "getdents02"; 68int TST_TOTAL = 1; 69extern int Tst_count; 70 71int exp_enos[] = {EBADF, 0}; /* 0 terminated list of expected errnos */ 72 73int main(int ac, char **av) 74{ 75 int lc; /* loop counter */ 76 char *msg; /* message returned from parse_opts */ 77 int rval, fd; 78 int count; 79 const int cnum = 141; /* system call number 141 = getdents */ 80 size_t size = 0; 81 char *dir_name = NULL; 82 struct dirent *dirp; 83 84#ifndef __i386__ 85 tst_resm(TINFO, "This test includes x86 asm and will not work on " 86 "this machine"); 87 tst_exit(); 88#endif /* __i386__ */ 89 90 /* parse standard options */ 91 if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){ 92 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); 93 } 94 95 setup(); /* global setup */ 96 97 /* The following loop checks looping state if -i option given */ 98 99 for (lc = 0; TEST_LOOPING(lc); lc++) { 100 /* reset Tst_count in case we are looping */ 101 Tst_count = 0; 102 103 /* get the current working directory */ 104 105 if ((dir_name = getcwd(dir_name, size)) == NULL) { 106 tst_brkm(TBROK, cleanup, "Can not get current " 107 "directory name"); 108 } 109 110 /* allocate some space for the dirent structure */ 111 112 if ((dirp = 113 (struct dirent *)malloc(sizeof(struct dirent))) == NULL) { 114 tst_brkm(TBROK, cleanup, "malloc failed"); 115 } 116 117 /* set up count to be equal to the sizeof struct dirent */ 118 119 count = (int)sizeof(struct dirent); 120 121 /* set up a bad file descriptor */ 122 123 fd = -5; 124 125 /* 126 * here's a case where invoking the system call directly 127 * doesn't seem to work. getdents.h has an assembly 128 * macro to do the job. 129 * 130 * equivalent to - getdents(fd, dirp, count); 131 * if we could call getdents that way. 132 */ 133 134 rval = GETDENTS_ASM(); 135 136 /* 137 * Hopefully we get an error due to the bad file descriptor. 138 */ 139 140 if (rval < 0) { /* call returned an error */ 141 rval *= -1; 142 TEST_ERROR_LOG(rval); 143 144 switch(rval) { 145 case EBADF: 146 tst_resm(TPASS, "expected failure - errno = %d " 147 "- %s", rval, strerror(rval)); 148 break; 149 default: 150 tst_resm(TFAIL, "%s call failed to " 151 "produce EBADF - errno = %d : %s", 152 TCID, rval, strerror(rval)); 153 break; 154 } 155 } else { 156 tst_resm(TFAIL, "call failed to produce an " 157 "expected error - errno = %d - %s", rval, 158 strerror(rval)); 159 } 160 161 /* 162 * clean up things in case we are looping 163 */ 164 free(dir_name); 165 dir_name = NULL; 166 167 free(dirp); 168 } 169 170 cleanup(); 171 172 /*NOTREACHED*/ 173} 174 175/* 176 * setup() - performs all the ONE TIME setup for this test. 177 */ 178void 179setup(void) 180{ 181 /* capture signals */ 182 tst_sig(NOFORK, DEF_HANDLER, cleanup); 183 184 /* Pause if that option was specified */ 185 TEST_PAUSE; 186 187 /* create a test directory and cd into it */ 188 tst_tmpdir(); 189 190 /* Set up the expected error numbers for -e option */ 191 TEST_EXP_ENOS(exp_enos); 192} 193 194/* 195 * cleanup() - performs all the ONE TIME cleanup for this test at completion 196 * or premature exit. 197 */ 198void 199cleanup(void) 200{ 201 /* remove the test directory */ 202 tst_rmdir(); 203 204 /* 205 * print timing stats if that option was specified. 206 * print errno log if that option was specified. 207 */ 208 TEST_CLEANUP; 209 210 /* exit with return code appropriate for results */ 211 tst_exit(); 212} 213 214