Finding all used fileno's ?

D

Dean Arnold

I've got an app that calls an external
3rd party C lib that opens sockets, but doesn't expose the sockets
directly outside of the library. I want to use the fileno's
of those sockets in a Perl select(read,write,error,timeout) call.
so I need to discover the fileno's of the sockets.

Q: will something like the following do what I need
(esp. on both Win32 and *nix) ? The upper fileno limit
is arbitrary, and can probably be tuned as needed.

@fdary = ();
foreach (0..23) {
$fdary[$_] = 1, next
unless open FH, "<&$_";
close FH;
}

foreach (0..$#fdary) {
print "$_ is available\n"
if defined($fdary[$_]);
}

The idea would be to scan once before
calling the external lib to open a socket,
then scan again, skipping the entries we know are
already open. The difference between
pre- and post- sets of dup'able handles is
assumed to be the fileno's of the new sockets.

It seems to work for files openned via Perl, but are
the fileno's generated via Perl identical to the underlying OS's
file descriptors ? esp. for Win32 ?
Is there a way to do this with a zero-timeout select() or poll()
(ie, set the bitmask to all fileno's, then scan for any fileno's
which report errors ?)

Is there a simpler solution (other than lsof, which
AFAIK doesn't exist in Win32) ? Google didn't provide
any promising results.

TIA,
Dean Arnold
Presicient Corp.
www.presicient.com
 
N

Nicholas Dronen

DA> I've got an app that calls an external
DA> 3rd party C lib that opens sockets, but doesn't expose the sockets
DA> directly outside of the library. I want to use the fileno's
DA> of those sockets in a Perl select(read,write,error,timeout) call.
DA> so I need to discover the fileno's of the sockets.

DA> Q: will something like the following do what I need
DA> (esp. on both Win32 and *nix) ? The upper fileno limit
DA> is arbitrary, and can probably be tuned as needed.

DA> @fdary = ();
DA> foreach (0..23) {
DA> $fdary[$_] = 1, next
DA> unless open FH, "<&$_";
DA> close FH;
DA> }

DA> foreach (0..$#fdary) {
DA> print "$_ is available\n"
DA> if defined($fdary[$_]);
DA> }

I don't know whether this works on Win32, but fstat seems to be
a better approach than open on UNIX.

#!/usr/bin/perl
use POSIX qw/fstat/;
for (0 .. 25) {
print "$_ is open\n" if fstat $_;
}
$ ./fds
0 is open
1 is open
2 is open

DA> The idea would be to scan once before
DA> calling the external lib to open a socket,
DA> then scan again, skipping the entries we know are
DA> already open. The difference between
DA> pre- and post- sets of dup'able handles is
DA> assumed to be the fileno's of the new sockets.

DA> It seems to work for files openned via Perl, but are
DA> the fileno's generated via Perl identical to the underlying OS's
DA> file descriptors ? esp. for Win32 ?

In the above output, 0, 1 and 2 are stdin, stdout and stderr,
respectively. The filenos are correct and identical to filenos
that the operating system associates with the process. I think
perl's behavior is such that you should be able to test this yourself
and not worry too much about the details.

DA> Is there a way to do this with a zero-timeout select() or poll()
DA> (ie, set the bitmask to all fileno's, then scan for any fileno's
DA> which report errors ?)

You can only select(2) or poll(2) on "valid" file descriptors;
you'll get an EBADF if your file descriptor set contains a fileno
that's not yet open.

Regards,

Nicholas
 
L

Lawrence D¹Oliveiro

Nicholas Dronen said:
...t fstat seems to be
a better approach than open on UNIX.

#!/usr/bin/perl
use POSIX qw/fstat/;
for (0 .. 25) {
print "$_ is open\n" if fstat $_;
}
$ ./fds
0 is open
1 is open
2 is open

Clever approach, but you may want to raise the upper limit number. A
quick check of this Linux login session I have open shows fd number 255
open on the terminal device.

How did I discover this? By using procfs, of course. procfs is probably
a more efficient way of doing the same thing as above, but it's
Linux-specific.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,900
Latest member
Nell636132

Latest Threads

Top