Perl problem - COM ports and filehandles

Nicholas Clark nick at ccl4.org
Thu Feb 2 11:05:18 GMT 2012


On Wed, Feb 01, 2012 at 11:59:17AM -0500, Darren Harwood wrote:
> good afternoon all,
> 
> me=long time lurker, first time poster!

It happens that there's a social meeting tonight near Euston station - you
could also come and lurk at that:

  http://london.pm.org/pipermail/london.pm-announce/2012-January/000266.html

(or not lurk, and claim a free beer (or beer-equivalent thing) if it's your
first time.)

> (warning! there is code in the post below - but as a first time poster i have no idea how well
> that is going to format itself for your consumption...we'll see....i apologise now if its a garbled mess.
> i did try to find posting advice on the london.pm website, but no joy)

Something like:

1) jobs go to the jobs list at jobs at london.pm.org
2) Perl is sometimes considered "Off Topic", as a joking reference to how
   much other chat is on the list.

?

Yes, there's not much advice.

> i am trying to convert a perl script from *nix to win32.
> i am having difficulty with a couple of things:
> 
> 1) the unix script opens a filehandle to a device like this:
> 
> open my $pipe, '+<', '/dev/ttyUSB0' or die "Couldn't open pipe for reading and writing";
> my $mb = myDevice::myObject->new($pipe);
> 
> this filehandle is then referenced in the module via a mechanism containing:
> my $rin = '';
> vec($rin,fileno($pipe),1) = 1;
> my ($nfound, $timeleft) = select($rin, undef, undef, $timeDelimiter_s);
> last if($nfound == 0);
> my $bytes;
> sysread($pipe, $bytes, $nfound);

The intent of that code looks to be doing non-blocking reads from the
serial port. And just the serial port - it's not using select to multiplex
between more than one input device.


> my (clearly incorrect) approach was to substitute the "open" for a use Win32::SerialPort; 
> (because the device is connected via a virtual serial port over usb)
> with the following:
> 
> my $PortObj = tie (*FH, 'Win32::SerialPort', $Configuration_File_Name) || die "Can't tie: $^E\n";
> 
> which i would expect to allow me to code:
> my $mb = myDevice::myObject->new(FH);
> 
> but perl complains about the FH bareword.
> using *FH in the new method allows the script to compile, but i am unsure of the impact!?!

*that* part should be fine, but.

> with my (dodgy?) *FH, i then hit the problem:
> Can't locate object method "FILENO" via package "Win32::SerialPort"
> when it hits the line:
> vec($rin,fileno($pipe),1) = 1;
> 
> and i go no further. i clearly dont have a valid filehandle in my FH at this point - but i'm not sure why
> or what alternate approach to use. (aside - how do i know if my "tied" filehandle is opened for input/output/both in this
> context?)
> i appreciate that the "vec" and "fileno" commands are quite rare (to me, they were brand spanky new) and primarily
> associated with low level tty operations - so perhaps they dont work the same on win32 as *nix?
> 
> thoughts on equivalent code?

Right. I don't know Win32 at all. But from what I can infer the Unix code
is looking to read data from the serial port when data is available, but
not block when it is not. It's using file handles and select() as the
mechanism to do this. From the code you give I don't think that they are
only an implementation detail.

The fact that Win32::SerialPort provides a *tied* file handle strongly
suggests that it's only emulating a file handle interface for compatibility.
I don't think your code needs to use file handles, as I'm guessing that they
aren't exposed externally. The documentation for Win32::SerialPort seems,
um, big: https://metacpan.org/module/Win32::SerialPort

but skimming it I can see that there's reference to non-blocking reads.
I think you need to look to see what API Win32::SerialPort provides to
do a non-blocking read natively, and use that.


I have no idea about the answer to your other question.

Nicholas Clark


More information about the london.pm mailing list