IO::Termios(3pm)

πŸ“¦
version 0.10 Β· 2 versions
, in debian trixie, ubuntu resolute, ubuntu stonking

πŸ’– IO::Termios β€” the manual page, but make it a group chat πŸ’–

okay bestie, so this is the IO::Termios page from the User Contributed Perl Documentation section. it's a Perl module. it's giving very much "let me talk to your serial port for you". let's go ✨


🌸 NAME 🌸

IO::Termios β€” no cap, what it does is supply termios(3) methods to IO::Handle objects. that's the whole vibe. 🫢


πŸŽ€ SYNOPSIS πŸŽ€

use IO::Termios;

my $term = IO::Termios->open( "/dev/ttyS0", "9600,8,n,1" )
   or die "Cannot open ttyS0 - $!";

$term->print( "Hello world\n" ); # Still an IO::Handle

while( <$term> ) {
   print "A line from ttyS0: $_";
}

see how it's still an IO::Handle? like yes it got a glow-up but it did not forget where it came from πŸ’…


πŸ¦‹ DESCRIPTION πŸ¦‹

so basically this class extends the generic IO::Handle object class and gives it methods that reach into the system's terminal control termios(3) operations. these methods are mainly the moment when you're dealing with TTY devices β€” serial ports included, obviously. πŸ”₯

the flag-setting methods will apply to any TTY device, pseudo-tty included, and they're super handy for controlling flags like the ECHO flag, aka turning off local echo. iconic behaviour tbh.

my $stdin = IO::Termios->new( \*STDIN );
$stdin->setflag_echo( 0 );

and when you're dealing with a serial port? the line mode method is the one β€” it sets the basic serial parameters like baud rate, and the modem line control methods let you poke at the hardware handshaking lines. slay.

my $ttyS0 = IO::Termios->open( "/dev/ttyS0" );
$ttyS0->set_mode( "19200,8,n,1" );
$ttyS0->set_modem({ dsr => 1, cts => 1 });

✨ Upgrading STDIN/STDOUT/STDERR ✨

if you pass the -upgrade option at import time, then any of STDIN, STDOUT or STDERR that turn out to be TTY wrappers get automatically upgraded into IO::Termios instances. glow-up, but for your standard streams πŸ’–

use IO::Termios -upgrade;

STDIN->setflag_echo(0);

🌈 Arbitrary Baud Rates on Linux 🌈

Linux has a non-POSIX extension to the usual termios interface that lets you set arbitrary baud rates. IO::Termios can automatically use that ability if the Linux::Termios2 module is installed. if it is, it gets used automatically and transparently, so the set*baud methods can set any rate the kernel/driver allows. if it's not installed? then bestie, only the POSIX-compatible rates for you. 😭


πŸ‘‘ CONSTRUCTORS πŸ‘‘

🌟 new

$term = IO::Termios->new();

constructs a new IO::Termios object around the terminal for the program. how does it find it? it checks whether any of STDIN, STDOUT or STDERR is a terminal, and the first one it finds is the one it uses. if it can't find a terminal this way, that's an error. periodt.

🌟 new (handle)

$term = IO::Termios->new( $handle );

constructs a new IO::Termios object around the given filehandle. simple as that, no drama πŸ’…

🌟 open

$term = IO::Termios->open( $path, $modestr, $flags );

opens the given path and returns a new IO::Termios object around the filehandle. if the open call fails, you get undef back. πŸ™ˆ

if $modestr is provided, the constructor passes it to the set_mode method before returning.

if $flags is provided, it gets passed on to the underlying sysopen() call used to open the filehandle. it should be a bitwise-or combination of O_* flags from the Fcntl module β€” for example O_NOCTTY or O_NDELAY. the value O_RDWR gets added to it automatically, so the caller doesn't need to say it themselves. for example:

use Fcntl qw( O_NOCTTY O_NDELAY );

$term = IO::Termios->open( "/dev/ttyS0", O_NOCTTY|O_NDELAY );
$term->setflag_clocal( 1 );
$term->blocking( 1 );

πŸ’… METHODS πŸ’…

πŸ’œ getattr

$attrs = $term->getattr;

makes a tcgetattr() call on the underlying filehandle and returns an IO::Termios::Attrs object. πŸŽ€

if the tcgetattr() call fails, undef comes back.

πŸ’œ setattr

$term->setattr( $attrs );

makes a tcsetattr() call on the underlying file handle, setting attributes from the given IO::Termios::Attrs object.

if the tcsetattr() call fails, undef comes back. otherwise you get a true value. no in-between, bestie.

πŸ’œ set_mode / get_mode

$term->set_mode( $modestr );

$modestr = $term->get_mode;

accessor for the derived "mode string" β€” a comma-joined concatenation of the baud rate, character size, parity mode, and stop size, in a format like:

19200,8,n,1

when you're setting the mode string, trailing components can be omitted, which means their value just won't be touched. lowkey convenient.

πŸ’œ tiocmget / tiocmset

$bits = $term->tiocmget;

$term->tiocmset( $bits );

accessor for the modem line control bits. takes or returns a bitmask of values. bitmask girlies rise 🫢

πŸ’œ tiocmbic / tiocmbis

$term->tiocmbic( $bits );

$term->tiocmbis( $bits );

bitwise mutator methods for the modem line control bits. tiocmbic clears just the bits you provided and leaves all the others alone; tiocmbis sets them. they do not touch anything else, they're very respectful of boundaries ✨

πŸ’œ get_modem

$flags = $term->get_modem;

returns a hash reference holding named flags corresponding to the modem line control bits. any bit that's set will show up as a key in the returned hash with the same name. the bit names are:

dtr dsr rts cts cd ri

