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