Expand description
An interface for controlling asynchronous communication ports
This interface provides a safe wrapper around the termios subsystem defined by POSIX. The underlying types are all implemented in libc for most platforms and either wrapped in safer types here or exported directly.
If you are unfamiliar with the termios
API, you should first read the
API documentation and
then come back to understand how nix
safely wraps it.
It should be noted that this API incurs some runtime overhead above the base libc
definitions.
As this interface is not used with high-bandwidth information, this should be fine in most
cases. The primary cost when using this API is that the Termios
datatype here duplicates the
standard fields of the underlying termios
struct and uses safe type wrappers for those fields.
This means that when crossing the FFI interface to the underlying C library, data is first
copied into the underlying termios
struct, then the operation is done, and the data is copied
back (with additional sanity checking) into the safe wrapper types. The termios
struct is
relatively small across all platforms (on the order of 32-64 bytes).
The following examples highlight some of the API use cases such that users coming from using C or reading the standard documentation will understand how to use the safe API exposed here.
Example disabling processing of the end-of-file control character:
termios.control_chars[VEOF as usize] = _POSIX_VDISABLE;
The flags within Termios
are defined as bitfields using the bitflags
crate. This provides
an interface for working with bitfields that is similar to working with the raw unsigned
integer types but offers type safety because of the internal checking that values will always
be a valid combination of the defined flags.
An example showing some of the basic operations for interacting with the control flags:
termios.control_flags & ControlFlags::CSIZE == ControlFlags::CS5;
termios.control_flags |= ControlFlags::CS5;
§Baud rates
This API is not consistent across platforms when it comes to BaudRate
: Android and Linux both
only support the rates specified by the BaudRate
enum through their termios API while the BSDs
support arbitrary baud rates as the values of the BaudRate
enum constants are the same integer
value of the constant (B9600
== 9600
). Therefore the nix::termios
API uses the following
conventions:
cfgetispeed()
- Returnsu32
on BSDs,BaudRate
on Android/Linuxcfgetospeed()
- Returnsu32
on BSDs,BaudRate
on Android/Linuxcfsetispeed()
- Takesu32
orBaudRate
on BSDs,BaudRate
on Android/Linuxcfsetospeed()
- Takesu32
orBaudRate
on BSDs,BaudRate
on Android/Linuxcfsetspeed()
- Takesu32
orBaudRate
on BSDs,BaudRate
on Android/Linux
The most common use case of specifying a baud rate using the enum will work the same across platforms:
cfsetispeed(&mut t, BaudRate::B9600).unwrap();
cfsetospeed(&mut t, BaudRate::B9600).unwrap();
cfsetspeed(&mut t, BaudRate::B9600).unwrap();
Additionally round-tripping baud rates is consistent across platforms:
let speed = cfgetispeed(&t);
assert_eq!(speed, cfgetospeed(&t));
cfsetispeed(&mut t, speed).unwrap();
On non-BSDs, cfgetispeed()
and cfgetospeed()
both return a BaudRate
:
assert_eq!(cfgetispeed(&t), BaudRate::B9600);
assert_eq!(cfgetospeed(&t), BaudRate::B9600);
But on the BSDs, cfgetispeed()
and cfgetospeed()
both return u32
s:
assert_eq!(cfgetispeed(&t), 9600u32);
assert_eq!(cfgetospeed(&t), 9600u32);
It’s trivial to convert from a BaudRate
to a u32
on BSDs:
assert_eq!(cfgetispeed(&t), BaudRate::B9600.into());
assert_eq!(u32::from(BaudRate::B9600), 9600u32);
And on BSDs you can specify arbitrary baud rates (note this depends on hardware support)
by specifying baud rates directly using u32
s:
cfsetispeed(&mut t, 9600u32);
cfsetospeed(&mut t, 9600u32);
cfsetspeed(&mut t, 9600u32);
Structs§
- Flags for setting the control mode of a terminal
- Flags for configuring the input mode of a terminal
- Flags for setting any local modes
- Flags for configuring the output mode of a terminal
- Stores settings for the termios API
Enums§
- Baud rates supported by the system.
- Specify how transmission flow should be altered
- Specify a combination of the input and output buffers to flush
- Specify when a port configuration change should occur.
- Indices into the
termios.c_cc
array for special characters.
Constants§
Functions§
- Get input baud rate (see cfgetispeed(3p)).
- Get output baud rate (see cfgetospeed(3p)).
- Configures the port to something like the “raw” mode of the old Version 7 terminal driver (see termios(3)).
- Set input baud rate (see cfsetispeed(3p)).
- Set output baud rate (see cfsetospeed(3p)).
- Set both the input and output baud rates (see termios(3)).
- Block until all output data is written (see tcdrain(3p)).
- Suspend or resume the transmission or reception of data (see tcflow(3p)).
- Discard data in the output or input queue (see tcflush(3p)).
- Return the configuration of a port tcgetattr(3p)).
- Get the session controlled by the given terminal (see tcgetsid(3)).
- Send a break for a specific duration (see tcsendbreak(3p)).
- Set the configuration for a terminal (see tcsetattr(3p)).