JOBCONTROL(2) System Calls JOBCONTROL(2)
settpgrp, tcnewpgrp, tctpgrp - interface for the new job control model
int tcnewpgrp(int fdtty);
int settpgrp(int fdtty);
int tctpgrp(int fdtty, int pid);
The job control interface is used to control what processes are 'in the
foreground' on a particular terminal. Every tty has a process group.
Each process is a member of a process group. A process is a foreground
process on a tty if and only if that process and the terminal belong to
the same process group. Certain characters (such as ^C) typed on a tty
with a non-zero process group produce signals sent to every process
which is a member of the group.
A process is suspended (stopped) if it performs a sufficiently invasive
operation on a tty with a different process group. This includes these
job control calls, reads from a terminal, and writes to a terminal if
it is configured to do so with ioctl(2). When a tty file is first
opened, it is assigned process group zero (init(8) has process group
zero). As init launches login processes on various ttys, it assigns
process groups to those ttys and processes.
tcnewpgrp allocates a new process group and assigns it to the terminal
referred to by fdtty. If the calling process is not in the foreground,
it is sent SIGTTOU.
settpgrp sets the current process to have the process group as fdtty.
tctpgrp sets the tty referred to by fdtty to the same process group as
the process pid, where pid is the current process or a descendant of
These calls will return zero on success, otherwise they'll return -1
and set errno accordingly.
EBADF fdtty is not a valid file descriptor.
ENOTTY fdtty does not refer to a terminal file.
ESRCH pid is not a valid process identifier.
The following are some example uses of the job control interface.
Forking a pipeline in a job-control shell: The shell starts
with tcnewpgrp so that the tty is in the new process group
before there are even any children. It then forks each process
in the pipeline. Each process does settpgrp, thus joining the
new process group.
Handling a stopped child process: When the shell sees that a
pipeline has stopped or exited, it does tctpgrp to set the tty
to its own process group. To resume the pipeline it does tctp-
grp where pid is one of the child processes, then sends SIGCONT.
Starting a process under a new tty: When, for instance, telnetd
(8) wants to grap a pseudo-tty, it opens the pty and forks a
child process. The child does tcnewpgrp to give the tty a real
process group, then settpgrp to place itself into the foregroup.
Security under this scheme is trivial. there is no way a process can
join a process group except by settpgrp, and that requires a descriptor
open to a tty with that pgrp. To make a tty have that requires either
tcnewpgrp (in which case nobody else is using the pgrp), or tctpgrp
(which reduces to the first problem of having a process in the process
Note that 'using' must be defined as use both by ttys and by processes;
the kernel keeps a table of pgrps, each with a total tty and process
reference count. When the reference count reaches zero, the pgrp is
ioctl(2), kill(2), signal(2), tty(4), GNO Shell Reference Manual.
This job control interface was designed by Dan Bernstein <brnstnd@kram-
den.acf.nyu.edu>. He was inspired by Chris Torek, and dedicated the
system to Mark Teitelbaum. The text of this manpage is derived from
his original specifications.
The GNO implementation was written strictly from specs.
GNO 19 January 1997 JOBCONTROL(2)
Man(1) output converted with