Files
oldlinux-files/Ref-docs/POSIX/susv3/xrat/xbd_chap11.html
2024-02-19 00:21:47 -05:00

359 lines
22 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link type="text/css" rel="stylesheet" href="style.css"><!-- Generated by The Open Group's rhtm tool v1.2.1 -->
<!-- Copyright (c) 2001 The Open Group, All Rights Reserved -->
<title>Rationale</title>
</head>
<body>
<basefont size="3">
<center><font size="2">The Open Group Base Specifications Issue 6<br>
IEEE Std 1003.1-2001<br>
Copyright &copy; 2001 The IEEE and The Open Group</font></center>
<hr size="2" noshade>
<h3><a name="tag_01_11"></a>General Terminal Interface</h3>
<p>If the implementation does not support this interface on any device types, it should behave as if it were being used on a device
that is not a terminal device (in most cases <i>errno</i> will be set to [ENOTTY] on return from functions defined by this
interface). This is based on the fact that many applications are written to run both interactively and in some non-interactive
mode, and they adapt themselves at runtime. Requiring that they all be modified to test an environment variable to determine
whether they should try to adapt is unnecessary. On a system that provides no general terminal interface, providing all the entry
points as stubs that return [ENOTTY] (or an equivalent, as appropriate) has the same effect and requires no changes to the
application.</p>
<p>Although the needs of both interface implementors and application developers were addressed throughout
IEEE&nbsp;Std&nbsp;1003.1-2001, this section pays more attention to the needs of the latter. This is because, while many aspects of
the programming interface can be hidden from the user by the application developer, the terminal interface is usually a large part
of the user interface. Although to some extent the application developer can build missing features or work around inappropriate
ones, the difficulties of doing that are greater in the terminal interface than elsewhere. For example, efficiency prohibits the
average program from interpreting every character passing through it in order to simulate character erase, line kill, and so on.
These functions should usually be done by the operating system, possibly at the interrupt level.</p>
<p>The <i>tc*</i>() functions were introduced as a way of avoiding the problems inherent in the
traditional <a href="../functions/ioctl.html"><i>ioctl</i>()</a> function and in variants of it that were proposed. For example, <a
href="../functions/tcsetattr.html"><i>tcsetattr</i>()</a> is specified in place of the use of the TCSETA <a href=
"../functions/ioctl.html"><i>ioctl</i>()</a> command function. This allows specification of all the arguments in a manner
consistent with the ISO&nbsp;C standard unlike the varying third argument of <a href="../functions/ioctl.html"><i>ioctl</i>()</a>,
which is sometimes a pointer (to any of many different types) and sometimes an <b>int</b>.</p>
<p>The advantages of this new method include:</p>
<ul>
<li>
<p>It allows strict type checking.</p>
</li>
<li>
<p>The direction of transfer of control data is explicit.</p>
</li>
<li>
<p>Portable capabilities are clearly identified.</p>
</li>
<li>
<p>The need for a general interface routine is avoided.</p>
</li>
<li>
<p>Size of the argument is well-defined (there is only one type).</p>
</li>
</ul>
<p>The disadvantages include:</p>
<ul>
<li>
<p>No historical implementation used the new method.</p>
</li>
<li>
<p>There are many small routines instead of one general-purpose one.</p>
</li>
<li>
<p>The historical parallel with <a href="../functions/fcntl.html"><i>fcntl</i>()</a> is broken.</p>
</li>
</ul>
<p>The issue of modem control was excluded from IEEE&nbsp;Std&nbsp;1003.1-2001 on the grounds that:</p>
<ul>
<li>
<p>It was concerned with setting and control of hardware timers.</p>
</li>
<li>
<p>The appropriate timers and settings vary widely internationally.</p>
</li>
<li>
<p>Feedback from European computer manufacturers indicated that this facility was not consistent with European needs and that
specification of such a facility was not a requirement for portability.</p>
</li>
</ul>
<h4><a name="tag_01_11_01"></a>Interface Characteristics</h4>
<h5><a name="tag_01_11_01_01"></a>Opening a Terminal Device File</h5>
<p>There is no additional rationale provided for this section.</p>
<h5><a name="tag_01_11_01_02"></a>Process Groups</h5>
<p>There is a potential race when the members of the foreground process group on a terminal leave that process group, either by
exit or by changing process groups. After the last process exits the process group, but before the foreground process group ID of
the terminal is changed (usually by a job control shell), it would be possible for a new process to be created with its process ID
equal to the terminal's foreground process group ID. That process might then become the process group leader and accidentally be
placed into the foreground on a terminal that was not necessarily its controlling terminal. As a result of this problem, the
controlling terminal is defined to not have a foreground process group during this time.</p>
<p>The cases where a controlling terminal has no foreground process group occur when all processes in the foreground process group
either terminate and are waited for or join other process groups via <a href="../functions/setpgid.html"><i>setpgid</i>()</a> or <a
href="../functions/setsid.html"><i>setsid</i>()</a>. If the process group leader terminates, this is the first case described; if
it leaves the process group via <a href="../functions/setpgid.html"><i>setpgid</i>()</a>, this is the second case described (a
process group leader cannot successfully call <a href="../functions/setsid.html"><i>setsid</i>()</a>). When one of those cases
causes a controlling terminal to have no foreground process group, it has two visible effects on applications. The first is the
value returned by <a href="../functions/tcgetpgrp.html"><i>tcgetpgrp</i>()</a>. The second (which occurs only in the case where the
process group leader terminates) is the sending of signals in response to special input characters. The intent of
IEEE&nbsp;Std&nbsp;1003.1-2001 is that no process group be wrongly identified as the foreground process group by <a href=
"../functions/tcgetpgrp.html"><i>tcgetpgrp</i>()</a> or unintentionally receive signals because of placement into the
foreground.</p>
<p>In 4.3 BSD, the old process group ID continues to be used to identify the foreground process group and is returned by the
function equivalent to <a href="../functions/tcgetpgrp.html"><i>tcgetpgrp</i>()</a>. In that implementation it is possible for a
newly created process to be assigned the same value as a process ID and then form a new process group with the same value as a
process group ID. The result is that the new process group would receive signals from this terminal for no apparent reason, and
IEEE&nbsp;Std&nbsp;1003.1-2001 precludes this by forbidding a process group from entering the foreground in this way. It would be
more direct to place part of the requirement made by the last sentence under <a href="../functions/fork.html"><i>fork</i>()</a>,
but there is no convenient way for that section to refer to the value that <a href=
"../functions/tcgetpgrp.html"><i>tcgetpgrp</i>()</a> returns, since in this case there is no process group and thus no process
group ID.</p>
<p>One possibility for a conforming implementation is to behave similarly to 4.3 BSD, but to prevent this reuse of the ID, probably
in the implementation of <a href="../functions/fork.html"><i>fork</i>()</a>, as long as it is in use by the terminal.</p>
<p>Another possibility is to recognize when the last process stops using the terminal's foreground process group ID, which is when
the process group lifetime ends, and to change the terminal's foreground process group ID to a reserved value that is never used as
a process ID or process group ID. (See the definition of <i>process group lifetime</i> in the definitions section.) The process ID
can then be reserved until the terminal has another foreground process group.</p>
<p>The 4.3 BSD implementation permits the leader (and only member) of the foreground process group to leave the process group by
calling the equivalent of <a href="../functions/setpgid.html"><i>setpgid</i>()</a> and to later return, expecting to return to the
foreground. There are no known application needs for this behavior, and IEEE&nbsp;Std&nbsp;1003.1-2001 neither requires nor forbids
it (except that it is forbidden for session leaders) by leaving it unspecified.</p>
<h5><a name="tag_01_11_01_03"></a>The Controlling Terminal</h5>
<p>IEEE&nbsp;Std&nbsp;1003.1-2001 does not specify a mechanism by which to allocate a controlling terminal. This is normally done
by a system utility (such as <i>getty</i>) and is considered an administrative feature outside the scope of
IEEE&nbsp;Std&nbsp;1003.1-2001.</p>
<p>Historical implementations allocate controlling terminals on certain <a href="../functions/open.html"><i>open</i>()</a> calls.
Since <a href="../functions/open.html"><i>open</i>()</a> is part of POSIX.1, its behavior had to be dealt with. The traditional
behavior is not required because it is not very straightforward or flexible for either implementations or applications. However,
because of its prevalence, it was not practical to disallow this behavior either. Thus, a mechanism was standardized to ensure
portable, predictable behavior in <a href="../functions/open.html"><i>open</i>()</a>.</p>
<p>Some historical implementations deallocate a controlling terminal on the last system-wide close. This behavior in neither
required nor prohibited. Even on implementations that do provide this behavior, applications generally cannot depend on it due to
its system-wide nature.</p>
<h5><a name="tag_01_11_01_04"></a>Terminal Access Control</h5>
<p>The access controls described in this section apply only to a process that is accessing its controlling terminal. A process
accessing a terminal that is not its controlling terminal is effectively treated the same as a member of the foreground process
group. While this may seem unintuitive, note that these controls are for the purpose of job control, not security, and job control
relates only to a process' controlling terminal. Normal file access permissions handle security.</p>
<p>If the process calling <a href="../functions/read.html"><i>read</i>()</a> or <a href=
"../functions/write.html"><i>write</i>()</a> is in a background process group that is orphaned, it is not desirable to stop the
process group, as it is no longer under the control of a job control shell that could put it into the foreground again.
Accordingly, calls to <a href="../functions/read.html"><i>read</i>()</a> or <a href="../functions/write.html"><i>write</i>()</a>
functions by such processes receive an immediate error return. This is different from 4.2 BSD, which kills orphaned processes that
receive terminal stop signals.</p>
<p>The foreground/background/orphaned process group check performed by the terminal driver must be repeatedly performed until the
calling process moves into the foreground or until the process group of the calling process becomes orphaned. That is, when the
terminal driver determines that the calling process is in the background and should receive a job control signal, it sends the
appropriate signal (SIGTTIN or SIGTTOU) to every process in the process group of the calling process and then it allows the calling
process to immediately receive the signal. The latter is typically performed by blocking the process so that the signal is
immediately noticed. Note, however, that after the process finishes receiving the signal and control is returned to the driver, the
terminal driver must re-execute the foreground/background/orphaned process group check. The process may still be in the background,
either because it was continued in the background by a job control shell, or because it caught the signal and did nothing.</p>
<p>The terminal driver repeatedly performs the foreground/background/orphaned process group checks whenever a process is about to
access the terminal. In the case of <a href="../functions/write.html"><i>write</i>()</a> or the control
<i>tc*</i>() functions, the check is performed at the entry of the function. In the case of <a href=
"../functions/read.html"><i>read</i>()</a>, the check is performed not only at the entry of the function, but also after blocking
the process to wait for input characters (if necessary). That is, once the driver has determined that the process calling the <a
href="../functions/read.html"><i>read</i>()</a> function is in the foreground, it attempts to retrieve characters from the input
queue. If the queue is empty, it blocks the process waiting for characters. When characters are available and control is returned
to the driver, the terminal driver must return to the repeated foreground/background/orphaned process group check again. The
process may have moved from the foreground to the background while it was blocked waiting for input characters.</p>
<h5><a name="tag_01_11_01_05"></a>Input Processing and Reading Data</h5>
<p>There is no additional rationale provided for this section.</p>
<h5><a name="tag_01_11_01_06"></a>Canonical Mode Input Processing</h5>
<p>The term &quot;character&quot; is intended here. ERASE should erase the last character, not the last byte. In the case of multi-byte
characters, these two may be different.</p>
<p>4.3 BSD has a WERASE character that erases the last &quot;word&quot; typed (but not any preceding &lt;blank&gt;s or &lt;tab&gt;s). A
word is defined as a sequence of non- &lt;blank&gt;s, with &lt;tab&gt;s counted as &lt;blank&gt;s. Like ERASE, WERASE does not
erase beyond the beginning of the line. This WERASE feature has not been specified in POSIX.1 because it is difficult to define in
the international environment. It is only useful for languages where words are delimited by &lt;blank&gt;s. In some ideographic
languages, such as Japanese and Chinese, words are not delimited at all. The WERASE character should presumably go back to the
beginning of a sentence in those cases; practically, this means it would not be used much for those languages.</p>
<p>It should be noted that there is a possible inherent deadlock if the application and implementation conflict on the value of
{MAX_CANON}. With ICANON set (if IXOFF is enabled) and more than {MAX_CANON} characters transmitted without a &lt;linefeed&gt;,
transmission will be stopped, the &lt;linefeed&gt; (or &lt;carriage-return&gt; when ICRLF is set) will never arrive, and the <a
href="../functions/read.html"><i>read</i>()</a> will never be satisfied.</p>
<p>An application should not set IXOFF if it is using canonical mode unless it knows that (even in the face of a transmission
error) the conditions described previously cannot be met or unless it is prepared to deal with the possible deadlock in some other
way, such as timeouts.</p>
<p>It should also be noted that this can be made to happen in non-canonical mode if the trigger value for sending IXOFF is less
than VMIN and VTIME is zero.</p>
<h5><a name="tag_01_11_01_07"></a>Non-Canonical Mode Input Processing</h5>
<p>Some points to note about MIN and TIME:</p>
<ol>
<li>
<p>The interactions of MIN and TIME are not symmetric. For example, when MIN&gt;0 and TIME=0, TIME has no effect. However, in the
opposite case where MIN=0 and TIME&gt;0, both MIN and TIME play a role in that MIN is satisfied with the receipt of a single
character.</p>
</li>
<li>
<p>Also note that in case A (MIN&gt;0, TIME&gt;0), TIME represents an inter-character timer, while in case C (MIN=0, TIME&gt;0),
TIME represents a read timer.</p>
</li>
</ol>
<p>These two points highlight the dual purpose of the MIN/TIME feature. Cases A and B, where MIN&gt;0, exist to handle burst-mode
activity (for example, file transfer programs) where a program would like to process at least MIN characters at a time. In case A,
the inter-character timer is activated by a user as a safety measure; in case B, it is turned off.</p>
<p>Cases C and D exist to handle single-character timed transfers. These cases are readily adaptable to screen-based applications
that need to know if a character is present in the input queue before refreshing the screen. In case C, the read is timed; in case
D, it is not.</p>
<p>Another important note is that MIN is always just a minimum. It does not denote a record length. That is, if a program does a
read of 20 bytes, MIN is 10, and 25 characters are present, 20 characters are returned to the user. In the special case of MIN=0,
this still applies: if more than one character is available, they all will be returned immediately.</p>
<h5><a name="tag_01_11_01_08"></a>Writing Data and Output Processing</h5>
<p>There is no additional rationale provided for this section.</p>
<h5><a name="tag_01_11_01_09"></a>Special Characters</h5>
<p>There is no additional rationale provided for this section.</p>
<h5><a name="tag_01_11_01_10"></a>Modem Disconnect</h5>
<p>There is no additional rationale provided for this section.</p>
<h5><a name="tag_01_11_01_11"></a>Closing a Terminal Device File</h5>
<p>IEEE&nbsp;Std&nbsp;1003.1-2001 does not specify that a <a href="../functions/close.html"><i>close</i>()</a> on a terminal device
file include the equivalent of a call to <i>tcflow</i>( <i>fd</i>,TCOON).</p>
<p>An implementation that discards output at the time <a href="../functions/close.html"><i>close</i>()</a> is called after
reporting the return value to the <a href="../functions/write.html"><i>write</i>()</a> call that data was written does not conform
with IEEE&nbsp;Std&nbsp;1003.1-2001. An application has functions such as <a href="../functions/tcdrain.html"><i>tcdrain</i>()</a>,
<a href="../functions/tcflush.html"><i>tcflush</i>()</a>, and <a href="../functions/tcflow.html"><i>tcflow</i>()</a> available to
obtain the detailed behavior it requires with respect to flushing of output.</p>
<p>At the time of the last close on a terminal device, an application relinquishes any ability to exert flow control via <a href=
"../functions/tcflow.html"><i>tcflow</i>()</a>.</p>
<h4><a name="tag_01_11_02"></a>Parameters that Can be Set</h4>
<h5><a name="tag_01_11_02_01"></a>The termios Structure</h5>
<p>This structure is part of an interface that, in general, retains the historic grouping of flags. Although a more optimal
structure for implementations may be possible, the degree of change to applications would be significantly larger.</p>
<h5><a name="tag_01_11_02_02"></a>Input Modes</h5>
<p>Some historical implementations treated a long break as multiple events, as many as one per character time. The wording in
POSIX.1 explicitly prohibits this.</p>
<p>Although the ISTRIP flag is normally superfluous with today's terminal hardware and software, it is historically supported.
Therefore, applications may be using ISTRIP, and there is no technical problem with supporting this flag. Also, applications may
wish to receive only 7-bit input bytes and may not be connected directly to the hardware terminal device (for example, when a
connection traverses a network).</p>
<p>Also, there is no requirement in general that the terminal device ensures that high-order bits beyond the specified character
size are cleared. ISTRIP provides this function for 7-bit characters, which are common.</p>
<p>In dealing with multi-byte characters, the consequences of a parity error in such a character, or in an escape sequence
affecting the current character set, are beyond the scope of POSIX.1 and are best dealt with by the application processing the
multi-byte characters.</p>
<h5><a name="tag_01_11_02_03"></a>Output Modes</h5>
<p>POSIX.1 does not describe postprocessing of output to a terminal or detailed control of that from a conforming application.
(That is, translation of &lt;newline&gt; to &lt;carriage-return&gt; followed by &lt;linefeed&gt; or &lt;tab&gt; processing.) There
is nothing that a conforming application should do to its output for a terminal because that would require knowledge of the
operation of the terminal. It is the responsibility of the operating system to provide postprocessing appropriate to the output
device, whether it is a terminal or some other type of device.</p>
<p>Extensions to POSIX.1 to control the type of postprocessing already exist and are expected to continue into the future. The
control of these features is primarily to adjust the interface between the system and the terminal device so the output appears on
the display correctly. This should be set up before use by any application.</p>
<p>In general, both the input and output modes should not be set absolutely, but rather modified from the inherited state.</p>
<h5><a name="tag_01_11_02_04"></a>Control Modes</h5>
<p>This section could be misread that the symbol &quot;CSIZE&quot; is a title in the <b>termios</b> <i>c_cflag</i> field. Although it does
serve that function, it is also a required symbol, as a literal reading of POSIX.1 (and the caveats about typography) would
indicate.</p>
<h5><a name="tag_01_11_02_05"></a>Local Modes</h5>
<p>Non-canonical mode is provided to allow fast bursts of input to be read efficiently while still allowing single-character
input.</p>
<p>The ECHONL function historically has been in many implementations. Since there seems to be no technical problem with supporting
ECHONL, it is included in POSIX.1 to increase consensus.</p>
<p>The alternate behavior possible when ECHOK or ECHOE are specified with ICANON is permitted as a compromise depending on what the
actual terminal hardware can do. Erasing characters and lines is preferred, but is not always possible.</p>
<h5><a name="tag_01_11_02_06"></a>Special Control Characters</h5>
<p>Permitting VMIN and VTIME to overlap with VEOF and VEOL was a compromise for historical implementations. Only when
backwards-compatibility of object code is a serious concern to an implementor should an implementation continue this practice.
Correct applications that work with the overlap (at the source level) should also work if it is not present, but not the
reverse.</p>
<hr size="2" noshade>
<center><font size="2"><!--footer start-->
UNIX &reg; is a registered Trademark of The Open Group.<br>
POSIX &reg; is a registered Trademark of The IEEE.<br>
[ <a href="../mindex.html">Main Index</a> | <a href="../basedefs/contents.html">XBD</a> | <a href=
"../utilities/contents.html">XCU</a> | <a href="../functions/contents.html">XSH</a> | <a href="../xrat/contents.html">XRAT</a>
]</font></center>
<!--footer end-->
<hr size="2" noshade>
</body>
</html>