getdents02.c revision e1f008ec81a2828dfb2113ce97347946f42e9f3e
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 <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 73#ifndef __i386__ 74int main() 75{ 76 tst_resm(TINFO, "This test includes x86 asm and will not work on " 77 "this machine"); 78 tst_exit(); 79 return 0; 80} 81#else 82 83int main(int ac, char **av) 84{ 85 int lc; /* loop counter */ 86 char *msg; /* message returned from parse_opts */ 87 int rval, fd; 88 int count; 89 const int cnum = 141; /* system call number 141 = getdents */ 90 size_t size = 0; 91 char *dir_name = NULL; 92 struct dirent *dirp; 93 94 /* parse standard options */ 95 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { 96 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); 97 } 98 99 setup(); /* global setup */ 100 101 /* The following loop checks looping state if -i option given */ 102 103 for (lc = 0; TEST_LOOPING(lc); lc++) { 104 /* reset Tst_count in case we are looping */ 105 Tst_count = 0; 106 107 /* get the current working directory */ 108 109 if ((dir_name = getcwd(dir_name, size)) == NULL) { 110 tst_brkm(TBROK, cleanup, "Can not get current " 111 "directory name"); 112 } 113 114 /* allocate some space for the dirent structure */ 115 116 if ((dirp = 117 (struct dirent *)malloc(sizeof(struct dirent))) == NULL) { 118 tst_brkm(TBROK, cleanup, "malloc failed"); 119 } 120 121 /* set up count to be equal to the sizeof struct dirent */ 122 123 count = (int)sizeof(struct dirent); 124 125 /* set up a bad file descriptor */ 126 127 fd = -5; 128 129 /* 130 * here's a case where invoking the system call directly 131 * doesn't seem to work. getdents.h has an assembly 132 * macro to do the job. 133 * 134 * equivalent to - getdents(fd, dirp, count); 135 * if we could call getdents that way. 136 */ 137 138 rval = GETDENTS_ASM(); 139 140 /* 141 * Hopefully we get an error due to the bad file descriptor. 142 */ 143 144 if (rval < 0) { /* call returned an error */ 145 rval *= -1; 146 TEST_ERROR_LOG(rval); 147 148 switch (rval) { 149 case EBADF: 150 tst_resm(TPASS, "expected failure - errno = %d " 151 "- %s", rval, strerror(rval)); 152 break; 153 default: 154 tst_resm(TFAIL, "%s call failed to " 155 "produce EBADF - errno = %d : %s", 156 TCID, rval, strerror(rval)); 157 break; 158 } 159 } else { 160 tst_resm(TFAIL, "call failed to produce an " 161 "expected error - errno = %d - %s", rval, 162 strerror(rval)); 163 } 164 165 /* 166 * clean up things in case we are looping 167 */ 168 free(dir_name); 169 dir_name = NULL; 170 171 free(dirp); 172 } 173 174 cleanup(); 175 176 /*NOTREACHED*/ return 0; 177} 178 179/* 180 * setup() - performs all the ONE TIME setup for this test. 181 */ 182void setup(void) 183{ 184 /* capture signals */ 185 tst_sig(NOFORK, DEF_HANDLER, cleanup); 186 187 /* Pause if that option was specified */ 188 TEST_PAUSE; 189 190 /* create a test directory and cd into it */ 191 tst_tmpdir(); 192 193 /* Set up the expected error numbers for -e option */ 194 TEST_EXP_ENOS(exp_enos); 195} 196 197/* 198 * cleanup() - performs all the ONE TIME cleanup for this test at completion 199 * or premature exit. 200 */ 201void cleanup(void) 202{ 203 /* remove the test directory */ 204 tst_rmdir(); 205 206 /* 207 * print timing stats if that option was specified. 208 * print errno log if that option was specified. 209 */ 210 TEST_CLEANUP; 211 212 /* exit with return code appropriate for results */ 213 tst_exit(); 214} 215 216#endif /* __i386__ */ 217