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 18ATF_TC_WITHOUT_HEAD(fionread); 19ATF_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 60ATF_TP_ADD_TCS(tp) 61{ 62 ATF_TP_ADD_TC(tp, fionread); 63 return (atf_no_error()); 64} 65