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
O_NOCTTY
tcgetattr() to retrieve the current device modes. While one
struct termios.
c_iflag, c_oflag, c_cflag,
c_lflag, and c_cc in the termios structure. (See below.)
cfsetispeed() and cfsetospeed() to set the desired
tcsetattr() to set the device modes.
O_NONBLOCK when opening the port, to
fcntl() to ensure that O_NONBLOCK is turned off again.
read() calls; better to be explicit.
Once you have opened and set up the port, you can then use 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.)