File Coverage

blib/lib/IO/Termios.pm
Criterion Covered Total %
statement 101 209 48.3
branch 13 88 14.7
condition 0 6 0.0
subroutine 29 55 52.7
pod 13 13 100.0
total 156 371 42.0


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2008-2018 -- leonerd@leonerd.org.uk
5              
6             package IO::Termios;
7              
8 2     2   76002 use v5.10;
  2         18  
9 2     2   10 use strict;
  2         4  
  2         52  
10 2     2   11 use warnings;
  2         4  
  2         57  
11 2     2   19 use base qw( IO::Handle );
  2         3  
  2         1162  
12              
13 2     2   12756 use Carp;
  2         5  
  2         122  
14              
15             our $VERSION = '0.09';
16              
17 2     2   12 use Exporter ();
  2         4  
  2         36  
18              
19 2     2   9 use Fcntl qw( O_RDWR );
  2         4  
  2         117  
20 2     2   1146 use POSIX qw( TCSANOW );
  2         12948  
  2         11  
21 2     2   3869 use IO::Tty;
  2         11381  
  2         8  
22 2         413 use IO::Tty::Constant qw(
23             TIOCMGET TIOCMSET TIOCMBIC TIOCMBIS
24             TIOCM_DTR TIOCM_DSR TIOCM_RTS TIOCM_CTS TIOCM_CD TIOCM_RI
25 2     2   300 );
  2         4  
26              
27             # Linux can support finer-grained control of baud rates if we let it
28 2     2   17 use constant HAVE_LINUX_TERMIOS2 => eval { require Linux::Termios2; };
  2         4  
  2         4  
  2         2829  
