1314817Sngie/*	$NetBSD: t_nullpts.c,v 1.6 2017/01/13 21:30:40 christos Exp $	*/
2272343Sngie
3272343Sngie#include <sys/types.h>
4272343Sngie#include <sys/mount.h>
5272343Sngie#include <sys/ioctl.h>
6272343Sngie
7272343Sngie#include <atf-c.h>
8272343Sngie#include <err.h>
9272343Sngie#include <errno.h>
10272343Sngie#include <fcntl.h>
11272343Sngie#include <stdio.h>
12272343Sngie#include <unistd.h>
13272343Sngie#include <string.h>
14272343Sngie#include <stdlib.h>
15272343Sngie
16272343Sngie#include <rump/rump.h>
17272343Sngie#include <rump/rump_syscalls.h>
18272343Sngie
19272343Sngie#include <fs/ptyfs/ptyfs.h>
20272343Sngie#include <miscfs/nullfs/null.h>
21272343Sngie
22314817Sngie#include "h_macros.h"
23272343Sngie
24272343Sngiestatic void
25272343Sngiemountptyfs(const char *mp, int flags)
26272343Sngie{
27272343Sngie	struct ptyfs_args args;
28272343Sngie
29272343Sngie	if (rump_sys_mkdir(mp, 0777) == -1) {
30272343Sngie		if (errno != EEXIST)
31272343Sngie			atf_tc_fail_errno("null create %s", mp);
32272343Sngie	}
33272343Sngie	memset(&args, 0, sizeof(args));
34272343Sngie	args.version = PTYFS_ARGSVERSION;
35272343Sngie	args.mode = 0777;
36272343Sngie	if (rump_sys_mount(MOUNT_PTYFS, mp, flags, &args, sizeof(args)) == -1)
37272343Sngie		atf_tc_fail_errno("could not mount ptyfs");
38272343Sngie}
39272343Sngie
40272343Sngiestatic void
41272343Sngiemountnull(const char *what, const char *mp, int flags)
42272343Sngie{
43272343Sngie	struct null_args nargs;
44272343Sngie
45272343Sngie	if (rump_sys_mkdir(what, 0777) == -1) {
46272343Sngie		if (errno != EEXIST)
47272343Sngie			atf_tc_fail_errno("null create %s", what);
48272343Sngie	}
49272343Sngie	if (rump_sys_mkdir(mp, 0777) == -1) {
50272343Sngie		if (errno != EEXIST)
51272343Sngie			atf_tc_fail_errno("null create %s", mp);
52272343Sngie	}
53272343Sngie	memset(&nargs, 0, sizeof(nargs));
54272343Sngie	nargs.nulla_target = __UNCONST(what);
55272343Sngie	if (rump_sys_mount(MOUNT_NULL, mp, flags, &nargs, sizeof(nargs)) == -1)
56272343Sngie		atf_tc_fail_errno("could not mount nullfs");
57272343Sngie}
58272343Sngie
59272343SngieATF_TC(nullrevoke);
60272343SngieATF_TC_HEAD(nullrevoke, tc)
61272343Sngie{
62272343Sngie	atf_tc_set_md_var(tc, "descr", "null mount ptyfs and revoke");
63272343Sngie}
64272343Sngie
65272343SngieATF_TC_BODY(nullrevoke, tc)
66272343Sngie{
67272343Sngie	char path[MAXPATHLEN];
68272343Sngie	struct ptmget ptg;
69272343Sngie	int ptm;
70272343Sngie
71272343Sngie	rump_init();
72272343Sngie
73272343Sngie	/*
74272343Sngie	 * mount /dev/pts
75272343Sngie	 */
76272343Sngie	mountptyfs("/dev/pts", 0);
77272343Sngie
78272343Sngie	/*
79272343Sngie	 * null mount /dev/pts to /null/dev/pts
80272343Sngie	 */
81272343Sngie	if (rump_sys_mkdir("/null", 0777) == -1) {
82272343Sngie		if (errno != EEXIST)
83272343Sngie			atf_tc_fail_errno("null create /null");
84272343Sngie	}
85272343Sngie	if (rump_sys_mkdir("/null/dev", 0777) == -1) {
86272343Sngie		if (errno != EEXIST)
87272343Sngie			atf_tc_fail_errno("null create /null/dev");
88272343Sngie	}
89272343Sngie
90272343Sngie	mountnull("/dev/pts", "/null/dev/pts", 0);
91272343Sngie
92272343Sngie	/*
93272343Sngie	 * get slave/master pair.
94272343Sngie	 */
95272343Sngie	ptm = rump_sys_open("/dev/ptm", O_RDWR);
96272343Sngie	if (rump_sys_ioctl(ptm, TIOCPTMGET, &ptg) == -1)
97272343Sngie		atf_tc_fail_errno("get pty");
98272343Sngie
99272343Sngie	/*
100272343Sngie	 * Build nullfs path to slave.
101272343Sngie	 */
102272343Sngie	strcpy(path, "/null");
103272343Sngie	strcat(path, ptg.sn);
104272343Sngie
105272343Sngie	/*
106272343Sngie	 * Open slave tty via nullfs.
107272343Sngie	 */
108272343Sngie	if (rump_sys_open(path, O_RDWR) == -1)
109272343Sngie		atf_tc_fail_errno("slave null open");
110272343Sngie
111272343Sngie	/*
112272343Sngie	 * Close slave opened with /dev/ptm.  Need purely non-null refs to it.
113272343Sngie	 */
114272343Sngie	rump_sys_close(ptg.sfd);
115272343Sngie
116272343Sngie	/* revoke slave tty. */
117272343Sngie	rump_sys_revoke(path);
118272343Sngie
119272343Sngie	/* done */
120272343Sngie}
121272343Sngie
122272343SngieATF_TP_ADD_TCS(tp)
123272343Sngie{
124272343Sngie
125272343Sngie	ATF_TP_ADD_TC(tp, nullrevoke);
126272343Sngie
127272343Sngie	return atf_no_error();
128272343Sngie}
129