File Coverage

blib/lib/IO/Termios.pm
Criterion Covered Total %
statement 91 199 45.7
branch 9 82 10.9
condition 0 6 0.0
subroutine 28 54 51.8
pod 12 12 100.0
total 140 353 39.6


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   70907 use strict;
  2         14  
  2         56  
9 2     2   10 use warnings;
  2         4  
  2         47  
10 2     2   39 use 5.010; # //
  2         7  
11 2     2   11 use base qw( IO::Handle );
  2         3  
  2         1108  
12              
13 2     2   12392 use Carp;
  2         5  
  2         130  
14              
15             our $VERSION = '0.08';
16              
17 2     2   14 use Exporter ();
  2         3  
  2         45  
18              
19 2     2   9 use Fcntl qw( O_RDWR );
  2         4  
  2         85  
20 2     2   1062 use POSIX qw( TCSANOW );
  2         12414  
  2         11  
21 2     2   3731 use IO::Tty;
  2         10528  
  2         8  
22 2         421 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   260 );
  2         3  
26              
27             # Linux can support finer-grained control of baud rates if we let it
28 2     2   15 use constant HAVE_LINUX_TERMIOS2 => eval { require Linux::Termios2; };
  2         3  
  2         3  
  2         2647  
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   31 my $pkg = shift;
93 2         6 my @symbols = @_;
94 2         4 my $caller = caller;
95              
96 2         2 my $upgrade;
97 2 0       6 @symbols = grep { $_ eq "-upgrade" ? ( $upgrade++, 0 ) : 1 } @symbols;
  0         0  
98              
99 2 50       47 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 1358 my $class = shift;
132 1         3 my ( $handle ) = @_;
133              
134 1 50       4 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       4 croak '$handle is not a filehandle' unless defined fileno $handle;
144              
145 1         6 my $self = $class->SUPER::new_from_fd( $handle, "w+" );
146              
147 1         93 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 8     8 1 12 my $self = shift;
207              
208 8         22 my $attrs = IO::Termios::Attrs->new;
209 8 50       27 $attrs->getattr( $self->fileno ) or return undef;
210              
211 8         134 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 4     4 1 6 my $self = shift;
229 4         7 my ( $attrs ) = @_;
230              
231 4         10 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   13 no strict 'refs';
  2         4  
  2         908  
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         368  
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   21 no strict 'refs';
  2         5  
  2         396  
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_opost
565              
566             =head2 setflag_opost
567              
568             $mode = $term->getflag_opost
569              
570             $term->setflag_opost( $mode )
571              
572             I
573              
574             Accessor for the C bit of the C. This enables system-specific
575             post-processing on output.
576              
577             =head2 getflag_cread
578              
579             =head2 setflag_cread
580              
581             $mode = $term->getflag_cread
582              
583             $term->setflag_cread( $mode )
584              
585             Accessor for the C bit of the C. This enables the receiver.
586              
587             =head2 getflag_hupcl
588              
589             =head2 setflag_hupcl
590              
591             $mode = $term->getflag_hupcl
592              
593             $term->setflag_hupcl( $mode )
594              
595             Accessor for the C bit of the C. This lowers the modem control
596             lines after the last process closes the device.
597              
598             =head2 getflag_clocal
599              
600             =head2 setflag_clocal
601              
602             $mode = $term->getflag_clocal
603              
604             $term->setflag_clocal( $mode )
605              
606             Accessor for the C bit of the C. This controls whether local
607             mode is enabled; which if set, ignores modem control lines.
608              
609             =cut
610              
611             =head2 getflag_icanon
612              
613             =head2 setflag_icanon
614              
615             $mode = $term->getflag_icanon
616              
617             $term->setflag_icanon( $mode )
618              
619             Accessor for the C bit of C. This is called "canonical" mode
620             and controls whether the terminal's line-editing feature will be used to
621             return a whole line (if true), or if individual bytes from keystrokes will be
622             returned as they are available (if false).
623              
624             =cut
625              
626             =head2 getflag_echo
627              
628             =head2 setflag_echo
629              
630             $mode = $term->getflag_echo
631              
632             $term->setflag_echo( $mode )
633              
634             Accessor for the C bit of C. This controls whether input
635             characters are echoed back to the terminal.
636              
637             =cut
638              
639             my @flags = (
640             # oflag
641             [ opost => qw( OPOST o ) ],
642             # cflag
643             [ cread => qw( CREAD c ) ],
644             [ clocal => qw( CLOCAL c ) ],
645             [ hupcl => qw( HUPCL c ) ],
646             # lflag
647             [ icanon => qw( ICANON l ) ],
648             [ echo => qw( ECHO l ) ],
649             );
650              
651             foreach ( @flags ) {
652             my ( $name ) = @$_;
653              
654             my $getmethod = "getflag_$name";
655             my $setmethod = "setflag_$name";
656              
657 2     2   14 no strict 'refs';
  2         20  
  2         393  
658             *$getmethod = sub {
659 4     4   76 my ( $self ) = @_;
660 4 50       9 my $attrs = $self->getattr or croak "Cannot getattr - $!";
661 4         14 return $attrs->$getmethod;
662             };
663             *$setmethod = sub {
664 4     4   3294 my ( $self, $set ) = @_;
665 4 50       12 my $attrs = $self->getattr or croak "Cannot getattr - $!";
666 4         17 $attrs->$setmethod( $set );
667 4 50       12 $self->setattr( $attrs ) or croak "Cannot setattr - $!";
668             };
669             }
670              
671             package # hide from CPAN
672             IO::Termios::Attrs;
673              
674 2     2   33 use Carp;
  2         6  
  2         146  