πŸ’œ set_modem

$term->set_modem( $flags );

changes the modem line control bit flags as given by the hash reference. each bit you want changed should be a key in the $flags hash, using the names listed above. false values get cleared, true values get set. other flags will not be altered. as we said: boundaries πŸ’…

πŸ’œ getmodem_BIT / setmodem_BIT

$set = $term->getmodem_BIT;

$term->setmodem_BIT( $set );

accessor methods for each one of the modem line control bits. there's a set of methods for every named modem control bit listed above. one per bit, all the bits, no bit left behind πŸŽ€


🌈 FLAG-ACCESSOR METHODS 🌈

these methods are implemented in terms of the lower level methods, but they give you an interface that's more abstract and easier to re-implement on other non-POSIX systems. so like, use these ones in preference to the lower ones. iykyk.

for efficiency, when you're getting or setting a large number of flags, it can be more efficient to call getattr, then operate on the returned object, and then possibly pass it to setattr. the returned IO::Termios::Attrs object supports the same methods documented here. so you can do a whole lil makeover in one go ✨

the following two sections of code are therefore equivalent, though the latter is more efficient since it only calls setattr once:

$term->setbaud( 38400 );
$term->setcsize( 8 );
$term->setparity( 'n' );
$term->setstop( 1 );

my $attrs = $term->getattr;
$attrs->setbaud( 38400 );
$attrs->setcsize( 8 );
$attrs->setparity( 'n' );
$attrs->setstop( 1 );
$term->setattr( $attrs );

but for the common case of setting baud rate, character size, parity and stop size all at the same time, there's a convenient shortcut method. it's set_mode:

$term->set_mode( "38400,8,n,1" );

🌟 getibaud / getobaud / setibaud / setobaud / setbaud

$baud = $term->getibaud;

$baud = $term->getobaud;

$term->setibaud( $baud );

$term->setobaud( $baud );

$term->setbaud( $baud );

convenience accessors for the ispeed and ospeed. $baud is an integer that directly gives the line rate, instead of one of the Bnnn constants. so you just say the number, bestie πŸ’–

🌟 getcsize / setcsize

$bits = $term->getcsize;

$term->setcsize( $bits );

convenience accessor for the CSIZE bits of c_cflag. $bits is an integer from 5 to 8.

🌟 getparity / setparity

$parity = $term->getparity;

$term->setparity( $parity );

convenience accessor for the PARENB and PARODD bits of c_cflag. $parity is n, o or e.

🌟 getstop / setstop

$stop = $term->getstop;

$term->setstop( $stop );

convenience accessor for the CSTOPB bit of c_cflag. $stop is 1 or 2.

🌟 cfmakeraw

$term->cfmakeraw;

since version 0.07. πŸŽ€

adjusts several bit flags to put the terminal into a "raw" mode. input becomes available a character at a time, echo is disabled, and all special processing of input and output characters is disabled. it's giving unhinged, unfiltered, no-edit terminal. iconic.

🌟 getflag_FLAG / setflag_FLAG

$mode = $term->getflag_FLAG;

$term->setflag_FLAG( $mode );

accessors for various control flags. the following methods are defined for specific flags:

  • inlcr β€” since version 0.09. the INLCR bit of the c_iflag. this translates NL to CR on input.
  • igncr β€” since version 0.09. the IGNCR bit of the c_iflag. this ignores incoming CR characters.
  • icrnl β€” since version 0.09. the ICRNL bit of the c_iflag. this translates CR to NL on input, unless IGNCR is also set.
  • ignbrk β€” since version 0.09. the IGNBRK bit of the c_iflag. this controls whether incoming break conditions are ignored entirely.
  • brkint β€” since version 0.09. the BRKINT bit of the c_iflag. this controls whether non-ignored incoming break conditions result in a SIGINT signal being delivered to the process. if not, such a condition reads as a nul byte.
  • parmrk β€” since version 0.09. the PARMRK bit of the c_iflag. this controls how parity errors and break conditions are handled.
  • opost β€” since version 0.07. the OPOST bit of the c_oflag. this enables system-specific post-processing on output.
  • cread β€” the CREAD bit of the c_cflag. this enables the receiver.
  • hupcl β€” the HUPCL bit of the c_cflag. this lowers the modem control lines after the last process closes the device.
  • clocal β€” the CLOCAL bit of the c_cflag. this controls whether local mode is enabled; which, if set, ignores modem control lines.
  • icanon β€” the ICANON bit of c_lflag. this is called "canonical" mode, and it controls whether the terminal's line-editing feature returns a whole line (if true), or whether individual bytes from keystrokes get returned as they become available (if false).
  • echo β€” the ECHO bit of c_lflag. this controls whether input characters are echoed back to the terminal.

🌟 setflags

$term->setflags( @flags );

since version 0.09. ✨

a convenient wrapper for calling multiple flag setting methods in a sequence. each flag is specified by name, in lower case, prefixed by either a + symbol to enable it, or - to disable it. for example:

$term->setflags( "+igncr", "+opost", "+clocal", "-echo" );

πŸ“ TODO πŸ“

  • Adding more getflag_*/setflag_* convenience wrappers

πŸ’€ SEE ALSO πŸ’€

  • IO::Tty - Import Tty control constants

🌸 AUTHOR 🌸

Paul Evans <leonerd@leonerd.org.uk>


and that's the whole page, bestie!! πŸ¦‹ this little beauty is from perl v5.38.2, dated 2024-07-28, and it lives at IO::Termios(3pm). go forth and talk to your serial ports responsibly πŸ’–βœ¨πŸŽ€πŸ«ΆπŸ‘‘

πŸ“¦ where this page comes from