Pseudo-Terminals

A pseudo-terminal is a special interprocess communication channel that acts like a terminal. One end of the channel is called the master side or master pseudo-terminal device, the other side is called the slave side. Data written to the master side is received by the slave side as if it was the result of a user typing at an ordinary terminal, and data written to the slave side is sent to the master side as if it was written on an ordinary terminal.

Pseudo terminals are the way programs like xterm and emacs implement their terminal emulation functionality.

Allocating Pseudo-Terminals

This subsection describes functions for allocating a pseudo-terminal, and for making this pseudo-terminal available for actual use. These functions are declared in the header file stdlib.h.

int function>getpt/function> (void) The getpt function returns a new file descriptor for the next available master pseudo-terminal. The normal return value from getpt is a non-negative integer file descriptor. In the case of an error, a value of -1 is returned instead. The following errno conditions are defined for this function:

ENOENT

There are no free master pseudo-terminals available.

This function is a GNU extension.

int function>grantpt/function> (int filedes) The grantpt function changes the ownership and access permission of the slave pseudo-terminal device corresponding to the master pseudo-terminal device associated with the file descriptor filedes. The owner is set from the real user ID of the calling process (the section called “The Persona of a Process”), and the group is set to a special group (typically tty) or from the real group ID of the calling process. The access permission is set such that the file is both readable and writable by the owner and only writable by the group.

On some systems this function is implemented by invoking a special setuid root program (the section called “How an Application Can Change Persona”). As a consequence, installing a signal handler for the SIGCHLD signal (the section called “Job Control Signals”) may interfere with a call to grantpt.

The normal return value from grantpt is 0; a value of -1 is returned in case of failure. The following errno error conditions are defined for this function:

EBADF

The filedes argument is not a valid file descriptor.

EINVAL

The filedes argument is not associated with a master pseudo-terminal device.

EACCES

The slave pseudo-terminal device corresponding to the master associated with filedes could not be accessed.

int function>unlockpt/function> (int filedes) The unlockpt function unlocks the slave pseudo-terminal device corresponding to the master pseudo-terminal device associated with the file descriptor filedes. On many systems, the slave can only be opened after unlocking, so portable applications should always call unlockpt before trying to open the slave.

The normal return value from unlockpt is 0; a value of -1 is returned in case of failure. The following errno error conditions are defined for this function:

EBADF

The filedes argument is not a valid file descriptor.

EINVAL

The filedes argument is not associated with a master pseudo-terminal device.

char * function>ptsname/function> (int filedes) If the file descriptor filedes is associated with a master pseudo-terminal device, the ptsname function returns a pointer to a statically-allocated, null-terminated string containing the file name of the associated slave pseudo-terminal file. This string might be overwritten by subsequent calls to ptsname.

int function>ptsname_r/function> (int filedes, char *buf, size_t len) The ptsname_r function is similar to the ptsname function except that it places its result into the user-specified buffer starting at buf with length len.

This function is a GNU extension.

Portability Note: On System V derived systems, the file returned by the ptsname and ptsname_r functions may be STREAMS-based, and therefore require additional processing after opening before it actually behaves as a pseudo terminal.

Typical usage of these functions is illustrated by the following example:

int
open_pty_pair (int *amaster, int *aslave)
{
  int master, slave;
  char *name;

  master = getpt ();
  if (master  0)
    return 0;

  if (grantpt (master)  0 || unlockpt (master)  0)
    goto close_master;
  name = ptsname (master);
  if (name == NULL)
    goto close_master;

  slave = open (name, O_RDWR);
  if (slave == -1)
    goto close_master;

  if (isastream (slave))
    {
      if (ioctl (slave, I_PUSH, "ptem")  0
          || ioctl (slave, I_PUSH, "ldterm")  0)
        goto close_slave;
    }

  *amaster = master;
  *aslave = slave;
  return 1;

close_slave:
  close (slave);

close_master:
  close (master);
  return 0;
}

Opening a Pseudo-Terminal Pair

These functions, derived from BSD, are available in the separate libutil library, and declared in pty.h.

int function>openpty/function> (int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) This function allocates and opens a pseudo-terminal pair, returning the file descriptor for the master in *amaster, and the file descriptor for the slave in *aslave. If the argument name is not a null pointer, the file name of the slave pseudo-terminal device is stored in *name. If termp is not a null pointer, the terminal attributes of the slave are set to the ones specified in the structure that termp points to (the section called “Terminal Modes”). Likewise, if the winp is not a null pointer, the screen size of the slave is set to the values specified in the structure that winp points to.

The normal return value from openpty is 0; a value of -1 is returned in case of failure. The following errno conditions are defined for this function:

ENOENT

There are no free pseudo-terminal pairs available.

Warning: Using the openpty function with name not set to NULL is very dangerous because it provides no protection against overflowing the string name. You should use the ttyname function on the file descriptor returned in *slave to find out the file name of the slave pseudo-terminal device instead.

int function>forkpty/function> (int *amaster, char *name, struct termios *termp, struct winsize *winp) This function is similar to the openpty function, but in addition, forks a new process (the section called “Creating a Process”) and makes the newly opened slave pseudo-terminal device the controlling terminal (the section called “Controlling Terminal of a Process”) for the child process.

If the operation is successful, there are then both parent and child processes and both see forkpty return, but with different values: it returns a value of 0 in the child process and returns the child's process ID in the parent process.

If the allocation of a pseudo-terminal pair or the process creation failed, forkpty returns a value of -1 in the parent process.

Warning: The forkpty function has the same problems with respect to the name argument as openpty.