llseek02.c revision 865695bbc89088b9526ea9045410e5afb70a985c
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 * Test Name: llseek02 22 * 23 * Test Description: 24 * Verify that, 25 * 1. llseek() returns -1 and sets errno to EINVAL, if the 'Whence' argument 26 * is not a proper value. 27 * 2. llseek() returns -1 and sets errno to EBADF, if the file handle of 28 * the specified file is not valid. 29 * 30 * Expected Result: 31 * llseek() should fail with return value -1 and set expected errno. 32 * 33 * Algorithm: 34 * Setup: 35 * Setup signal handling. 36 * Create temporary directory. 37 * Pause for SIGUSR1 if option specified. 38 * 39 * Test: 40 * Loop if the proper options are given. 41 * Execute system call 42 * Check return code, if system call failed (return=-1) 43 * if errno set == expected errno 44 * Issue sys call fails with expected return value and errno. 45 * Otherwise, 46 * Issue sys call fails with unexpected errno. 47 * Otherwise, 48 * Issue sys call returns unexpected value. 49 * 50 * Cleanup: 51 * Print errno log and/or timing stats if options given 52 * Delete the temporary directory(s)/file(s) created. 53 * 54 * Usage: <for command-line> 55 * llseek02 [-c n] [-e] [-i n] [-I x] [-P x] [-t] 56 * where, -c n : Run n copies concurrently. 57 * -i n : Execute test n times. 58 * -I x : Execute test for x seconds. 59 * -P x : Pause for x seconds between iterations. 60 * -t : Turn on syscall timing. 61 * 62 * HISTORY 63 * 07/2001 Ported by Wayne Boyer 64 * 65 * RESTRICTIONS: 66 * None. 67 */ 68 69#include <stdio.h> 70#include <unistd.h> 71#include <sys/types.h> 72#include <errno.h> 73#include <fcntl.h> 74#include <utime.h> 75#include <string.h> 76#include <sys/stat.h> 77#include <signal.h> 78 79#include "test.h" 80#include "usctest.h" 81 82#define TEMP_FILE1 "tmp_file1" 83#define TEMP_FILE2 "tmp_file2" 84#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH 85#define SEEK_TOP 10 86 87char *TCID="llseek02"; /* Test program identifier. */ 88int TST_TOTAL=2; /* Total number of test cases. */ 89extern int Tst_count; /* Test Case counter for tst_* routines */ 90 91int no_setup(); 92int setup1(); /* setup function to test llseek() for EINVAL */ 93int setup2(); /* setup function to test llseek() for EBADF */ 94 95int fd1; /* file handle for testfile1 */ 96int fd2; /* file handle for testfile2 */ 97 98struct test_case_t { /* test case struct. to hold ref. test cond's*/ 99 int fd; 100 int Whence; 101 char *desc; 102 int exp_errno; 103 int (*setupfunc)(); 104} Test_cases[] = { 105 { 1, SEEK_TOP, "'whence' argument is not valid", EINVAL, setup1 }, 106 { 2, SEEK_SET, "'fd' is not an open file descriptor", EBADF, setup2 }, 107 { 0, 0, NULL, 0, no_setup } 108}; 109 110int exp_enos[] = {EINVAL, EBADF, 0}; 111 112void setup(); /* Main setup function of test */ 113void cleanup(); /* cleanup function for the test */ 114 115int 116main(int ac, char **av) 117{ 118 int lc; /* loop counter */ 119 char *msg; /* message returned from parse_opts */ 120 int fildes; /* file handle for testfile */ 121 int whence; /* position of file handle in the file */ 122 char *test_desc; /* test specific error message */ 123 loff_t offset; /* return value after llseek */ 124 int ind; /* counter to test different test conditions */ 125 126 /* Parse standard options given to run the test. */ 127 msg = parse_opts(ac, av, (option_t *) NULL, NULL); 128 if (msg != (char *) NULL) { 129 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); 130 tst_exit(); 131 } 132 133 /* Perform global setup for test */ 134 setup(); 135 136 /* set up expected error numbers */ 137 TEST_EXP_ENOS(exp_enos); 138 139 /* Check looping state if -i option given */ 140 for (lc = 0; TEST_LOOPING(lc); lc++) { 141 /* Reset Tst_count in case we are looping. */ 142 Tst_count=0; 143 144 for (ind = 0; Test_cases[ind].desc != NULL; ind++) { 145 fildes = Test_cases[ind].fd; 146 test_desc = Test_cases[ind].desc; 147 whence = Test_cases[ind].Whence; 148 149 /* Assign the 'fd' values appropriatly */ 150 if (fildes == 1) { 151 fildes = fd1; 152 } else { 153 fildes = fd2; 154 } 155 156 /* 157 * Invoke llseek(2) to test different test conditions. 158 * Verify that it fails with -1 return value and 159 * sets appropriate errno. 160 */ 161 TEST(llseek(fildes, (loff_t)0, whence)); 162 163 /* check return code of llseek(2) */ 164 if (TEST_RETURN != (loff_t)-1) { 165 tst_resm(TFAIL, "llseek() returned %d, expected" 166 " -1, errno:%d", TEST_RETURN, 167 Test_cases[ind].exp_errno); 168 continue; 169 } 170 TEST_ERROR_LOG(TEST_ERRNO); 171 if (TEST_ERRNO == Test_cases[ind].exp_errno) { 172 tst_resm(TPASS, "llseek() fails, %s, errno:%d", 173 test_desc, TEST_ERRNO); 174 } else { 175 tst_resm(TFAIL, "llseek() fails, %s, errno:%d, " 176 "expected errno:%d", test_desc, 177 TEST_ERRNO, Test_cases[ind].exp_errno); 178 } 179 } 180 } 181 182 /* Call cleanup() to undo setup done for the test. */ 183 cleanup(); 184 185 /*NOTREACHED*/ 186} /* End main */ 187 188/* 189 * setup() - performs all ONE TIME setup for this test. 190 * Create a temporary directory and change directory to it. 191 * Invoke individual test setup functions according to the order 192 * set in test struct. definition. 193 */ 194void 195setup() 196{ 197 int ind; /* counter for test setup function */ 198 199 /* capture signals */ 200 tst_sig(NOFORK, DEF_HANDLER, cleanup); 201 202 /* Pause if that option was specified */ 203 TEST_PAUSE; 204 205 /* make a temp directory and cd to it */ 206 tst_tmpdir(); 207 208 /* call individual setup functions */ 209 for (ind = 0; Test_cases[ind].desc != NULL; ind++) { 210 Test_cases[ind].setupfunc(); 211 } 212} 213 214/* 215 * no_setup() - This is a dummy function which simply returns 0. 216 */ 217int 218no_setup() 219{ 220 return 0; 221} 222 223/* 224 * setup1() - setup function for a test condition for which llseek(2) 225 * returns -1 and sets errno to EINVAL. 226 * Creat a temporary file for reading/writing and write some data 227 * into it. 228 * This function returns 0 on success. 229 */ 230int 231setup1() 232{ 233 char write_buff[BUFSIZ]; /* buffer to hold data */ 234 235 /* Get the data to be written to temporary file */ 236 strcpy(write_buff, "abcdefg"); 237 238 /* Creat/open a temporary file under above directory */ 239 if ((fd1 = open(TEMP_FILE1, O_RDWR | O_CREAT, FILE_MODE)) == -1) { 240 tst_brkm(TBROK, cleanup, 241 "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s", 242 TEMP_FILE1, FILE_MODE, errno, strerror(errno)); 243 } 244 245 /* Write data into temporary file */ 246 if(write(fd1, write_buff, sizeof(write_buff)) <= 0) { 247 tst_brkm(TBROK, cleanup, "write(2) on %s Failed, errno=%d : %s", 248 TEMP_FILE1, errno, strerror(errno)); 249 } 250 251 return 0; 252} 253 254/* 255 * setup2() - setup function for a test condition for which llseek(2) 256 * returns -1 and sets errno to EBADF. 257 * Creat a temporary file for reading/writing and close it. 258 * This function returns 0 on success. 259 */ 260int 261setup2() 262{ 263 /* Creat/open a temporary file under above directory */ 264 if ((fd2 = open(TEMP_FILE2, O_RDWR | O_CREAT, FILE_MODE)) == -1) { 265 tst_brkm(TBROK, cleanup, 266 "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d :%s", 267 TEMP_FILE2, FILE_MODE, errno, strerror(errno)); 268 } 269 270 /* Close the temporary file created above */ 271 if (close(fd2) < 0) { 272 tst_brkm(TBROK, cleanup, "close(%s) Failed, errno=%d : %s:", 273 TEMP_FILE2, errno, strerror(errno)); 274 } 275 276 return 0; 277} 278/* 279 * cleanup() - performs all ONE TIME cleanup for this test at 280 * completion or premature exit. 281 * Close the temporary file. 282 * Remove the test directory and testfile created in the setup. 283 */ 284void 285cleanup() 286{ 287 /* 288 * print timing stats if that option was specified. 289 * print errno log if that option was specified. 290 */ 291 TEST_CLEANUP; 292 293 /* Close the temporary file(s) created in setup1/setup2*/ 294 if (close(fd1) < 0) { 295 tst_brkm(TFAIL, NULL, "close(%s) Failed, errno=%d : %s:", 296 TEMP_FILE1, errno, strerror(errno)); 297 } 298 299 /* Remove tmp dir and all files in it */ 300 tst_rmdir(); 301 302 /* exit with return code appropriate for results */ 303 tst_exit(); 304} 305