more useful options | |
PerlMonks |
Current Perl documentation can be found at perldoc.perl.org.
Here is our local, out-dated (pre-5.6) version:
This depends on which operating system your program is running on. In the case of Unix, the serial ports will be accessible through files in /dev; on other systems, the devices names will doubtless differ. Several problem areas common to all device interaction are the following
sysopen()
and
O_RDWR|O_NDELAY|O_NOCTTY
from the Fcntl module (part of the standard perl distribution). See
sysopen for more on this approach.
print DEV "atv1\012"; # wrong, for some devices print DEV "atv1\015"; # right, for some devices
Even though with normal text files, a ``\n'' will do the trick, there is still no unified scheme for terminating a line that is portable between Unix, DOS/Win, and Macintosh, except to terminate ALL line ends with ``\015\012'', and strip what you don't need from the output. This applies especially to socket I/O and autoflushing, discussed next.
print()
them, you'll want to autoflush that filehandle. You can use
select()
and the
$|
variable to control autoflushing (see perlvar/$
and select):
$oldh = select(DEV); $| = 1; select($oldh);
You'll also see code that does this without a temporary variable, as in
select((select(DEV), $| = 1)[0]);
Or if you don't mind pulling in a few thousand lines of code just because you're afraid of a little $| variable:
use IO::Handle; DEV->autoflush(1);
As mentioned in the previous item, this still doesn't work when using socket I/O between Unix and Macintosh. You'll need to hardcode your line terminators, in that case.
read()
or
sysread(),
you'll have to arrange for an alarm handler to provide a timeout (see
alarm). If you have a non-blocking open, you'll likely have a non-blocking read, which means you may have to use a 4-arg
select()
to determine whether
I/O is ready on that device (see
select.
While trying to read from his caller-id box, the notorious Jamie Zawinski <jwz@netscape.com>, after much gnashing of teeth and fighting with sysread, sysopen, POSIX's tcgetattr business, and various other functions that go bump in the night, finally came up with this:
sub open_modem { use IPC::Open2; my $stty = `/bin/stty -g`; open2( \*MODEM_IN, \*MODEM_OUT, "cu -l$modem_device -s2400 2>&1"); # starting cu hoses /dev/tty's stty settings, even when it has # been opened on a pipe... system("/bin/stty $stty"); $_ = <MODEM_IN>; chop; if ( !m/^Connected/ ) { print STDERR "$0: cu printed `$_' instead of `Connected'\n"; } }