1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2021 FUJITSU LIMITED. All rights reserved. 4 * Author: Dai Shili <daisl.fnst@fujitsu.com> 5 */ 6 7/*\ 8 * [Description] 9 * 10 * Test the write() system call with O_APPEND. 11 * 12 * The full description of O_APPEND is in open(2) man-pages: 13 * The file is opened in append mode. Before each write(2), the 14 * file offset is positioned at the end of the file, as if with lseek(2). 15 * The modification of the file offset and the write operation are 16 * performed as a single atomic step. 17 * 18 * Writing 2k data to the file, close it and reopen it with O_APPEND. 19 * Verify that the file size is 3k and offset is moved to the end of the file. 20 */ 21 22#include <stdlib.h> 23#include <inttypes.h> 24#include "tst_test.h" 25#include "tst_safe_prw.h" 26 27#define K1 1024 28#define K2 (K1 * 2) 29#define K3 (K1 * 3) 30#define DATA_FILE "write06_file" 31 32static int fd = -1; 33static char *write_buf[2]; 34 35static void verify_write(void) 36{ 37 off_t off; 38 struct stat statbuf; 39 40 fd = SAFE_OPEN(DATA_FILE, O_RDWR | O_CREAT | O_TRUNC, 0666); 41 SAFE_WRITE(SAFE_WRITE_ALL, fd, write_buf[0], K2); 42 SAFE_CLOSE(fd); 43 44 fd = SAFE_OPEN(DATA_FILE, O_RDWR | O_APPEND); 45 SAFE_FSTAT(fd, &statbuf); 46 if (statbuf.st_size != K2) 47 tst_res(TFAIL, "file size is %ld != K2", statbuf.st_size); 48 49 off = SAFE_LSEEK(fd, K1, SEEK_SET); 50 if (off != K1) 51 tst_brk(TBROK, "Failed to seek to K1"); 52 53 SAFE_WRITE(SAFE_WRITE_ALL, fd, write_buf[1], K1); 54 55 off = SAFE_LSEEK(fd, 0, SEEK_CUR); 56 if (off != K3) 57 tst_res(TFAIL, "Wrong offset after write %zu expected %u", off, K3); 58 else 59 tst_res(TPASS, "Offset is correct after write %zu", off); 60 61 SAFE_FSTAT(fd, &statbuf); 62 if (statbuf.st_size != K3) 63 tst_res(TFAIL, "Wrong file size after append %zu expected %u", statbuf.st_size, K3); 64 else 65 tst_res(TPASS, "Correct file size after append %u", K3); 66 67 SAFE_CLOSE(fd); 68} 69 70static void setup(void) 71{ 72 memset(write_buf[0], 0, K2); 73 memset(write_buf[1], 1, K1); 74} 75 76static void cleanup(void) 77{ 78 if (fd != -1) 79 SAFE_CLOSE(fd); 80 81 SAFE_UNLINK(DATA_FILE); 82} 83 84static struct tst_test test = { 85 .needs_tmpdir = 1, 86 .setup = setup, 87 .cleanup = cleanup, 88 .test_all = verify_write, 89 .bufs = (struct tst_buffers[]) { 90 {&write_buf[0], .size = K2}, 91 {&write_buf[1], .size = K1}, 92 {} 93 } 94}; 95