?? library_24.html
字號:
<!-- This HTML file has been created by texi2html 1.27
from library.texinfo on 3 March 1994 -->
<TITLE>The GNU C Library - Job Control</TITLE>
<P>Go to the <A HREF="library_23.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_23.html">previous</A>, <A HREF="library_25.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_25.html">next</A> section.<P>
<H1><A NAME="SEC411" HREF="library_toc.html#SEC411" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC411">Job Control</A></H1>
<A NAME="IDX1729"></A>
<A NAME="IDX1730"></A>
<A NAME="IDX1731"></A>
<A NAME="IDX1732"></A>
<P>
<DFN>Job control</DFN> refers to the protocol for allowing a user to move
between multiple <DFN>process groups</DFN> (or <DFN>jobs</DFN>) within a single
<DFN>login session</DFN>. The job control facilities are set up so that
appropriate behavior for most programs happens automatically and they
need not do anything special about job control. So you can probably
ignore the material in this chapter unless you are writing a shell or
login program.
<P>
You need to be familiar with concepts relating to process creation
(see section <A HREF="library_23.html#SEC403" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_23.html#SEC403">Process Creation Concepts</A>) and signal handling (see section <A HREF="library_21.html#SEC330" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC330">Signal Handling</A>) in order to understand this material presented in this
chapter.
<P>
<H2><A NAME="SEC412" HREF="library_toc.html#SEC412" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC412">Concepts of Job Control</A></H2>
<A NAME="IDX1733"></A>
<P>
The fundamental purpose of an interactive shell is to read
commands from the user's terminal and create processes to execute the
programs specified by those commands. It can do this using the
<CODE>fork</CODE> (see section <A HREF="library_23.html#SEC405" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_23.html#SEC405">Creating a Process</A>) and <CODE>exec</CODE>
(see section <A HREF="library_23.html#SEC406" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_23.html#SEC406">Executing a File</A>) functions.
<P>
A single command may run just one process--but often one command uses
several processes. If you use the <SAMP>`|'</SAMP> operator in a shell command,
you explicitly request several programs in their own processes. But
even if you run just one program, it can use multiple processes
internally. For example, a single compilation command such as <SAMP>`cc
-c foo.c'</SAMP> typically uses four processes (though normally only two at any
given time). If you run <CODE>make</CODE>, its job is to run other programs
in separate processes.
<P>
The processes belonging to a single command are called a <DFN>process
group</DFN> or <DFN>job</DFN>. This is so that you can operate on all of them at
once. For example, typing <KBD>C-c</KBD> sends the signal <CODE>SIGINT</CODE> to
terminate all the processes in the foreground process group.
<A NAME="IDX1734"></A>
<P>
A <DFN>session</DFN> is a larger group of processes. Normally all the
proccesses that stem from a single login belong to the same session.
<P>
Every process belongs to a process group. When a process is created, it
becomes a member of the same process group and session as its parent
process. You can put it in another process group using the
<CODE>setpgid</CODE> function, provided the process group belongs to the same
session.
<A NAME="IDX1735"></A>
<P>
The only way to put a process in a different session is to make it the
initial process of a new session, or a <DFN>session leader</DFN>, using the
<CODE>setsid</CODE> function. This also puts the session leader into a new
process group, and you can't move it out of that process group again.
<P>
Usually, new sessions are created by the system login program, and the
session leader is the process running the user's login shell.
<A NAME="IDX1736"></A>
<P>
A shell that supports job control must arrange to control which job can
use the terminal at any time. Otherwise there might be multiple jobs
trying to read from the terminal at once, and confusion about which
process should receive the input typed by the user. To prevent this,
the shell must cooperate with the terminal driver using the protocol
described in this chapter.
<A NAME="IDX1737"></A>
<A NAME="IDX1738"></A>
<P>
The shell can give unlimited access to the controlling terminal to only
one process group at a time. This is called the <DFN>foreground job</DFN> on
that controlling terminal. Other process groups managed by the shell
that are executing without such access to the terminal are called
<DFN>background jobs</DFN>.
<A NAME="IDX1739"></A>
<P>
If a background job needs to read from or write to its controlling
terminal, it is <DFN>stopped</DFN> by the terminal driver. The user can stop
a foreground job by typing the SUSP character (see section <A HREF="library_16.html#SEC281" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_16.html#SEC281">Special Characters</A>) and a program can stop any job by sending it a
<CODE>SIGSTOP</CODE> signal. It's the responsibility of the shell to notice
when jobs stop, to notify the user about them, and to provide mechanisms
for allowing the user to interactively continue stopped jobs and switch
jobs between foreground and background.
<P>
See section <A HREF="library_24.html#SEC415" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_24.html#SEC415">Access to the Controlling Terminal</A>, for more information about I/O to the
controlling terminal,
<P>
<A NAME="IDX1740"></A>
<H2><A NAME="SEC413" HREF="library_toc.html#SEC413" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC413">Job Control is Optional</A></H2>
<P>
Not all operating systems support job control. The GNU system does
support job control, but if you are using the GNU library on some other
system, that system may not support job control itself.
<P>
You can use the <CODE>_POSIX_JOB_CONTROL</CODE> macro to test at compile-time
whether the system supports job control. See section <A HREF="library_27.html#SEC456" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_27.html#SEC456">Overall System Options</A>.
<P>
If job control is not supported, then there can be only one process
group per session, which behaves as if it were always in the foreground.
The functions for creating additional process groups simply fail with
the error code <CODE>ENOSYS</CODE>.
<P>
The macros naming the various job control signals (see section <A HREF="library_21.html#SEC340" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC340">Job Control Signals</A>) are defined even if job control is not supported. However,
the system never generates these signals, and attempts to send a job
control signal or examine or specify their actions report errors or do
nothing.
<P>
<H2><A NAME="SEC414" HREF="library_toc.html#SEC414" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC414">Controlling Terminal of a Process</A></H2>
<P>
One of the attributes of a process is its controlling terminal. Child
processes created with <CODE>fork</CODE> inherit the controlling terminal from
their parent process. In this way, all the processes in a session
inherit the controlling terminal from the session leader. A session
leader that has control of a terminal is called the <DFN>controlling
process</DFN> of that terminal.
<A NAME="IDX1741"></A>
<P>
You generally do not need to worry about the exact mechanism used to
allocate a controlling terminal to a session, since it is done for you
by the system when you log in.
<P>
An individual process disconnects from its controlling terminal when it
calls <CODE>setsid</CODE> to become the leader of a new session.
See section <A HREF="library_24.html#SEC427" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_24.html#SEC427">Process Group Functions</A>.
<P>
<A NAME="IDX1742"></A>
<H2><A NAME="SEC415" HREF="library_toc.html#SEC415" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC415">Access to the Controlling Terminal</A></H2>
<P>
Processes in the foreground job of a controlling terminal have
unrestricted access to that terminal; background proesses do not. This
section describes in more detail what happens when a process in a
background job tries to access its controlling terminal.
<A NAME="IDX1743"></A>
<P>
When a process in a background job tries to read from its controlling
terminal, the process group is usually sent a <CODE>SIGTTIN</CODE> signal.
This normally causes all of the processes in that group to stop (unless
they handle the signal and don't stop themselves). However, if the
reading process is ignoring or blocking this signal, then <CODE>read</CODE>
fails with an <CODE>EIO</CODE> error instead.
<A NAME="IDX1744"></A>
<P>
Similarly, when a process in a background job tries to write to its
controlling terminal, the default behavior is to send a <CODE>SIGTTOU</CODE>
signal to the process group. However, the behavior is modified by the
<CODE>TOSTOP</CODE> bit of the local modes flags (see section <A HREF="library_16.html#SEC279" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_16.html#SEC279">Local Modes</A>). If
this bit is not set (which is the default), then writing to the
controlling terminal is always permitted without sending a signal.
Writing is also permitted if the <CODE>SIGTTOU</CODE> signal is being ignored
or blocked by the writing process.
<P>
Most other terminal operations that a program can do are treated as
reading or as writing. (The description of each operation should say
which.)
<P>
For more information about the primitive <CODE>read</CODE> and <CODE>write</CODE>
functions, see section <A HREF="library_12.html#SEC173" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_12.html#SEC173">Input and Output Primitives</A>.
<P>
<A NAME="IDX1745"></A>
<H2><A NAME="SEC416" HREF="library_toc.html#SEC416" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC416">Orphaned Process Groups</A></H2>
<P>
When a controlling process terminates, its terminal becomes free and a
new session can be established on it. (In fact, another user could log
in on the terminal.) This could cause a problem if any processes from
the old session are still trying to use that terminal.
<P>
To prevent problems, process groups that continue running even after the
session leader has terminated are marked as <DFN>orphaned process
groups</DFN>. Processes in an orphaned process group cannot read from or
write to the controlling terminal. Attempts to do so will fail with an
<CODE>EIO</CODE> error.
<P>
When a process group becomes an orphan, its processes are sent a
<CODE>SIGHUP</CODE> signal. Ordinarily, this causes the processes to
terminate. However, if a program ignores this signal or establishes a
handler for it (see section <A HREF="library_21.html#SEC330" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC330">Signal Handling</A>), it can continue running as in
the orphan process group even after its controlling process terminates;
but it still cannot access the terminal any more.
<P>
<H2><A NAME="SEC417" HREF="library_toc.html#SEC417" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC417">Implementing a Job Control Shell</A></H2>
<P>
This section describes what a shell must do to implement job control, by
presenting an extensive sample program to illustrate the concepts
involved.
<P>
<UL>
<LI>
section <A HREF="library_24.html#SEC418" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_24.html#SEC418">Data Structures for the Shell</A>, introduces the example and presents
its primary data structures.
<P>
<LI>
section <A HREF="library_24.html#SEC419" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_24.html#SEC419">Initializing the Shell</A>, discusses actions which the shell must
perform to prepare for job control.
<P>
<LI>
section <A HREF="library_24.html#SEC420" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_24.html#SEC420">Launching Jobs</A>, includes information about how to create jobs
to execute commands.
<P>
<LI>
section <A HREF="library_24.html#SEC421" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_24.html#SEC421">Foreground and Background</A>, discusses what the shell should
do differently when launching a job in the foreground as opposed to
a background job.
<P>
<LI>
section <A HREF="library_24.html#SEC422" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_24.html#SEC422">Stopped and Terminated Jobs</A>, discusses reporting of job status
back to the shell.
<P>
<LI>
section <A HREF="library_24.html#SEC423" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_24.html#SEC423">Continuing Stopped Jobs</A>, tells you how to continue jobs that
have been stopped.
<P>
<LI>
section <A HREF="library_24.html#SEC424" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_24.html#SEC424">The Missing Pieces</A>, discusses other parts of the shell.
</UL>
<P>
<H3><A NAME="SEC418" HREF="library_toc.html#SEC418" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC418">Data Structures for the Shell</A></H3>
<P>
All of the program examples included in this chapter are part of
a simple shell program. This section presents data structures
and utility functions which are used throughout the example.
<P>
The sample shell deals mainly with two data structures. The
<CODE>job</CODE> type contains information about a job, which is a
set of subprocesses linked together with pipes. The <CODE>process</CODE> type
holds information about a single subprocess. Here are the relevant
data structure declarations:
<P>
<PRE>
/* A process is a single process. */
typedef struct process
{
struct process *next; /* next process in pipeline */
char **argv; /* for exec */
pid_t pid; /* process ID */
char completed; /* true if process has completed */
char stopped; /* true if process has stopped */
int status; /* reported status value */
} process;
/* A job is a pipeline of processes. */
typedef struct job
{
struct job *next; /* next active job */
char *command; /* command line, used for messages */
process *first_process; /* list of processes in this job */
pid_t pgid; /* process group ID */
char notified; /* true if user told about stopped job */
struct termios tmodes; /* saved terminal modes */
int stdin, stdout, stderr; /* standard i/o channels */
} job;
/* The active jobs are linked into a list. This is its head. */
job *first_job = NULL;
</PRE>
<P>
Here are some utility functions that are used for operating on <CODE>job</CODE>
objects.
<P>
<PRE>
/* Find the active job with the indicated <VAR>pgid</VAR>. */
job *
find_job (pid_t pgid)
{
job *j;
for (j = first_job; j; j = j->next)
if (j->pgid == pgid)
return j;
return NULL;
}
/* Return true if all processes in the job have stopped or completed. */
int
job_is_stopped (job *j)
{
process *p;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -