1 /* 2 * Copyright (c) 2014 Fujitsu Ltd. 3 * Author: Xiaoguang Wang <wangxg.fnst (at) cn.fujitsu.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 * You should have received a copy of the GNU General Public License along 14 * with this program; if not, write the Free Software Foundation, Inc., 15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 */ 17 18 /* 19 * Description: 20 * Verify that, 21 * 1. llseek() succeeds to set the file pointer position to the current 22 * specified location, when 'whence' value is set to SEEK_CUR and the data 23 * read from the specified location should match the expected data. 24 * 2. llseek() succeeds to set the file pointer position to the end of 25 * the file when 'whence' value set to SEEK_END and any attempts to read 26 * from that position should return 0. 27 * 28 */ 29 30 #define _GNU_SOURCE 31 32 #include <unistd.h> 33 #include <errno.h> 34 #include <unistd.h> 35 #include <fcntl.h> 36 #include <utime.h> 37 #include <string.h> 38 #include <signal.h> 39 #include <sys/resource.h> 40 #include <sys/stat.h> 41 #include <sys/types.h> 42 #include <inttypes.h> 43 44 #include "test.h" 45 #include "safe_macros.h" 46 47 #define TEST_FILE "testfile" 48 49 static void setup(void); 50 static void cleanup(void); 51 52 static void testfunc_seekcur(void); 53 static void testfunc_seekend(void); 54 55 static void (*testfunc[])(void) = { testfunc_seekcur, testfunc_seekend }; 56 57 char *TCID = "llseek03"; 58 int TST_TOTAL = 2; 59 60 static size_t file_size; 61 62 int main(int ac, char **av) 63 { 64 int i, lc; 65 66 tst_parse_opts(ac, av, NULL, NULL); 67 68 setup(); 69 70 for (lc = 0; TEST_LOOPING(lc); lc++) { 71 tst_count = 0; 72 73 for (i = 0; i < TST_TOTAL; i++) 74 (*testfunc[i])(); 75 } 76 77 cleanup(); 78 tst_exit(); 79 } 80 81 static void setup(void) 82 { 83 int fd; 84 struct stat stat_buf; 85 86 tst_sig(NOFORK, DEF_HANDLER, cleanup); 87 88 tst_tmpdir(); 89 90 TEST_PAUSE; 91 92 fd = SAFE_CREAT(cleanup, TEST_FILE, 0644); 93 94 #define STR "abcdefgh" 95 SAFE_WRITE(cleanup, 1, fd, STR, sizeof(STR) - 1); 96 97 SAFE_FSTAT(cleanup, fd, &stat_buf); 98 99 SAFE_CLOSE(cleanup, fd); 100 101 file_size = stat_buf.st_size; 102 } 103 104 static void testfunc_seekcur(void) 105 { 106 int fd; 107 static char read_buf[BUFSIZ]; 108 109 /* reopen TEST_FILE and file offset will be 0 */ 110 fd = SAFE_OPEN(cleanup, TEST_FILE, O_RDONLY); 111 112 /* after read, file offset will be 4 */ 113 SAFE_READ(cleanup, 1, fd, read_buf, 4); 114 115 TEST(lseek64(fd, (loff_t) 1, SEEK_CUR)); 116 117 if (TEST_RETURN == (loff_t) -1) { 118 tst_resm(TFAIL | TTERRNO, "llseek failed on %s ", TEST_FILE); 119 goto cleanup_seekcur; 120 } 121 122 if (TEST_RETURN != 5) { 123 tst_resm(TFAIL, "llseek return a incorrect file offset"); 124 goto cleanup_seekcur; 125 } 126 127 memset(read_buf, 0, sizeof(read_buf)); 128 129 /* the expected characters are "fgh" */ 130 SAFE_READ(cleanup, 1, fd, read_buf, 3); 131 132 if (strcmp(read_buf, "fgh")) 133 tst_resm(TFAIL, "Read wrong bytes after llseek"); 134 else 135 tst_resm(TPASS, "test SEEK_SET for llseek success"); 136 137 cleanup_seekcur: 138 SAFE_CLOSE(cleanup, fd); 139 } 140 141 142 static void testfunc_seekend(void) 143 { 144 int fd; 145 ssize_t nread; 146 static char read_buf[BUFSIZ]; 147 148 /* reopen TEST_FILE and file offset will be 0 */ 149 fd = SAFE_OPEN(cleanup, TEST_FILE, O_RDONLY); 150 151 TEST(lseek64(fd, (loff_t) 0, SEEK_END)); 152 153 if (TEST_RETURN == (loff_t) -1) { 154 tst_resm(TFAIL | TTERRNO, "llseek failed on %s ", TEST_FILE); 155 goto cleanup_seekend; 156 } 157 158 if (TEST_RETURN != (long)file_size) { 159 tst_resm(TFAIL, "llseek return a incorrect file offset"); 160 goto cleanup_seekend; 161 } 162 163 memset(read_buf, 0, sizeof(read_buf)); 164 165 nread = SAFE_READ(cleanup, 0, fd, read_buf, file_size); 166 if (nread > 0) 167 tst_resm(TFAIL, "Read bytes after llseek to end of file"); 168 else 169 tst_resm(TPASS, "test SEEK_END for llseek success"); 170 171 cleanup_seekend: 172 SAFE_CLOSE(cleanup, fd); 173 } 174 175 static void cleanup(void) 176 { 177 tst_rmdir(); 178 } 179