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