/*- * Copyright (c) 2024 Kyle Evans <kevans@FreeBSD.org> * * SPDX-License-Identifier: BSD-2-Clause */ #include <sys/types.h> #include <sys/ioctl.h> #include <termios.h> #include <atf-c.h> #include <libutil.h> /* Just a little more concise. */ #define newpty(masterp, slavep) openpty((masterp), (slavep), NULL, NULL, NULL) ATF_TC_WITHOUT_HEAD(fionread); ATF_TC_BODY(fionread, tc) { char rbuf[32]; char buf[] = "Hello"; int master, slave; int bytes; ATF_REQUIRE_EQ(0, newpty(&master, &slave)); /* Should be empty to begin with. */ ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes)); ATF_REQUIRE_EQ(0, bytes); ATF_REQUIRE_EQ(sizeof(buf) - 1, write(slave, buf, sizeof(buf) - 1)); ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes)); ATF_REQUIRE_EQ(sizeof(buf) - 1, bytes); /* Drain what we have available, should result in 0 bytes again. */ ATF_REQUIRE_EQ(sizeof(buf) - 1, read(master, rbuf, sizeof(rbuf))); ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes)); ATF_REQUIRE_EQ(0, bytes); /* * Write once more, then close the slave side with data still in the * buffer. */ ATF_REQUIRE_EQ(sizeof(buf) - 1, write(slave, buf, sizeof(buf) - 1)); ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes)); ATF_REQUIRE_EQ(sizeof(buf) - 1, bytes); ATF_REQUIRE_EQ(0, close(slave)); /* * The tty's output queue is discarded upon close, so we shouldn't have * anything else to read(). */ ATF_REQUIRE_EQ(0, ioctl(master, FIONREAD, &bytes)); ATF_REQUIRE_EQ(0, bytes); ATF_REQUIRE_EQ(0, read(master, rbuf, sizeof(rbuf))); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, fionread); return (atf_no_error()); }