How can I detect when someone opens the slave side of a pty (pseudo-terminal) in Linux?
The reason you can't find this is because there's no documented interface specifically to allow it. However, there is a trick that allows you to do it. After opening the pseudo-terminal master (assumed here to be file descriptor ptm
), you open and immediately close the slave side:
close(open(ptsname(ptm), O_RDWR | O_NOCTTY));
This sets the HUP flag on the tty master. You now poll the HUP flag regularly with poll()
(say, whenever data comes in from your data source):
struct pollfd pfd = { .fd = ptm, .events = POLLHUP };
poll(&pfd, 1, 10 /* or other small timeout */);
if (!(pfd.revents & POLLHUP))
{
/* There is now a reader on the slave side */
}
If the reader ever goes away, POLLHUP
will be set again.
In your case, you probably don't even need to remember from one loop to the next whether a given pty has a reader - just block on read()
on your data source, then when data is available, simultaneously poll()
all of your master ttys and send the data to any of them that do not have POLLHUP
set.
How can the master pty detect if a slave tty has exited?
I've found the answer to this question by examining the telnetd source code found in the GNU inetutils package. In telnetd, they use a SIGCHLD handler like this:
int status;
pid_t pid = waitpid((pid_t)-1, &status, WNOHANG);
syslog (LOG_INFO, "child process %ld exited: %d",
(long) pid, WEXITSTATUS(status));
// do cleanup code
PTY/TTY - What Can't You Do With Only Slave FD
Thanks to StackOverflow's related-questions suggestions and other online searching since asking this, I've found a (partial?) answer:
- Enabling or disabling packet mode on a PTY in Linux can only be done if you have the master FD [See TIOCPKT at this manpage]
- Getting the Session ID associated with a TTY in Linux can only be done if you have the master FD (unclear if this is expected/intended behavior) [See TIOCGSID at this manpage]
- Re-sizing the TTY is only portable from the master FD in practice (a terminal emulator might resize the TTY when it's resized, but an application with just the slave FD has no real certainty that the master size resizes accordingly, or that the terminal driver will even accept a resize from the slave end). [Source]
- There is a trick for telling if the slave end of a TTY is opened, that you can't do if you don't have the master FD. [Source]
I'll try to keep coming back to edit this as I learn more.
Related Topics
Dummy Questions About Setting Up Git on Amazon Cloud Ec2
Hook Functions for Linux Filesystem
Using Grep to Search for a String That Has a Dot in It
Control Mouse by Writing to /Dev/Input/Mice
Should Linux Cron Jobs Be Specified with an "&" to Indicate to Run in Background
How to Untar a Tar.Bz File in Unix
What's the Difference Between Tempfile and Mktemp
Using Assertion in the Linux Kernel
Pipe Output to Use as the Search Specification for Grep on Linux
How to Get the First Column of Comm Output
Cmake Doesn't Know Where Is Qt4 Qmake
How Much Memory Is Consumed by the Linux Kernel Per Tcp/Ip Network Connection
Tcp_Tw_Reuse VS Tcp_Tw_Recycle:Which to Use (Or Both)
How Does a Linux Socket Buffer Overflow
What Does "Bash:No Job Control in This Shell" Mean
Linux Perf Reporting Cache Misses for Unexpected Instruction