1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
4f08c3bdfSopenharmony_ci *
5f08c3bdfSopenharmony_ci * Test whether ustat(2) system call returns appropriate error number for
6f08c3bdfSopenharmony_ci * invalid dev_t parameter and for bad address paramater.
7f08c3bdfSopenharmony_ci */
8f08c3bdfSopenharmony_ci
9f08c3bdfSopenharmony_ci#include "config.h"
10f08c3bdfSopenharmony_ci#include "tst_test.h"
11f08c3bdfSopenharmony_ci
12f08c3bdfSopenharmony_ci#if defined(HAVE_SYS_USTAT_H) || defined(HAVE_LINUX_TYPES_H)
13f08c3bdfSopenharmony_ci#include <unistd.h>
14f08c3bdfSopenharmony_ci#include <errno.h>
15f08c3bdfSopenharmony_ci#include <sys/stat.h>
16f08c3bdfSopenharmony_ci#include <sys/types.h>
17f08c3bdfSopenharmony_ci
18f08c3bdfSopenharmony_ci#include "lapi/syscalls.h"
19f08c3bdfSopenharmony_ci#include "lapi/ustat.h"
20f08c3bdfSopenharmony_ci
21f08c3bdfSopenharmony_cistatic dev_t invalid_dev = -1;
22f08c3bdfSopenharmony_cistatic dev_t root_dev;
23f08c3bdfSopenharmony_cistruct ustat ubuf;
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_cistatic struct test_case_t {
26f08c3bdfSopenharmony_ci	char *err_desc;
27f08c3bdfSopenharmony_ci	int exp_errno;
28f08c3bdfSopenharmony_ci	char *exp_errval;
29f08c3bdfSopenharmony_ci	dev_t *dev;
30f08c3bdfSopenharmony_ci	struct ustat *buf;
31f08c3bdfSopenharmony_ci} tc[] = {
32f08c3bdfSopenharmony_ci	{"Invalid parameter", EINVAL, "EINVAL", &invalid_dev, &ubuf},
33f08c3bdfSopenharmony_ci#ifndef UCLINUX
34f08c3bdfSopenharmony_ci	{"Bad address", EFAULT, "EFAULT", &root_dev, (void*)-1}
35f08c3bdfSopenharmony_ci#endif
36f08c3bdfSopenharmony_ci};
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_ciint TST_TOTAL = ARRAY_SIZE(tc);
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_civoid run(unsigned int test)
41f08c3bdfSopenharmony_ci{
42f08c3bdfSopenharmony_ci	TEST(tst_syscall(__NR_ustat, (unsigned int)*tc[test].dev, tc[test].buf));
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci	if ((TST_RET == -1) && (TST_ERR == tc[test].exp_errno))
45f08c3bdfSopenharmony_ci		tst_res(TPASS | TTERRNO, "ustat(2) expected failure");
46f08c3bdfSopenharmony_ci	else
47f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO,
48f08c3bdfSopenharmony_ci			"ustat(2) failed to produce expected error; %d, errno"
49f08c3bdfSopenharmony_ci			": %s", tc[test].exp_errno, tc[test].exp_errval);
50f08c3bdfSopenharmony_ci}
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_cistatic void setup(void)
53f08c3bdfSopenharmony_ci{
54f08c3bdfSopenharmony_ci	struct stat buf;
55f08c3bdfSopenharmony_ci
56f08c3bdfSopenharmony_ci	/* Find a valid device number */
57f08c3bdfSopenharmony_ci	SAFE_STAT("/", &buf);
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_ci	root_dev = buf.st_dev;
60f08c3bdfSopenharmony_ci}
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_cistatic struct tst_test test = {
63f08c3bdfSopenharmony_ci	.test = run,
64f08c3bdfSopenharmony_ci	.setup = setup,
65f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(tc),
66f08c3bdfSopenharmony_ci	.tags = (const struct tst_tag[]) {
67f08c3bdfSopenharmony_ci		{"known-fail", "ustat() is known to fail with EINVAL on Btrfs, see "
68f08c3bdfSopenharmony_ci			"https://lore.kernel.org/linux-btrfs/e7e867b8-b57a-7eb2-2432-1627bd3a88fb@toxicpanda.com/"
69f08c3bdfSopenharmony_ci		},
70f08c3bdfSopenharmony_ci		{}
71f08c3bdfSopenharmony_ci	}
72f08c3bdfSopenharmony_ci};
73f08c3bdfSopenharmony_ci#else
74f08c3bdfSopenharmony_ciTST_TEST_TCONF("testing ustat requires <sys/ustat.h> or <linux/types.h>");
75f08c3bdfSopenharmony_ci#endif
76