Francisco Zarabozo
Francisco Zarabozo

Reputation: 3749

How can I obtain a file handle from its fileno in Perl?

I'm working with a Perl script that uses threads and threads::shared. I want to read from a file handle that is opened by a separate thread, but threads::shared can't admit it as a value for a shared scalar.

I'm thinking maybe I can simply share the result of fileno to the other thread and then have it read it. The problem is that I don't know what to do with that number. If the answer is in the documentation, I'm probably not searching for the right thing as I haven't found it yet. How can I get an actual file handle from its fileno value?

If that's not possible, is there a way to open and pass a file handle to another thread after both threads are created?

Thanks in advance for any suggestions.

Upvotes: 3

Views: 730

Answers (2)

cjm
cjm

Reputation: 62109

Use open:

If you specify '<&=X', where X is a file descriptor number or a filehandle, then Perl will do an equivalent of C's fdopen of that file descriptor

my $fileno = 0;
open(my $stdin, "<&=$fileno");   # 2-argument form
open(my $stdin, "<&=", $fileno); # or use 3-argument form

If you prefer an object-oriented approach, you can use IO::File and the fdopen or new_from_fd methods (as Borodin pointed out):

use IO::File;
my $stdin = IO::File->new_from_fd($fileno, 'r');

Upvotes: 7

Borodin
Borodin

Reputation: 126732

As @cjm has said, you need to call fdopen on the file number.

But it is much more straightforward and more readable to use the fdopen method from IO::Handle.

It looks like this

my $fh = IO::File->new;
$fh->fdopen($fileno, 'r');

and note that IO::File (which subclasses IO::Handle) is loaded on demand with Perl 5 version 14 and later, so you don't need to use IO::File unless you have a very old Perl installation.

Upvotes: 3

Related Questions