1 /* 2 * Copyright (c) International Business Machines Corp., 2001 3 * 06/2017 modified by Xiao Yang <yangx.jy@cn.fujitsu.com> 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, see <http://www.gnu.org/licenses/>. 17 */ 18 19 /* 20 * Description: 21 * lseek() succeeds to set the specified offset according to whence 22 * and read valid data from this location. 23 */ 24 25 #include <errno.h> 26 #include <string.h> 27 #include <sys/types.h> 28 #include <unistd.h> 29 #include "tst_test.h" 30 31 #define WRITE_STR "abcdefg" 32 #define TFILE "tfile" 33 34 static int fd; 35 static struct tcase { 36 off_t off; 37 int whence; 38 char *wname; 39 off_t exp_off; 40 ssize_t exp_size; 41 char *exp_data; 42 } tcases[] = { 43 {4, SEEK_SET, "SEEK_SET", 4, 3, "efg"}, 44 {-2, SEEK_CUR, "SEEK_CUR", 5, 2, "fg"}, 45 {-4, SEEK_END, "SEEK_END", 3, 4, "defg"}, 46 {0, SEEK_END, "SEEK_END", 7, 0, NULL}, 47 }; 48 49 static void verify_lseek(unsigned int n) 50 { 51 char read_buf[64]; 52 struct tcase *tc = &tcases[n]; 53 54 // reset the offset to end of file 55 SAFE_READ(0, fd, read_buf, sizeof(read_buf)); 56 57 memset(read_buf, 0, sizeof(read_buf)); 58 59 TEST(lseek(fd, tc->off, tc->whence)); 60 if (TEST_RETURN == (off_t) -1) { 61 tst_res(TFAIL | TTERRNO, "lseek(%s, %ld, %s) failed", TFILE, 62 tc->off, tc->wname); 63 return; 64 } 65 66 if (TEST_RETURN != tc->exp_off) { 67 tst_res(TFAIL, "lseek(%s, %ld, %s) returned %ld, expected %ld", 68 TFILE, tc->off, tc->wname, TEST_RETURN, tc->exp_off); 69 return; 70 } 71 72 SAFE_READ(1, fd, read_buf, tc->exp_size); 73 74 if (tc->exp_data && strcmp(read_buf, tc->exp_data)) { 75 tst_res(TFAIL, "lseek(%s, %ld, %s) read incorrect data", 76 TFILE, tc->off, tc->wname); 77 } else { 78 tst_res(TPASS, "lseek(%s, %ld, %s) read correct data", 79 TFILE, tc->off, tc->wname); 80 } 81 } 82 83 static void setup(void) 84 { 85 fd = SAFE_OPEN(TFILE, O_RDWR | O_CREAT, 0644); 86 87 SAFE_WRITE(1, fd, WRITE_STR, sizeof(WRITE_STR) - 1); 88 } 89 90 static void cleanup(void) 91 { 92 if (fd > 0) 93 SAFE_CLOSE(fd); 94 } 95 96 static struct tst_test test = { 97 .setup = setup, 98 .cleanup = cleanup, 99 .tcnt = ARRAY_SIZE(tcases), 100 .test = verify_lseek, 101 .needs_tmpdir = 1, 102 }; 103