Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re^4: reading from a file after a seek isn't working for me

by jakobi (Pilgrim)
on Oct 21, 2009 at 22:46 UTC ( [id://802557]=note: print w/replies, xml ) Need Help??


in reply to Re^3: reading from a file after a seek isn't working for me
in thread reading from a file after a seek isn't working for me

Thanx for the pointer, almut. That dup & perlio scrap is interesting.

But there must be more to it than that, as I don't see any special treatment for STDOUT in the perlio.c scrap (neither for the numeric FD's 0 to 2):

I was playing with the scrap below in the meantime.

I dupped SAVOUT on STDERR instead / simplifying system to printing / using autoflush / opening STDOUT myself to /dev/tty first: no change.

This however is interesting:

Changing the name of the handle STDOUT <=> ANYTHINGeLSE manages to act as a toggle for the problem. Furthermore, w/o close, the tell on the STDOUT file pointer at begin prints 19 in the example below (might be due to the handle earlier being a tty, and something didn't quite catch the change to a plain file w/o explicit close?). Any other handle name prints 5 regardless of close or no close.

So it looks like we have some hard-coded STDOUT-related magic somewhere in the guts of PERLIO or even lower, with probably STDIN/ERR offering similar peculiarities.

use IO::Handle; open(SAVOUT, '>&STDERR') or die $!; #open(SAVOUT, '>&STDOUT') or die $!; # play with these: # s/STDOUT/STDOUT/; s/STDOUT/STDOUT/ close STDOUT; open(STDOUT, '>>', "/dev/tty"); STDOUT->autoflush; print STDOUT "a STDOUT test\n"; # play with this: # close STDOUT; open(STDOUT, '+>', "/tmp/STDOUT.log") or die $!; STDOUT->autoflush; print STDOUT "test\n"; #system("echo hello world"); print SAVOUT "before=", tell(STDOUT), "\n"; seek(STDOUT, 0, 0) or die $!; print SAVOUT "after=", tell(STDOUT), "\n"; while (1) { my $rv = read STDOUT, $_, 8192; die "read: $!\n" if !defined($rv); last unless $_; print SAVOUT "STDOUT=", $_; } print SAVOUT "at end=", tell(STDOUT), "\n"; close STDOUT;

Given that too much in Perl, esp wrt <> and stdio is magic, it's probably a good idea to say strictly outside any possibly dusty corner whose smell is faintly related to something magic. Which in this case might just be the idea of reusing a special handle, and worse, reading from it.

How to classify this behaviour: What doc/code do we still miss? Or is this indeed, say, an easy-to-fix oversight in the documentation? Or is it a somewhat larger actual bug?

Still wondering (& vowing to step even more cautiously anywhere near STDIO magic),
My thanx to almut & ikegami for the work below!
less confused now (& busy scribbling away two new-to-me debugging tips along with a link to their demonstration here)
Peter

Replies are listed 'Best First'.
Re^5: reading from a file after a seek isn't working for me
by almut (Canon) on Oct 21, 2009 at 23:23 UTC
    ...as I don't see any special treatment for STDOUT in the perlio.c scrap

    Just to be clear: the perlio.c snippet was only meant to show where the PerlIOValid() check happens for the read.  The decision between using a direct close vs. the indirect dup2, OTOH, is more likely to happen in Perl's open implementation (which I didn't yet have time to wade through — it's rather lengthy...  and for a low-depth explanation I figured the manifestation of the difference in the strace should be sufficient evidence).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://802557]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-04-25 19:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found