Pseudo Terminals Concept Application APIs Overview A pseudo terminal (PTY) is a user level program that appears to be a terminal device to another program A pseudo terminal has two bidirectionally connected ends, the master and the slave slave is connected to the program that thinks its connected to a terminal device master is connected to the program that is providing this pseudo terminal service Typical Pseudo Terminal Arrangement Typical Pseudo Terminal Arrangement Steps Process opens pseudo terminal master and calls fork Child creates new session, opens corresponding pseudo terminal slave, duplicates fd of terminal slave to stdin, stdout, stderr and then calls exec Pseudo terminal slave becomes the controlling terminal for the child It appears to the user process above the slave that it is connected to a terminal device Output from the master appears as input to the slave and vice versa Applications Network login (telnetd, sshd, etc) The script utility X Windows etc Applications – Network Login Applications – Network Login Network login requests come in through the network interface driver inetd. rlogind is started per request rlogind opens a pseudo terminal master and then forks Child duplicates file descriptors 0, 1 and 2 to the pseudo terminal then execs login Parent and child communicate through the pseudo terminal Note that the process connected to the master is also reading/writing another I/O stream at the same time. This implies multiplexed I/O (select or poll) Applications – script utility Applications – script utility The script utility places itself between the terminal and a new copy of the login shell While running, all the output from the terminal line descriptor above the PTY slave is copied into a script file Input that is echoed is also stored Pseudo Terminal Interfaces Historically there were two main pseudo terminal APIs BSD System V (aka UNIX98) LINUX supports both, but since kernel 2.4.4 BSD APIs are deprecated. Use UNIX98 interface instead UNIX98 Pseudo Terminals int posix_openpt(int flags); Opens an unused UNIX98 PTY master flags can the OR zero or more of O_RDWR and O_NOCTTY int grantpt(int fd); Sets permissions of the slave PTY int unlockpt(int fd); Unlocks the slave PTY corresponding to the master PTY designated by fd char *ptsname(int fd); Returns the pathname of the PTY device based on the FD of the master UNIX98 Pseudo Terminals Limits on number of PTY devices Default limit is 256 Can be changed by re-compiling the kernel up to 4096 Two files under /proc/sys/kernel/pty max – the max pairs of PTYs nr – number of PTYs currently in use BSD Pseudo Terminals BSD style PTYs come as pre-created pairs /dev/ptyXY (master) /dev/ttyXY (slave) X is one letter from [p-z,a-e] Y is one letter from [0-9,a-f] Ex: /dev/ptyp1 and /dev/ttyp1 are a PTY pair Process opens a PTY by trying master devices sequentially until it can open one then opening the corresponding slave GLIBC PTY Library Calls glibc provides openpty and forkpty int openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize * winp); Opens a master slave pair and optionally uses termios and winsize to set up the slave tty. pid_t forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp); Combines openpty and fork Returns pid of 0 in child and actual pid in parent like regular fork function