29              
30             =head1 NAME
31              
32             C - supply F methods to C objects
33              
34             =head1 SYNOPSIS
35              
36             use IO::Termios;
37              
38             my $term = IO::Termios->open( "/dev/ttyS0", "9600,8,n,1" )
39             or die "Cannot open ttyS0 - $!";
40              
41             $term->print( "Hello world\n" ); # Still an IO::Handle
42              
43             while( <$term> ) {
44             print "A line from ttyS0: $_";
45             }
46              
47             =head1 DESCRIPTION
48              
49             This class extends the generic C object class by providing methods
50             which access the system's terminal control C operations. These
51             methods are primarily of interest when dealing with TTY devices, including
52             serial ports.
53              
54             The flag-setting methods will apply to any TTY device, such as a pseudo-tty,
55             and are useful for controlling such flags as the C flag, to disable
56             local echo.
57              
58             my $stdin = IO::Termios->new( \*STDIN );
59             $stdin->setflag_echo( 0 );
60              
61             When dealing with a serial port the line mode method is useful for setting the
62             basic serial parameters such as baud rate, and the modem line control methods
63             can be used to access the hardware handshaking lines.
64              
65             my $ttyS0 = IO::Termios->open( "/dev/ttyS0" );
66             $ttyS0->set_mode( "19200,8,n,1" );
67             $ttyS0->set_modem({ dsr => 1, cts => 1 });
68              
69             =head2 Upgrading STDIN/STDOUT/STDERR
70              
71             If you pass the C<-upgrade> option at C time, any of STDIN, STDOUT or
72             STDERR that are found to be TTY wrappers are automatically upgraded into
73             C instances.
74              
75             use IO::Termios -upgrade;
76              
77             STDIN->setflag_echo(0);
78              
79             =head2 Arbitrary Baud Rates on Linux
80              
81             F supports a non-POSIX extension to the usual C interface,
82             which allows arbitrary baud rates to be set. C can automatically
83             make use of this ability if the L module is installed. If so,
84             this will be used automatically and transparently, to allow the C
85             methods to set any rate allowed by the kernel/driver. If not, then only the
86             POSIX-compatible rates may be used.
87              
88             =cut
89              
90             sub import
91             {
92 2     2   25 my $pkg = shift;
93 2         4 my @symbols = @_;
94 2         6 my $caller = caller;
95              
96 2         3 my $upgrade;
97 2 0       4 @symbols = grep { $_ eq "-upgrade" ? ( $upgrade++, 0 ) : 1 } @symbols;
  0         0  
98              
99 2 50       52 if( $upgrade ) {
100 0         0 foreach my $fh ( *STDIN{IO}, *STDOUT{IO}, *STDERR{IO} ) {
101 0 0       0 IO::Termios::Attrs->new->getattr( $fh->fileno ) or next;
102              
103 0         0 bless $fh, __PACKAGE__;
104             }
105             }
106             }
107              
108             =head1 CONSTRUCTORS
109              
110             =cut
111              
112             =head2 new
113              
114             $term = IO::Termios->new()
115              
116             Construct a new C object around the terminal for the program.
117             This is found by checking if any of C, C or C are a
118             terminal. The first one that's found is used. An error occurs if no terminal
119             can be found by this method.
120              
121             =head2 new (handle)
122              
123             $term = IO::Termios->new( $handle )
124              
125             Construct a new C object around the given filehandle.
126              
127             =cut
128              
129             sub new
130             {
131 1     1 1 1583 my $class = shift;
132 1         3 my ( $handle ) = @_;
133              
134 1 50       6 if( not $handle ) {
135             # Try to find a terminal - STDIN, STDOUT, STDERR are good candidates
136 0 0       0 return $class->SUPER::new_from_fd( fileno STDIN, "w+" ) if -t STDIN;
137 0 0       0 return $class->SUPER::new_from_fd( fileno STDOUT, "w+" ) if -t STDOUT;
138 0 0       0 return $class->SUPER::new_from_fd( fileno STDERR, "w+" ) if -t STDERR;
139              
140 0         0 die "TODO: Need to find a terminal\n";
141             }
142              
143 1 50       14 croak '$handle is not a filehandle' unless defined fileno $handle;
144              
145 1         9 my $self = $class->SUPER::new_from_fd( $handle, "w+" );
146              
147 1         117 return $self;
148             }
149              
150             =head2 open
151              
152             $term = IO::Termios->open( $path, $modestr, $flags )
153              
154             Open the given path, and return a new C object around the
155             filehandle. If the C call fails, C is returned.
156              
157             If C<$modestr> is provided, the constructor will pass it to the C
158             method before returning.
159              
160             If C<$flags> is provided, it will be passed on to the underlying C
161             call used to open the filehandle. It should contain a bitwise-or combination
162             of C flags from the L module - for example C or
163             C. The value C will be added to this; the caller does not
164             need to specify it directly. For example:
165              
166             use Fcntl qw( O_NOCTTY O_NDELAY );
167              
168             $term = IO::Termios->open( "/dev/ttyS0", O_NOCTTY|O_NDELAY );
169             $term->setflag_clocal( 1 );
170             $term->blocking( 1 );
171              
172             =cut
173              
174             sub open
175             {
176 0     0 1 0 my $class = shift;
177 0         0 my ( $path, $modestr, $flags ) = @_;
178              
179 0   0     0 $flags //= 0;
180              
181 0 0       0 sysopen my $tty, $path, O_RDWR | $flags, or return undef;
182 0 0       0 my $self = $class->new( $tty ) or return undef;
183              
184 0 0       0 $self->set_mode( $modestr ) if defined $modestr;
185              
186 0         0 return $self;
187             }
188              
189             =head1 METHODS
190              
191             =cut
192              
193             =head2 getattr
194              
195             $attrs = $term->getattr
196              
197             Makes a C call on the underlying filehandle, and returns a
198             C object.
199              
200             If the C call fails, C is returned.
201              
202             =cut
203              
204             sub getattr
205             {
206 15     15 1 26 my $self = shift;
207              
208 15         39 my $attrs = IO::Termios::Attrs->new;
209 15 50       43 $attrs->getattr( $self->fileno ) or return undef;
210              
211 15         273 return $attrs;
212             }
213              
214             =head2 setattr
215              
216             $term->setattr( $attrs )
217              
218             Makes a C call on the underlying file handle, setting attributes
219             from the given C object.
220              
221             If the C call fails, C is returned. Otherwise, a true
222             value is returned.
223              
224             =cut
225              
226             sub setattr
227             {
228 6     6 1 10 my $self = shift;
229 6         11 my ( $attrs ) = @_;
230              
231 6         17 return $attrs->setattr( $self->fileno, TCSANOW );
232             }
233              
234             =head2 set_mode
235              
236             =head2 get_mode
237              
238             $term->set_mode( $modestr )
239              
240             $modestr = $term->get_mode
241              
242             Accessor for the derived "mode string", which is a comma-joined concatenation
243             of the baud rate, character size, parity mode, and stop size in a format such
244             as
245              
246             19200,8,n,1
247              
248             When setting the mode string, trailing components may be omitted meaning their
249             value will not be affected.
250              
251             =cut
252              
253             sub set_mode
254             {
255 0     0 1 0 my $self = shift;
256 0         0 my ( $modestr ) = @_;
257              
258 0         0 my ( $baud, $csize, $parity, $stop ) = split m/,/, $modestr;
259              
260 0         0 my $attrs = $self->getattr;
261              
262 0 0       0 $attrs->setbaud ( $baud ) if defined $baud;
263 0 0       0 $attrs->setcsize ( $csize ) if defined $csize;
264 0 0       0 $attrs->setparity( $parity ) if defined $parity;
265 0 0       0 $attrs->setstop ( $stop ) if defined $stop;
266              
267 0         0 $self->setattr( $attrs );
268             }
269              
270             sub get_mode
271             {
272 0     0 1 0 my $self = shift;
273              
274 0         0 my $attrs = $self->getattr;
275 0         0 return join ",",
276             $attrs->getibaud,
277             $attrs->getcsize,
278             $attrs->getparity,
279             $attrs->getstop;
280             }
281              
282             =head2 tiocmget
283              
284             =head2 tiocmset
285              
286             $bits = $term->tiocmget
287              
288             $term->tiocmset( $bits )
289              
290             Accessor for the modem line control bits. Takes or returns a bitmask of
291             values.
292              
293             =cut
294              
295             sub tiocmget
296             {
297 0     0 1 0 my $self = shift;
298              
299 0         0 my $bitstr = pack "i!", 0;
300 0 0       0 ioctl( $self, TIOCMGET, $bitstr ) or
301             croak "Cannot ioctl(TIOCMGET) - $!";
302              
303 0         0 return unpack "i!", $bitstr;
304             }
305              
306             sub tiocmset
307             {
308 0     0 1 0 my $self = shift;
309 0         0 my ( $bits ) = @_;
310              
311 0         0 my $bitstr = pack "i!", $bits;
312 0 0       0 ioctl( $self, TIOCMSET, $bitstr )
313             or croak "Cannot ioctl(TIOCMSET) - $!";
314             }
315              
316             =head2 tiocmbic
317              
318             =head2 tiocmbis
319              
320             $term->tiocmbic( $bits )
321              
322             $term->tiocmbis( $bits )
323              
324             Bitwise mutator methods for the modem line control bits. C will
325             clear just the bits provided and leave the others unchanged; C will
326             set them.
327              
328             =cut
329              
330             sub tiocmbic
331             {
332 0     0 1 0 my $self = shift;
333 0         0 my ( $bits ) = @_;
334              
335 0         0 my $bitstr = pack "i!", $bits;
336 0 0       0 ioctl( $self, TIOCMBIC, $bitstr )
337             or croak "Cannot ioctl(TIOCMBIC) - $!";
338             }
339              
340             sub tiocmbis
341             {
342 0     0 1 0 my $self = shift;
343 0         0 my ( $bits ) = @_;
344              
345 0         0 my $bitstr = pack "i!", $bits;
346 0 0       0 ioctl( $self, TIOCMBIS, $bitstr )
347             or croak "Cannot ioctl(TIOCMBIS) - $!";
348             }
349              
350             my %_bit2modem;
351             my %_modem2bit;
352             foreach (qw( dtr dsr rts cts cd ri )) {
353             my $bit = IO::Tty::Constant->${\"TIOCM_\U$_"};
354             $_bit2modem{$bit} = $_;
355             $_modem2bit{$_} = $bit;
356              
357             my $getmodem = sub {
358 0     0   0 my $self = shift;
359 0         0 return !!($self->tiocmget & $bit);
360             };
361             my $setmodem = sub {
362 0     0   0 my $self = shift;
363 0         0 my ( $set ) = @_;
364 0 0       0 $set ? $self->tiocmbis( $bit )
365             : $self->tiocmbic( $bit );
366             };
367              
368 2     2   16 no strict 'refs';
  2         10  
  2         625  
369             *{"getmodem_$_"} = $getmodem;
370             *{"setmodem_$_"} = $setmodem;
371             }
372              
373             =head2 get_modem
374              
375             $flags = $term->get_modem
376              
377             Returns a hash reference containing named flags corresponding to the modem
378             line control bits. Any bit that is set will yield a key in the returned hash
379             of the same name. The bit names are
380              
381             dtr dsr rts cts cd ri
382              
383             =cut
384              
385             sub get_modem
386             {
387 0     0 1 0 my $self = shift;
388 0         0 my $bits = $self->tiocmget;
389              
390             return +{
391 0 0       0 map { $bits & $_modem2bit{$_} ? ( $_ => 1 ) : () } keys %_modem2bit
  0         0  
392             };
393             }
394              
395             =head2 set_modem
396              
397             $term->set_modem( $flags )
398              
399             Changes the modem line control bit flags as given by the hash reference. Each
400             bit to be changed should be represented by a key in the C<$flags> hash of the
401             names given above. False values will be cleared, true values will be set.
402             Other flags will not be altered.
403              
404             =cut
405              
406             sub set_modem
407             {
408 0     0 1 0 my $self = shift;
409 0         0 my ( $flags ) = @_;
410              
411 0         0 my $bits = $self->tiocmget;
412 0         0 foreach ( keys %$flags ) {
413 0 0       0 my $bit = $_modem2bit{$_} or croak "Unrecognised modem line control bit $_";
414              
415 0 0       0 $flags->{$_} ? ( $bits |= $bit )
416             : ( $bits &= ~$bit );
417             }
418              
419 0         0 $self->tiocmset( $bits );
420             }
421              
422             =head2 getmodem_BIT
423              
424             =head2 setmodem_BIT
425              
426             $set = $term->getmodem_BIT
427              
428             $term->setmodem_BIT( $set )
429              
430             Accessor methods for each of the modem line control bits. A set of methods
431             exists for each of the named modem control bits given above.
432              
433             =head1 FLAG-ACCESSOR METHODS
434              
435             Theses methods are implemented in terms of the lower level methods, but
436             provide an interface which is more abstract, and easier to re-implement on
437             other non-POSIX systems. These should be used in preference to the lower ones.
438              
439             For efficiency, when getting or setting a large number of flags, it may be
440             more efficient to call C, then operate on the returned object,
441             before possibly passing it to C. The returned C
442             object supports the same methods as documented here.
443              
444             The following two sections of code are therefore equivalent, though the latter
445             is more efficient as it only calls C once.
446              
447             $term->setbaud( 38400 );
448             $term->setcsize( 8 );
449             $term->setparity( 'n' );
450             $term->setstop( 1 );
451              
452             Z<>
453              
454             my $attrs = $term->getattr;
455             $attrs->setbaud( 38400 );
456             $attrs->setcsize( 8 );
457             $attrs->setparity( 'n' );
458             $attrs->setstop( 1 );
459             $term->setattr( $attrs );
460              
461             However, a convenient shortcut method is provided for the common case of
462             setting the baud rate, character size, parity and stop size all at the same
463             time. This is C:
464              
465             $term->set_mode( "38400,8,n,1" );
466              
467             =cut
468              
469             =head2 getibaud
470              
471             =head2 getobaud
472              
473             =head2 setibaud
474              
475             =head2 setobaud
476              
477             =head2 setbaud
478              
479             $baud = $term->getibaud
480              
481             $baud = $term->getobaud
482              
483             $term->setibaud( $baud )
484              
485             $term->setobaud( $baud )
486              
487             $term->setbaud( $baud )
488              
489             Convenience accessors for the C and C. C<$baud> is an integer
490             directly giving the line rate, instead of one of the C> constants.
491              
492             =head2 getcsize
493              
494             =head2 setcsize
495              
496             $bits = $term->getcsize
497              
498             $term->setcsize( $bits )
499              
500             Convenience accessor for the C bits of C. C<$bits> is an
501             integer 5 to 8.
502              
503             =head2 getparity
504              
505             =head2 setparity
506              
507             $parity = $term->getparity
508              
509             $term->setparity( $parity )
510              
511             Convenience accessor for the C and C bits of C.
512             C<$parity> is C, C or C.
513              
514             =head2 getstop
515              
516             =head2 setstop
517              
518             $stop = $term->getstop
519              
520             $term->setstop( $stop )
521              
522             Convenience accessor for the C bit of C. C<$stop> is 1 or 2.
523              
524             =head2 cfmakeraw
525              
526             $term->cfmakeraw
527              
528             I
529              
530             Adjusts several bit flags to put the terminal into a "raw" mode. Input is
531             available a character at a time, echo is disabled, and all special processing
532             of input and output characters is disabled.
533              
534             =cut
535              
536             foreach my $name (qw( ibaud obaud csize parity stop )) {
537             my $getmethod = "get$name";
538             my $setmethod = "set$name";
539              
540 2     2   14 no strict 'refs';
  2         5  
  2         399  
541             *$getmethod = sub {
542 0     0   0 my ( $self ) = @_;
543 0 0       0 my $attrs = $self->getattr or croak "Cannot getattr - $!";
544 0         0 return $attrs->$getmethod;
545             };
546             *$setmethod = sub {
547 0     0   0 my ( $self, $val ) = @_;
548 0 0       0 my $attrs = $self->getattr or croak "Cannot getattr - $!";
549 0         0 $attrs->$setmethod( $val );
550 0 0       0 $self->setattr( $attrs ) or croak "Cannot setattr - $!";
551             };
552             }
553              
554             foreach my $method (qw( setbaud cfmakeraw )) {
555 2     2   17 no strict 'refs';
  2         4  
  2         440  
556             *$method = sub {
557 0     0   0 my $self = shift;
558 0 0       0 my $attrs = $self->getattr or croak "Cannot getattr - $!";
559 0         0 $attrs->$method( @_ );
560 0 0       0 $self->setattr( $attrs ) or croak "Cannot setattr - $!";
561             };
562             }
563              
564             =head2 getflag_I
565              
566             =head2 setflag_I
567              
568             $mode = $term->getflag_FLAG
569              
570             $term->setflag_FLAG( $mode )
571              
572             Accessors for various control flags. The following methods are defined for
573             specific flags:
574              
575             =head3 inlcr
576              
577             I
578              
579             The C bit of the C. This translates NL to CR on input.
580              
581             =head3 igncr
582              
583             I
584              
585             The C bit of the C. This ignores incoming CR characters.
586              
587             =head3 icrnl
588              
589             I
590              
591             The C bit of the C. This translates CR to NL on input, unless
592             C is also set.
593              
594             =head3 ignbrk
595              
596             I
597              
598             The C bit of the C. This controls whether incoming break
599             conditions are ignored entirely.
600              
601             =head3 brkint
602              
603             I
604              
605             The C bit of the C. This controls whether non-ignored
606             incoming break conditions result in a C signal being delivered to the
607             process. If not, such a condition reads as a nul byte.
608              
609             =head3 parmrk
610              
611             I
612              
613             The C bit of the C. This controls how parity errors and break
614             conditions are handled.
615              
616             =head3 opost
617              
618             I
619              
620             The C bit of the C. This enables system-specific
621             post-processing on output.
622              
623             =head3 cread
624              
625             The C bit of the C. This enables the receiver.
626              
627             =head3 hupcl
628              
629             The C bit of the C. This lowers the modem control lines after
630             the last process closes the device.
631              
632             =head3 clocal
633              
634             The C bit of the C. This controls whether local mode is
635             enabled; which if set, ignores modem control lines.
636              
637             =head3 icanon
638              
639             The C bit of C. This is called "canonical" mode and controls
640             whether the terminal's line-editing feature will be used to return a whole
641             line (if true), or if individual bytes from keystrokes will be returned as
642             they are available (if false).
643              
644             =head3 echo
645              
646             The C bit of C. This controls whether input characters are
647             echoed back to the terminal.
648              
649             =cut
650              
651             my @flags = (
652             # iflag
653             [ inlcr => qw( INLCR i ) ],
654             [ igncr => qw( IGNCR i ) ],
655             [ icrnl => qw( ICRNL i ) ],
656             [ ignbrk => qw( IGNBRK i ) ],
657             [ brkint => qw( BRKINT i ) ],
658             [ parmrk => qw( PARMRK i ) ],
659             # oflag
660             [ opost => qw( OPOST o ) ],
661             # cflag
662             [ cread => qw( CREAD c ) ],
663             [ clocal => qw( CLOCAL c ) ],
664             [ hupcl => qw( HUPCL c ) ],
665             # lflag
666             [ icanon => qw( ICANON l ) ],
667             [ echo => qw( ECHO l ) ],
668             );
669              
670             foreach ( @flags ) {
671             my ( $name ) = @$_;
672              
673             my $getmethod = "getflag_$name";
674             my $setmethod = "setflag_$name";
675              
676 2     2   14 no strict 'refs';
  2         4  
  2         741  
677             *$getmethod = sub {
678 9     9   114 my ( $self ) = @_;
679 9 50       18 my $attrs = $self->getattr or croak "Cannot getattr - $!";
680 9         33 return $attrs->$getmethod;
681             };
682             *$setmethod = sub {
683 4     4   3364 my ( $self, $set ) = @_;
684 4 50       44 my $attrs = $self->getattr or croak "Cannot getattr - $!";
685 4         34 $attrs->$setmethod( $set );
686 4 50       11 $self->setattr( $attrs ) or croak "Cannot setattr - $!";
687             };
688             }
689              
690             =head2 setflags
691              
692             $term->setflags( @flags )
693              
694             I
695              
696             A convenient wrapper to calling multiple flag setting methods in a sequence.
697              
698             Each flag is specified by name, in lower case, prefixed by either a C<+>
699             symbol to enable it, or C<-> to disable. For example:
700              
701             $term->setflags( "+igncr", "+opost", "+clocal", "-echo" );
702              
703             =cut
704              
705             sub setflags
706             {
707 2     2 1 1627 my $self = shift;
708 2         7 my @flags = @_;
709              
710 2 50       6 my $attrs = $self->getattr or croak "Cannot getattr - $!";
711              
712 2         6 foreach my $flag ( @flags ) {
713 6         9 my $sense = 1;
714 6 100       21 $sense = 0 if $flag =~ s/^-//;
715 6         17 $flag =~ s/^\+//;
716              
717 6         13 my $method = "setflag_$flag";
718 6         16 $attrs->$method( $sense );
719             }
720              
721 2 50       7 $self->setattr( $attrs ) or croak "Cannot setattr - $!";
722             }
723              
724             package # hide from CPAN
725             IO::Termios::Attrs;
726              
727 2     2   38 use Carp;
  2         6  
  2         163  
