3.5 What are pttys?
Pseudo-teletypes (pttys, ptys, other variant abbreviations) are pseudo-devices that have two parts: the master side, which can be thought of as the `user', and the slave side, which behaves like a standard tty device.They exist in order to provide a means to emulate the behaviour of a serial terminal under the control of a program. For example,
telnet
uses a pseudo-terminal on the remote system; the remote login shell sees the behaviour it expects from a tty device, but the master side of the pseudo-terminal is being controlled by a daemon that forwards all data over the network. They are also used by programs such as xterm
, expect
, script
, screen
, emacs
, and many others. 3.6 How to handle a serial port or modem?
The handling of serial devices under Unix is heavily influenced by the traditional use of serial terminals. Historically, various combinations of ioctls and other hacks were necessary to control the precise behaviour of a serial device, but fortunately this is one of the areas that POSIX made some efforts to standardise.If you're using a system that doesn't understand
<termios.h>
, tcsetattr()
and related functions, then you'll have to go elsewhere for information (or upgrade your system to something less archaeological). There are still significant differences between systems, however, mainly in the area of device names, handling of hardware flow control, and modem signalling. (Whenever possible, leave the device driver to do all the handshaking work, and don't attempt to manipulate handshaking signals directly.)
The basic steps for opening and initialising a serial device are:
open()
the device; this may require the use of certain flags:
O_NONBLOCK
Opening a dial-in or modem-controlled device will block until carrier is present, unless this flag is used. A nonblocking open gives you the opportunity to disable the modem controls (see CLOCAL below) if necessary.
O_NOCTTY
On 4.4BSD-derived systems this is redundant, but on other systems it controls whether the serial device can become a control terminal for the session. In most cases you probably don't want to acquire a control terminal, and should therefore specify this flag, but there are exceptions.
- Use
tcgetattr()
to retrieve the current device modes. While one will often ignore most or all of the initial settings thus obtained, it's still a convenient way of initialising astruct termios
. - Set suitable values for
c_iflag
,c_oflag
,c_cflag
,c_lflag
, andc_cc
in the termios structure. (See below.) - Use
cfsetispeed()
andcfsetospeed()
to set the desired baud rate. Very few systems allow you to set differing input and output speeds, so as a general rule you should set both to your desired speed. - Use
tcsetattr()
to set the device modes. - You may wish, if you used
O_NONBLOCK
when opening the port, to usefcntl()
to ensure thatO_NONBLOCK
is turned off again. Systems seem to differ as to whether a nonblocking open on a tty will affect subsequentread()
calls; better to be explicit.
read()
and write()
normally. Note that the behaviour of read()
will be controlled by the flag settings you gave to tcsetattr()
. tcflush()
, tcdrain()
, tcsendbreak()
and tcflow()
are additional useful functions that you should be aware of. When you're done with the port, and want to close it, be aware of a very nasty little hazard on some systems; if there's any pending output waiting to be written to the device (e.g. if output flow is stopped by hardware or software handshaking), your process can hang unkillably in the
close()
call until the output drains. Calling tcflush()
to discard any pending output is probably a wise move. (Blocked output on tty devices is by far the most common cause of "unkillable" processes in my experience.)
3.6.1 Serial device names and types
The device names used for serial port devices vary quite widely between systems. Some examples from different systems are:- `/dev/tty[0-9][a-z]' for direct access devices, and `/dev/tty[0-9][A-Z]' for modem control devices (e.g. SCO Unix)
- `/dev/cua[0-9]p[0-9]' for direct access devices, `/dev/cul[0-9]p[0-9]' for dial-out devices and `/dev/ttyd[0-9]p[0-9]' for dial-in devices (e.g. HP-UX)
- `/dev/cua[a-z][0-9]' for dial-out devices and `/dev/tty[a-z][0-9]' for dial-in devices (e.g. FreeBSD)
- A successful open of any device should assert DTR and RTS
- A blocking open of a modem-control or dial-in device will wait for DCD (and possibly also DSR and/or CTS) to be raised, usually after asserting DTR/RTS.
- An open of a dial-out device while an open call to the corresponding dial-in device is blocked waiting for carrier may or may not cause the open of the dial-in port to complete. Some systems implement a simple sharing scheme for dial-in and dial-out ports whereby the dial-in port is effectively "put to sleep" while the dial-out port is in use; other systems do not do this, and sharing the port between dial-in and dial-out on such systems requires external cooperation (e.g. use of UUCP lockfiles) to avoid contention problems.
3.6.2 Setting up termios flags
Some hints on setting up the termios flags when using a serial device that you've opened yourself (as opposed to using your existing control tty):3.6.2.1 c_iflag
You probably want to set all the bits inc_iflag
to 0, unless you want to use software flow control (ick) in which case you set IXON
and IXOFF
. 3.6.2.2 c_oflag
Most of the bits ofc_oflag
are hacks of one sort or another to make output to slow terminals work, and as such some newer systems have dropped almost all of them as obsolete (especially all the gory output-padding options). As with c_iflag
, setting everything to 0 is reasonable for most applications. 3.6.2.3 c_cflag
When setting the character size, remember to mask usingCSIZE
first; e.g. to set 8-bit characters, use: attr.c_cflag &= ~CSIZE;
attr.c_cflag |= CS8;Other important flags found in
c_cflag
that you probably want to turn on and CREAD
and HUPCL
. If you need to generate even parity, then set
PARENB
and clear PARODD
; if you need to generate odd parity then set both PARENB
and PARODD
. If you don't want parity at all, then make sure PARENB
is clear. Clear
CSTOPB
unless you actually need to generate two stop bits. Flags for enabling hardware flow control may also be found in
c_cflag
, but they aren't standardised (pity). 3.6.2.4 c_lflag
Most applications will probably want to turn offICANON
(canonical, i.e. line-based, input processing), ECHO
, and ISIG
. IEXTEN
is a more complex issue. If you don't turn it off, the implementation is allowed to do nonstandard things (like define additional control characters in c_cc
) that might cause unexpected results, but you might need to leave IEXTEN
enabled on some systems to get useful features like hardware flow control. 3.6.2.5 c_cc
This is an array of characters that have special meanings on input. These characters are given names likeVINTR
, VSTOP
etc.; the names are indexes into the array. (Two of these "characters" are not really characters at all, but control the behaviour of
read()
when ICANON
is disabled; these are VMIN
and VTIME
.) The indexes are often referred to as though they were actual variables, e.g. "set VMIN to 1" actually means "set c_cc[VMIN] to 1". The shorthand is useful and only occasionally confusing.
Many of the slots in
c_cc
are only used if some other combination of flags is set:
Used only if
ICANON
is set VEOF
, VEOL
, VERASE
, VKILL
(and also VEOL2
, VSTATUS
and VWERASE
if defined and IEXTEN
is set)
Used only if
ISIG
is set VINTR
, VQUIT
, VSUSP
(and also VDSUSP
if defined and IEXTEN
is set)
Used only if
IXON
or IXOFF
is set VSTOP
, VSTART
Used only if
ICANON
is not set VMIN
, VTIME
c_cc
. It may be prudent to initialise all the entries to _POSIX_VDISABLE
(the constant NCCS
gives the array size) before setting the specific values you wish to use. VMIN
and VTIME
(which may share slots with VEOF
and VEOL
respectively, depending on the implementation) have the following meaning. The value of VTIME
is (if not 0) always interpreted as a timer in tenths of seconds. c_cc[VMIN] > 0, c_cc[VTIME] > 0
read()
will return when either VMIN bytes of input are available, or if at least one character has been read and VTIME has expired between characters, or if interrupted by a signal. c_cc[VMIN] > 0, c_cc[VTIME] == 0
read()
will return when VMIN bytes of input are available, or if interrupted. Otherwise it will wait indefinitely. c_cc[VMIN] == 0, c_cc[VTIME] > 0
read()
will return as soon as any input is available; if VTIME expires with no data arriving, it will return with no characters read. (This conflicts slightly with the end-of-file indication received in the event of modem hangup; using 1 for VMIN and either alarm()
or select()
for a timeout avoids this particular problem.) c_cc[VMIN] == 0, c_cc[VTIME] == 0
read()
will always return immediately; if no data is available it will return with no characters read (with the same problem as above.To Look for similar posts on File handling in Linux explore the following links from the same blog as well.
Post a Comment