File: ioctl_nsfs-ns_mnt_get.c

package info (click to toggle)
strace 6.13%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 71,488 kB
  • sloc: ansic: 176,497; sh: 9,675; makefile: 4,133; cpp: 885; awk: 353; perl: 267; exp: 62; sed: 9
file content (80 lines) | stat: -rw-r--r-- 2,090 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
 * Check decoding of NS_MNT_GET_{INFO,NEXT,PREV} commands of ioctl syscall.
 *
 * Copyright (c) 2017-2024 The strace developers.
 * All rights reserved.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "tests.h"

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include <linux/nsfs.h>

int
main(void)
{
	static const char mnt_path[] = "/proc/self/ns/mnt";
	static const struct strval32 ops[] = {
		{ ARG_STR(NS_MNT_GET_INFO) },
		{ ARG_STR(NS_MNT_GET_NEXT) },
		{ ARG_STR(NS_MNT_GET_PREV) },
		{ ARG_STR(_IOC(_IOC_READ, 0xb7, 0xff, 0x10)) },

	};
	TAIL_ALLOC_OBJECT_CONST_PTR(struct mnt_ns_info, info);
	int fd = open(mnt_path, O_RDONLY);
	if (fd < 0)
		perror_msg_and_skip("open: %s", mnt_path);

	for (size_t i = 0; i < ARRAY_SIZE(ops); ++i) {
		int rc = ioctl(-1, ops[i].val, info);
		printf("ioctl(-1, %s, %p) = %s\n",
		       ops[i].str, info, sprintrc(rc));

		rc = ioctl(fd, ops[i].val, info);
		printf("ioctl(%d, %s, ", fd, ops[i].str);
		if (rc < 0) {
			printf("%p) = %s\n",
			       info, sprintrc(rc));
		} else {
			printf("{size=%u, nr_mounts=%u, mnt_ns_id=%#llx})"
			       " = %d\n",
			       info->size, info->nr_mounts,
			       (unsigned long long) info->mnt_ns_id, rc);
		}

		int code = _IOC(_IOC_READ, NSIO, _IOC_NR(ops[i].val),
				MNT_NS_INFO_SIZE_VER0 - 1);
		rc = ioctl(fd, code, info);
		printf("ioctl(%d, _IOC(_IOC_READ, %#x, %#x, %#x), %p) = %s\n",
		       fd, NSIO, _IOC_NR(code), _IOC_SIZE(code),
		       info, sprintrc(rc));

		code = _IOC(_IOC_READ, NSIO, _IOC_NR(ops[i].val),
			    sizeof(*info) + 1);
		rc = ioctl(fd, code, info);
		printf("ioctl(%d, _IOC(_IOC_READ, %#x, %#x, %#x), ",
		       fd, NSIO, _IOC_NR(code), _IOC_SIZE(code));
		if (rc < 0) {
			printf("%p) = %s\n",
			       info, sprintrc(rc));
		} else {
			printf("{size=%u, nr_mounts=%u, mnt_ns_id=%#llx})"
			       " = %d\n",
			       info->size, info->nr_mounts,
			       (unsigned long long) info->mnt_ns_id, rc);
		}
	}

	close(fd);

	puts("+++ exited with 0 +++");
	return 0;
}