1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines  Corp., 2001
4f08c3bdfSopenharmony_ci * Copyright (c) Red Hat Inc., 2007
5f08c3bdfSopenharmony_ci * 11/2007 Copyed from sendfile02.c by Masatake YAMATO
6f08c3bdfSopenharmony_ci * Copyright (c) 2021 Xie Ziyao <xieziyao@huawei.com>
7f08c3bdfSopenharmony_ci */
8f08c3bdfSopenharmony_ci
9f08c3bdfSopenharmony_ci/*\
10f08c3bdfSopenharmony_ci * [Description]
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * Test that sendfile() system call updates file position of in_fd correctly
13f08c3bdfSopenharmony_ci * when passing NULL as offset.
14f08c3bdfSopenharmony_ci */
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci#include <stdio.h>
17f08c3bdfSopenharmony_ci#include <inttypes.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_cistatic struct stat sb;
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_cistatic void setup(void)
28f08c3bdfSopenharmony_ci{
29f08c3bdfSopenharmony_ci	int fd;
30f08c3bdfSopenharmony_ci	char buf[27];
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci	fd = SAFE_CREAT(IN_FILE, 00700);
33f08c3bdfSopenharmony_ci	sprintf(buf, "abcdefghijklmnopqrstuvwxyz");
34f08c3bdfSopenharmony_ci	SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, strlen(buf));
35f08c3bdfSopenharmony_ci	SAFE_FSTAT(fd, &sb);
36f08c3bdfSopenharmony_ci	SAFE_CLOSE(fd);
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_ci	fd = SAFE_CREAT(OUT_FILE, 00700);
39f08c3bdfSopenharmony_ci	SAFE_CLOSE(fd);
40f08c3bdfSopenharmony_ci}
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_cistatic void run(void)
43f08c3bdfSopenharmony_ci{
44f08c3bdfSopenharmony_ci	off_t after_pos;
45f08c3bdfSopenharmony_ci	int in_fd = SAFE_OPEN(IN_FILE, O_RDONLY);
46f08c3bdfSopenharmony_ci	int out_fd = SAFE_OPEN(OUT_FILE, O_WRONLY);
47f08c3bdfSopenharmony_ci
48f08c3bdfSopenharmony_ci	TEST(sendfile(out_fd, in_fd, NULL, sb.st_size));
49f08c3bdfSopenharmony_ci	after_pos = SAFE_LSEEK(in_fd, 0, SEEK_CUR);
50f08c3bdfSopenharmony_ci
51f08c3bdfSopenharmony_ci	if (sb.st_size != TST_RET)
52f08c3bdfSopenharmony_ci		tst_res(TFAIL, "sendfile() failed to return expected value, expected: %"
53f08c3bdfSopenharmony_ci			PRId64 ", got: %ld",
54f08c3bdfSopenharmony_ci			sb.st_size, TST_RET);
55f08c3bdfSopenharmony_ci	else if (after_pos != sb.st_size)
56f08c3bdfSopenharmony_ci		tst_res(TFAIL, "sendfile() updated the file position of in_fd unexpectedly,"
57f08c3bdfSopenharmony_ci			" expected file position: %" PRId64
58f08c3bdfSopenharmony_ci			" actual file position %" PRId64,
59f08c3bdfSopenharmony_ci			(int64_t)(sb.st_size), (int64_t)(after_pos));
60f08c3bdfSopenharmony_ci	else
61f08c3bdfSopenharmony_ci		tst_res(TPASS, "sendfile() with offset=NULL");
62f08c3bdfSopenharmony_ci
63f08c3bdfSopenharmony_ci	SAFE_CLOSE(in_fd);
64f08c3bdfSopenharmony_ci	SAFE_CLOSE(out_fd);
65f08c3bdfSopenharmony_ci}
66f08c3bdfSopenharmony_ci
67f08c3bdfSopenharmony_cistatic struct tst_test test = {
68f08c3bdfSopenharmony_ci	.needs_tmpdir = 1,
69f08c3bdfSopenharmony_ci	.setup = setup,
70f08c3bdfSopenharmony_ci	.test_all = run,
71f08c3bdfSopenharmony_ci};
72