Home | History | Annotate | Download | only in llseek
      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