xref: /freebsd/tests/sys/kern/tty_pts.c (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
1 /*-
2  * Copyright (c) 2024 Kyle Evans <kevans@FreeBSD.org>
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include <sys/types.h>
8 #include <sys/ioctl.h>
9 
10 #include <termios.h>
11 
12 #include <atf-c.h>
13 #include <libutil.h>
14 
15 /* Just a little more concise. */
16 #define	newpty(masterp, slavep)	openpty((masterp), (slavep), NULL, NULL, NULL)
17 
18 ATF_TC_WITHOUT_HEAD(fionread);
19 ATF_TC_BODY(fionread, tc)
20 {
21 	char rbuf[32];
22 	char buf[] = "Hello";
23 	int master, slave;
24 	int bytes;
25 
26 	ATF_REQUIRE_EQ(0, newpty(&master, &slave));
27 
28 	/* Should be empty to begin with. */
29 	ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes));
30 	ATF_REQUIRE_EQ(0, bytes);
31 
32 	ATF_REQUIRE_EQ(sizeof(buf) - 1, write(slave, buf, sizeof(buf) - 1));
33 	ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes));
34 	ATF_REQUIRE_EQ(sizeof(buf) - 1, bytes);
35 
36 	/* Drain what we have available, should result in 0 bytes again. */
37 	ATF_REQUIRE_EQ(sizeof(buf) - 1, read(master, rbuf, sizeof(rbuf)));
38 	ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes));
39 	ATF_REQUIRE_EQ(0, bytes);
40 
41 	/*
42 	 * Write once more, then close the slave side with data still in the
43 	 * buffer.
44 	 */
45 	ATF_REQUIRE_EQ(sizeof(buf) - 1, write(slave, buf, sizeof(buf) - 1));
46 	ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes));
47 	ATF_REQUIRE_EQ(sizeof(buf) - 1, bytes);
48 
49 	ATF_REQUIRE_EQ(0, close(slave));
50 
51 	/*
52 	 * The tty's output queue is discarded upon close, so we shouldn't have
53 	 * anything else to read().
54 	 */
55 	ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes));
56 	ATF_REQUIRE_EQ(0, bytes);
57 	ATF_REQUIRE_EQ(0, read(master, rbuf, sizeof(rbuf)));
58 }
59 
60 ATF_TP_ADD_TCS(tp)
61 {
62 	ATF_TP_ADD_TC(tp, fionread);
63 	return (atf_no_error());
64 }
65