• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) Linux Test Project, 2021
4  * Copyright (c) International Business Machines  Corp., 2002
5  * ported from SPIE, section2/filesuite/pread_pwrite.c, by Airong Zhang
6  */
7 
8 /*\
9  * [Description]
10  *
11  * Test the pwrite() system call with O_APPEND.
12  *
13  * Writing 2k data to the file, close it and reopen it with O_APPEND.
14  *
15  * POSIX requires that opening a file with the O_APPEND flag should have no effect on the
16  * location at which pwrite() writes data. However, on Linux, if a file is opened with
17  * O_APPEND, pwrite() appends data to the end of the file, regardless of the value of offset.
18  */
19 
20 #include <stdlib.h>
21 #include <inttypes.h>
22 #include "tst_test.h"
23 #include "tst_safe_prw.h"
24 
25 #define K1              1024
26 #define K2              (K1 * 2)
27 #define K3              (K1 * 3)
28 #define DATA_FILE       "pwrite04_file"
29 
30 static int fd = -1;
31 static char *write_buf[2];
32 
l_seek(int fdesc,off_t offset,int whence,off_t checkoff)33 static void l_seek(int fdesc, off_t offset, int whence, off_t checkoff)
34 {
35 	off_t offloc;
36 
37 	offloc = SAFE_LSEEK(fdesc, offset, whence);
38 	if (offloc != checkoff) {
39 		tst_res(TFAIL, "%" PRId64 " = lseek(%d, %" PRId64 ", %d) != %" PRId64,
40 			(int64_t)offloc, fdesc, (int64_t)offset, whence, (int64_t)checkoff);
41 	}
42 }
43 
verify_pwrite(void)44 static void verify_pwrite(void)
45 {
46 	struct stat statbuf;
47 
48 	fd = SAFE_OPEN(DATA_FILE, O_RDWR | O_CREAT | O_TRUNC, 0666);
49 	SAFE_PWRITE(1, fd, write_buf[0], K2, 0);
50 	SAFE_CLOSE(fd);
51 
52 	fd = SAFE_OPEN(DATA_FILE, O_RDWR | O_APPEND, 0666);
53 	SAFE_FSTAT(fd, &statbuf);
54 	if (statbuf.st_size != K2)
55 		tst_res(TFAIL, "file size is %ld != K2", statbuf.st_size);
56 
57 	/* Appends data to the end of the file regardless of offset. */
58 	l_seek(fd, K1, SEEK_SET, K1);
59 	SAFE_PWRITE(1, fd, write_buf[1], K1, 0);
60 	l_seek(fd, 0, SEEK_CUR, K1);
61 	SAFE_FSTAT(fd, &statbuf);
62 	if (statbuf.st_size != K3)
63 		tst_res(TFAIL, "file size is %ld != K3", statbuf.st_size);
64 
65 	tst_res(TPASS, "O_APPEND test passed.");
66 	SAFE_CLOSE(fd);
67 }
68 
setup(void)69 static void setup(void)
70 {
71 	write_buf[0] = SAFE_MALLOC(K2);
72 	memset(write_buf[0], 0, K2);
73 	write_buf[1] = SAFE_MALLOC(K1);
74 	memset(write_buf[0], 1, K1);
75 }
76 
cleanup(void)77 static void cleanup(void)
78 {
79 	free(write_buf[0]);
80 	free(write_buf[1]);
81 
82 	if (fd > -1)
83 		SAFE_CLOSE(fd);
84 
85 	SAFE_UNLINK(DATA_FILE);
86 }
87 
88 static struct tst_test test = {
89 	.needs_tmpdir = 1,
90 	.setup = setup,
91 	.cleanup = cleanup,
92 	.test_all = verify_pwrite,
93 };
94