675 2         20 use POSIX qw(
676             CSIZE CS5 CS6 CS7 CS8 PARENB PARODD CSTOPB
677             IGNBRK BRKINT PARMRK ISTRIP INLCR IGNCR ICRNL IXON OPOST ECHO ECHONL ICANON ISIG IEXTEN
678 2     2   14 );
  2         3  
679             # IO::Tty has more B<\d> constants than POSIX has
680 2     2   293 use IO::Tty;
  2         10  
  2         8  
681              
682             # Simple XS-implemented classes tend not to respect subclassing
683             sub new
684             {
685 8     8   12 my $class = shift;
686 8         32 my $self = $class->SUPER::new;
687 8         14 bless $self, $class;
688 8         23 return $self;
689             }
690              
691             if( IO::Termios::HAVE_LINUX_TERMIOS2 ) {
692             our @ISA = qw( Linux::Termios2 );
693              
694             # baud is directly applicable
695             *getibaud = __PACKAGE__->can( 'getispeed' );
696             *getobaud = __PACKAGE__->can( 'getospeed' );
697              
698             *setibaud = __PACKAGE__->can( 'setispeed' );
699             *setobaud = __PACKAGE__->can( 'setospeed' );
700             }
701             else {
702             our @ISA = qw( POSIX::Termios );
703              
704             # baud needs converting to/from the speed_t constants
705              
706             my %_speed2baud = map { IO::Tty::Constant->${\"B$_"} => $_ }
707             qw( 0 50 75 110 134 150 200 300 600 1200 2400 4800 9600 19200 38400 57600 115200 230400 );
708             my %_baud2speed = reverse %_speed2baud;
709              
710 0     0   0 *getibaud = sub { $_speed2baud{ $_[0]->getispeed } };
711 0     0   0 *getobaud = sub { $_speed2baud{ $_[0]->getospeed } };
712              
713             *setibaud = sub {
714 0   0 0   0 $_[0]->setispeed( $_baud2speed{$_[1]} // die "Unrecognised baud rate" );
715             };
716             *setobaud = sub {
717 0   0 0   0 $_[0]->setospeed( $_baud2speed{$_[1]} // die "Unrecognised baud rate" );
718             };
719              
720             }
721              
722             sub setbaud
723             {
724 0     0   0 $_[0]->setibaud( $_[1] ); $_[0]->setobaud( $_[1] );
  0         0  
725             }
726              
727             foreach ( @flags ) {
728             my ( $name, $const, $member ) = @$_;
729              
730             $const = POSIX->$const();
731              
732             my $getmethod = "getflag_$name";
733             my $getflag = "get${member}flag";
734              
735             my $setmethod = "setflag_$name";
736             my $setflag = "set${member}flag";
737              
738 2     2   1016 no strict 'refs';
  2         4  
  2         1418  
739             *$getmethod = sub {
740 4     4   7 my ( $self ) = @_;
741 4         34 $self->$getflag & $const
742             };
743             *$setmethod = sub {
744 4     4   9 my ( $self, $set ) = @_;
745 4 100       48 $set ? $self->$setflag( $self->$getflag | $const )
746             : $self->$setflag( $self->$getflag & ~$const );
747             };
748             }
749              
750             sub getcsize
751             {
752 0     0     my $self = shift;
753 0           my $cflag = $self->getcflag;
754             return {
755             CS5, 5,
756             CS6, 6,
757             CS7, 7,
758             CS8, 8,
759 0           }->{ $cflag & CSIZE };
760             }
761              
762             sub setcsize
763             {
764 0     0     my $self = shift;
765 0           my ( $bits ) = @_;
766 0           my $cflag = $self->getcflag;
767              
768 0           $cflag &= ~CSIZE;
769             $cflag |= {
770             5, CS5,
771             6, CS6,
772             7, CS7,
773             8, CS8,
774 0           }->{ $bits };
775              
776 0           $self->setcflag( $cflag );
777             }
778              
779             sub getparity
780             {
781 0     0     my $self = shift;
782 0           my $cflag = $self->getcflag;
783 0 0         return 'n' unless $cflag & PARENB;
784 0 0         return 'o' if $cflag & PARODD;
785 0           return 'e';
786             }
787              
788             sub setparity
789             {
790 0     0     my $self = shift;
791 0           my ( $parity ) = @_;
792 0           my $cflag = $self->getcflag;
793              
794 0 0         $parity eq 'n' ? $cflag &= ~PARENB :
    0          
    0          
795             $parity eq 'o' ? $cflag |= PARENB|PARODD :
796             $parity eq 'e' ? ($cflag |= PARENB) &= ~PARODD :
797             croak "Unrecognised parity '$parity'";
798              
799 0           $self->setcflag( $cflag );
800             }
801              
802             sub getstop
803             {
804 0     0     my $self = shift;
805 0 0         return 2 if $self->getcflag & CSTOPB;
806 0           return 1;
807             }
808              
809             sub setstop
810             {
811 0     0     my $self = shift;
812 0           my ( $stop ) = @_;
813 0           my $cflag = $self->getcflag;
814              
815 0 0         $stop == 1 ? $cflag &= ~CSTOPB :
    0          
816             $stop == 2 ? $cflag |= CSTOPB :
817             croak "Unrecognised stop '$stop'";
818              
819 0           $self->setcflag( $cflag );
820             }
821              
822             sub cfmakeraw
823             {
824 0     0     my $self = shift;
825              
826             # Coped from bit manipulations in termios(3)
827 0           $self->setiflag( $self->getiflag & ~( IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON ) );
828 0           $self->setoflag( $self->getoflag & ~( OPOST ) );
829 0           $self->setlflag( $self->getlflag & ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN ) );
830 0           $self->setcflag( $self->getcflag & ~( CSIZE | PARENB ) | CS8 );
831             }
832              
833             =head1 TODO
834              
835             =over 4
836              
837             =item *
838              
839             Adding more getflag_*/setflag_* convenience wrappers
840              
841             =back
842              
843             =head1 SEE ALSO
844              
845             =over 4
846              
847             =item *
848              
849             L - Import Tty control constants
850              
851             =back
852              
853             =head1 AUTHOR
854              
855             Paul Evans
856              
857             =cut
858              
859             0x55AA;