1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (C) 2012 Red Hat, Inc. 4f08c3bdfSopenharmony_ci */ 5f08c3bdfSopenharmony_ci 6f08c3bdfSopenharmony_ci/*\ 7f08c3bdfSopenharmony_ci * [Description] 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * Bug in the splice code has caused the file position on the write side 10f08c3bdfSopenharmony_ci * of the sendfile system call to be incorrectly set to the read side file 11f08c3bdfSopenharmony_ci * position. This can result in the data being written to an incorrect offset. 12f08c3bdfSopenharmony_ci * 13f08c3bdfSopenharmony_ci * This is a regression test for kernel commit 2cb4b05e76478. 14f08c3bdfSopenharmony_ci */ 15f08c3bdfSopenharmony_ci 16f08c3bdfSopenharmony_ci#include <stdio.h> 17f08c3bdfSopenharmony_ci#include <string.h> 18f08c3bdfSopenharmony_ci#include <sys/sendfile.h> 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#include "tst_test.h" 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_ci#define IN_FILE "in_file" 23f08c3bdfSopenharmony_ci#define OUT_FILE "out_file" 24f08c3bdfSopenharmony_ci 25f08c3bdfSopenharmony_ci#define TEST_MSG_IN "world" 26f08c3bdfSopenharmony_ci#define TEST_MSG_OUT "hello" 27f08c3bdfSopenharmony_ci#define TEST_MSG_ALL (TEST_MSG_OUT TEST_MSG_IN) 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_cistatic int in_fd; 30f08c3bdfSopenharmony_cistatic int out_fd; 31f08c3bdfSopenharmony_ci 32f08c3bdfSopenharmony_cistatic void run(void) 33f08c3bdfSopenharmony_ci{ 34f08c3bdfSopenharmony_ci TEST(sendfile(out_fd, in_fd, NULL, strlen(TEST_MSG_IN))); 35f08c3bdfSopenharmony_ci if (TST_RET == -1) 36f08c3bdfSopenharmony_ci tst_brk(TBROK | TTERRNO, "sendfile() failed"); 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_ci char buf[BUFSIZ]; 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci SAFE_LSEEK(out_fd, 0, SEEK_SET); 41f08c3bdfSopenharmony_ci SAFE_READ(0, out_fd, buf, BUFSIZ); 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_ci if (!strncmp(buf, TEST_MSG_ALL, strlen(TEST_MSG_ALL))) { 44f08c3bdfSopenharmony_ci tst_res(TPASS, "sendfile() copies data correctly"); 45f08c3bdfSopenharmony_ci return; 46f08c3bdfSopenharmony_ci } 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci tst_res(TFAIL, "sendfile() copies data incorrectly: '%s' expected: '%s%s'", 49f08c3bdfSopenharmony_ci buf, TEST_MSG_OUT, TEST_MSG_IN); 50f08c3bdfSopenharmony_ci} 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_cistatic void setup(void) 53f08c3bdfSopenharmony_ci{ 54f08c3bdfSopenharmony_ci in_fd = SAFE_CREAT(IN_FILE, 0700); 55f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, in_fd, TEST_MSG_IN, strlen(TEST_MSG_IN)); 56f08c3bdfSopenharmony_ci SAFE_CLOSE(in_fd); 57f08c3bdfSopenharmony_ci in_fd = SAFE_OPEN(IN_FILE, O_RDONLY); 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_ci out_fd = SAFE_OPEN(OUT_FILE, O_TRUNC | O_CREAT | O_RDWR, 0777); 60f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, out_fd, TEST_MSG_OUT, strlen(TEST_MSG_OUT)); 61f08c3bdfSopenharmony_ci} 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_cistatic void cleanup(void) 64f08c3bdfSopenharmony_ci{ 65f08c3bdfSopenharmony_ci SAFE_CLOSE(in_fd); 66f08c3bdfSopenharmony_ci SAFE_CLOSE(out_fd); 67f08c3bdfSopenharmony_ci} 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_cistatic struct tst_test test = { 70f08c3bdfSopenharmony_ci .needs_tmpdir = 1, 71f08c3bdfSopenharmony_ci .setup = setup, 72f08c3bdfSopenharmony_ci .cleanup = cleanup, 73f08c3bdfSopenharmony_ci .test_all = run, 74f08c3bdfSopenharmony_ci .tags = (const struct tst_tag[]) { 75f08c3bdfSopenharmony_ci {"linux-git", "2cb4b05e76478"}, 76f08c3bdfSopenharmony_ci {} 77f08c3bdfSopenharmony_ci } 78f08c3bdfSopenharmony_ci}; 79