1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
4f08c3bdfSopenharmony_ci * 06/2017 modified by Xiao Yang <yangx.jy@cn.fujitsu.com>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci/*
8f08c3bdfSopenharmony_ci * DESCRIPTION
9f08c3bdfSopenharmony_ci * 1) lseek(2) fails and sets errno to EBADF when fd is invalid.
10f08c3bdfSopenharmony_ci * 2) lseek(2) fails ans sets errno to EINVAL when whence is invalid.
11f08c3bdfSopenharmony_ci * 3) lseek(2) fails and sets errno to ESPIPE when fd is associated
12f08c3bdfSopenharmony_ci *    with a pipe or FIFO.
13f08c3bdfSopenharmony_ci */
14f08c3bdfSopenharmony_ci
15f08c3bdfSopenharmony_ci#include <errno.h>
16f08c3bdfSopenharmony_ci#include <sys/types.h>
17f08c3bdfSopenharmony_ci#include <unistd.h>
18f08c3bdfSopenharmony_ci#include <stdio.h>
19f08c3bdfSopenharmony_ci#include <sys/stat.h>
20f08c3bdfSopenharmony_ci#include "tst_test.h"
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_ci#define TFILE "tfile"
23f08c3bdfSopenharmony_ci#define TFIFO1 "tfifo1"
24f08c3bdfSopenharmony_ci#define TFIFO2 "tfifo2"
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_cistatic int bad_fd = -1;
27f08c3bdfSopenharmony_cistatic int fd, pfd1, pfd2;
28f08c3bdfSopenharmony_cistatic int pfds[2];
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_cistatic struct tcase {
31f08c3bdfSopenharmony_ci	int *fd;
32f08c3bdfSopenharmony_ci	int whence;
33f08c3bdfSopenharmony_ci	int exp_err;
34f08c3bdfSopenharmony_ci} tcases[] = {
35f08c3bdfSopenharmony_ci	{&bad_fd, SEEK_SET, EBADF},
36f08c3bdfSopenharmony_ci	{&bad_fd, SEEK_CUR, EBADF},
37f08c3bdfSopenharmony_ci	{&bad_fd, SEEK_END, EBADF},
38f08c3bdfSopenharmony_ci	{&fd, 5, EINVAL},
39f08c3bdfSopenharmony_ci	{&fd, -1, EINVAL},
40f08c3bdfSopenharmony_ci	{&fd, 7, EINVAL},
41f08c3bdfSopenharmony_ci	{&pfd1, SEEK_SET, ESPIPE},
42f08c3bdfSopenharmony_ci	{&pfd1, SEEK_CUR, ESPIPE},
43f08c3bdfSopenharmony_ci	{&pfd1, SEEK_END, ESPIPE},
44f08c3bdfSopenharmony_ci	{&pfds[0], SEEK_SET, ESPIPE},
45f08c3bdfSopenharmony_ci	{&pfds[0], SEEK_CUR, ESPIPE},
46f08c3bdfSopenharmony_ci	{&pfds[0], SEEK_END, ESPIPE},
47f08c3bdfSopenharmony_ci	{&pfd2, SEEK_SET, ESPIPE},
48f08c3bdfSopenharmony_ci	{&pfd2, SEEK_CUR, ESPIPE},
49f08c3bdfSopenharmony_ci	{&pfd2, SEEK_END, ESPIPE},
50f08c3bdfSopenharmony_ci};
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_cistatic void verify_lseek(unsigned int n)
53f08c3bdfSopenharmony_ci{
54f08c3bdfSopenharmony_ci	struct tcase *tc = &tcases[n];
55f08c3bdfSopenharmony_ci
56f08c3bdfSopenharmony_ci	TEST(lseek(*tc->fd, (off_t) 1, tc->whence));
57f08c3bdfSopenharmony_ci	if (TST_RET != (off_t) -1) {
58f08c3bdfSopenharmony_ci		tst_res(TFAIL, "lseek(%d, 1, %d) succeeded unexpectedly",
59f08c3bdfSopenharmony_ci			*tc->fd, tc->whence);
60f08c3bdfSopenharmony_ci			return;
61f08c3bdfSopenharmony_ci	}
62f08c3bdfSopenharmony_ci
63f08c3bdfSopenharmony_ci	if (TST_ERR == tc->exp_err) {
64f08c3bdfSopenharmony_ci		tst_res(TPASS | TTERRNO, "lseek(%d, 1, %d) failed as expected",
65f08c3bdfSopenharmony_ci			*tc->fd, tc->whence);
66f08c3bdfSopenharmony_ci	} else {
67f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO, "lseek(%d, 1, %d) failed "
68f08c3bdfSopenharmony_ci			"unexpectedly, expected %s", *tc->fd, tc->whence,
69f08c3bdfSopenharmony_ci			tst_strerrno(tc->exp_err));
70f08c3bdfSopenharmony_ci	}
71f08c3bdfSopenharmony_ci}
72f08c3bdfSopenharmony_ci
73f08c3bdfSopenharmony_cistatic void setup(void)
74f08c3bdfSopenharmony_ci{
75f08c3bdfSopenharmony_ci	fd = SAFE_OPEN(TFILE, O_RDWR | O_CREAT, 0777);
76f08c3bdfSopenharmony_ci	SAFE_MKFIFO(TFIFO1, 0777);
77f08c3bdfSopenharmony_ci	pfd1 = SAFE_OPEN(TFIFO1, O_RDWR, 0777);
78f08c3bdfSopenharmony_ci	SAFE_PIPE(pfds);
79f08c3bdfSopenharmony_ci	SAFE_MKNOD(TFIFO2, S_IFIFO | 0777, 0);
80f08c3bdfSopenharmony_ci	pfd2 = SAFE_OPEN(TFIFO2, O_RDWR, 0777);
81f08c3bdfSopenharmony_ci}
82f08c3bdfSopenharmony_ci
83f08c3bdfSopenharmony_cistatic void cleanup(void)
84f08c3bdfSopenharmony_ci{
85f08c3bdfSopenharmony_ci	if (fd > 0)
86f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd);
87f08c3bdfSopenharmony_ci
88f08c3bdfSopenharmony_ci	if (pfd1 > 0)
89f08c3bdfSopenharmony_ci		SAFE_CLOSE(pfd1);
90f08c3bdfSopenharmony_ci
91f08c3bdfSopenharmony_ci	if (pfds[0] > 0)
92f08c3bdfSopenharmony_ci		SAFE_CLOSE(pfds[0]);
93f08c3bdfSopenharmony_ci
94f08c3bdfSopenharmony_ci	if (pfds[1] > 0)
95f08c3bdfSopenharmony_ci		SAFE_CLOSE(pfds[1]);
96f08c3bdfSopenharmony_ci
97f08c3bdfSopenharmony_ci	if (pfd2 > 0)
98f08c3bdfSopenharmony_ci		SAFE_CLOSE(pfd2);
99f08c3bdfSopenharmony_ci}
100f08c3bdfSopenharmony_ci
101f08c3bdfSopenharmony_cistatic struct tst_test test = {
102f08c3bdfSopenharmony_ci	.setup = setup,
103f08c3bdfSopenharmony_ci	.cleanup = cleanup,
104f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(tcases),
105f08c3bdfSopenharmony_ci	.test = verify_lseek,
106f08c3bdfSopenharmony_ci	.needs_tmpdir = 1,
107f08c3bdfSopenharmony_ci};
108