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