728 2         13 use POSIX qw(
729             CSIZE CS5 CS6 CS7 CS8 PARENB PARODD CSTOPB
730             IGNBRK BRKINT PARMRK ISTRIP INLCR IGNCR ICRNL IXON OPOST ECHO ECHONL ICANON ISIG IEXTEN
731 2     2   12 );
  2         4  
732             # IO::Tty has more B<\d> constants than POSIX has
733 2     2   311 use IO::Tty;
  2         4  
  2         17  
734              
735             # Simple XS-implemented classes tend not to respect subclassing
736             sub new
737             {
738 15     15   35 my $class = shift;
739 15         58 my $self = $class->SUPER::new;
740 15         21 bless $self, $class;
741 15         30 return $self;
742             }
743              
744             if( IO::Termios::HAVE_LINUX_TERMIOS2 ) {
745             our @ISA = qw( Linux::Termios2 );
746              
747             # baud is directly applicable
748             *getibaud = __PACKAGE__->can( 'getispeed' );
749             *getobaud = __PACKAGE__->can( 'getospeed' );
750              
751             *setibaud = __PACKAGE__->can( 'setispeed' );
752             *setobaud = __PACKAGE__->can( 'setospeed' );
753             }
754             else {
755             our @ISA = qw( POSIX::Termios );
756              
757             # baud needs converting to/from the speed_t constants
758              
759             my %_speed2baud = map { IO::Tty::Constant->${\"B$_"} => $_ }
760             qw( 0 50 75 110 134 150 200 300 600 1200 2400 4800 9600 19200 38400 57600 115200 230400 );
761             my %_baud2speed = reverse %_speed2baud;
762              
763 0     0   0 *getibaud = sub { $_speed2baud{ $_[0]->getispeed } };
764 0     0   0 *getobaud = sub { $_speed2baud{ $_[0]->getospeed } };
765              
766             *setibaud = sub {
767 0   0 0   0 $_[0]->setispeed( $_baud2speed{$_[1]} // die "Unrecognised baud rate" );
768             };
769             *setobaud = sub {
770 0   0 0   0 $_[0]->setospeed( $_baud2speed{$_[1]} // die "Unrecognised baud rate" );
771             };
772              
773             }
774              
775             sub setbaud
776             {
777 0     0   0 $_[0]->setibaud( $_[1] ); $_[0]->setobaud( $_[1] );
  0         0  
778             }
779              
780             foreach ( @flags ) {
781             my ( $name, $const, $member ) = @$_;
782              
783             $const = POSIX->$const();
784              
785             my $getmethod = "getflag_$name";
786             my $getflag = "get${member}flag";
787              
788             my $setmethod = "setflag_$name";
789             my $setflag = "set${member}flag";
790              
791 2     2   1050 no strict 'refs';
  2         4  
  2         1514  
792             *$getmethod = sub {
793 9     9   15 my ( $self ) = @_;
794 9         59 $self->$getflag & $const
795             };
796             *$setmethod = sub {
797 10     10   21 my ( $self, $set ) = @_;
798 10 100       74 $set ? $self->$setflag( $self->$getflag | $const )
799             : $self->$setflag( $self->$getflag & ~$const );
800             };
801             }
802              
803             sub getcsize
804             {
805 0     0     my $self = shift;
806 0           my $cflag = $self->getcflag;
807             return {
808             CS5, 5,
809             CS6, 6,
810             CS7, 7,
811             CS8, 8,
812 0           }->{ $cflag & CSIZE };
813             }
814              
815             sub setcsize
816             {
817 0     0     my $self = shift;
818 0           my ( $bits ) = @_;
819 0           my $cflag = $self->getcflag;
820              
821 0           $cflag &= ~CSIZE;
822             $cflag |= {
823             5, CS5,
824             6, CS6,
825             7, CS7,
826             8, CS8,
827 0           }->{ $bits };
828              
829 0           $self->setcflag( $cflag );
830             }
831              
832             sub getparity
833             {
834 0     0     my $self = shift;
835 0           my $cflag = $self->getcflag;
836 0 0         return 'n' unless $cflag & PARENB;
837 0 0         return 'o' if $cflag & PARODD;
838 0           return 'e';
839             }
840              
841             sub setparity
842             {
843 0     0     my $self = shift;
844 0           my ( $parity ) = @_;
845 0           my $cflag = $self->getcflag;
846              
847 0 0         $parity eq 'n' ? $cflag &= ~PARENB :
    0          
    0          
848             $parity eq 'o' ? $cflag |= PARENB|PARODD :
849             $parity eq 'e' ? ($cflag |= PARENB) &= ~PARODD :
850             croak "Unrecognised parity '$parity'";
851              
852 0           $self->setcflag( $cflag );
853             }
854              
855             sub getstop
856             {
857 0     0     my $self = shift;
858 0 0         return 2 if $self->getcflag & CSTOPB;
859 0           return 1;
860             }
861              
862             sub setstop
863             {
864 0     0     my $self = shift;
865 0           my ( $stop ) = @_;
866 0           my $cflag = $self->getcflag;
867              
868 0 0         $stop == 1 ? $cflag &= ~CSTOPB :
    0          
869             $stop == 2 ? $cflag |= CSTOPB :
870             croak "Unrecognised stop '$stop'";
871              
872 0           $self->setcflag( $cflag );
873             }
874              
875             sub cfmakeraw
876             {
877 0     0     my $self = shift;
878              
879             # Coped from bit manipulations in termios(3)
880 0           $self->setiflag( $self->getiflag & ~( IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON ) );
881 0           $self->setoflag( $self->getoflag & ~( OPOST ) );
882 0           $self->setlflag( $self->getlflag & ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN ) );
883 0           $self->setcflag( $self->getcflag & ~( CSIZE | PARENB ) | CS8 );
884             }
885              
886             =head1 TODO
887              
888             =over 4
889              
890             =item *
891              
892             Adding more getflag_*/setflag_* convenience wrappers
893              
894             =back
895              
896             =head1 SEE ALSO
897              
898             =over 4
899              
900             =item *
901              
902             L - Import Tty control constants
903              
904             =back
905              
906             =head1 AUTHOR
907              
908             Paul Evans
909              
910             =cut
911              
912             0x55AA;