Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.96k stars 555 forks source link

bug in fh pointers w/perlio on dup() #7017

Open p5pRT opened 20 years ago

p5pRT commented 20 years ago

Migrated from rt.perl.org#24818 (status was 'open')

Searchable as RT24818$

p5pRT commented 20 years ago

From stas@stason.org

Created by stas@stason.org

Consider the following short program​:

# using Symbol to support older perls use Symbol; for (1..2) {   my $dup = Symbol​::gensym();   open $dup\, "\<&DATA" or die "Can't dup DATA​: $!";   print "DATA​: " . tell(DATA) . "\n";   print "dup : " . tell($dup) . "\n";   #seek $dup\, tell(DATA)\, 0; # rewind to the beginning   \<$dup>; }

__DATA__ foo bar

w/o perlio we get​:

DATA​: 309 dup : 309 DATA​: 318 dup : 318

the DATA fh pointer is correctly moved along with 'dup' as per dup(2).

w/ perlio we get​:

DATA​: 309 dup : 309 DATA​: 309 dup : 313

the DATA fh pointer is frozen and doesn't get moved to the same pointer as the 'dup' fh.

as rgs quoted on irc​:

\ that's what my dup(2) manpage says \ "After successful return of dup or dup2\, the old   and new descriptors may be used interchangeably."

and Nicolas has followed up​:

\ problem (presumably) is that duping by file   number means that the original file handle has buffered   data\, while the new one does not. so underlying Unix fh   is not at the same file offset as the return from ftell   might lead you to think

This is observed with any perl 5.8.x

Perl Info ``` Flags: category=core severity=medium Site configuration information for perl v5.8.1: Configured by gb at Mon Sep 1 17:25:48 CEST 2003. Summary of my perl5 (revision 5.0 version 8 subversion 1) configuration: Platform: osname=linux, osvers=2.4.18-23mdksmp, archname=i386-linux-thread-multi uname='linux hp6.mandrakesoft.com 2.4.18-23mdksmp #1 smp fri aug 2 12:31:40 cest 2002 i686 unknown unknown gnulinux ' config_args='-des -Dinc_version_list=5.8.0/i386-linux-thread-multi 5.8.0 5.6.1 5.6.0 -Darchname=i386-linux -Dcc=gcc -Doptimize=-O2 -fomit-frame-pointer -pipe -march=i586 -mcpu=pentiumpro -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr -Dman3ext=3pm -Dcf_by=MandrakeSoft -Dmyhostname=localhost -Dperladmin=root@localhost -Dd_dosuid -Ud_csh -Duseshrplib -Dusethreads' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm', optimize='-O2 -fomit-frame-pointer -pipe -march=i586 -mcpu=pentiumpro ', cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing -I/usr/local/include -I/usr/include/gdbm' ccversion='', gccversion='3.3.1 (Mandrake Linux 9.2 3.3.1-1mdk)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='gcc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lndbm -lgdbm -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=/lib/libc-2.3.2.so, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.3.2' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.8.1/i386-linux-thread-multi/CORE' cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib' Locally applied patches: RC4 @INC for perl v5.8.1: /usr/lib/perl5/5.8.1/i386-linux-thread-multi /usr/lib/perl5/5.8.1 /usr/lib/perl5/site_perl/5.8.1/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.1 /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.1/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.1 /usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.0 /usr/lib/perl5/vendor_perl . Environment for perl v5.8.1: HOME=/home/stas LANG=en_GB LANGUAGE=en_GB:en LC_ADDRESS=en_CA LC_COLLATE=en_GB LC_CTYPE=en_GB LC_IDENTIFICATION=en_CA LC_MEASUREMENT=en_CA LC_MESSAGES=en_GB LC_MONETARY=en_CA LC_NAME=en_CA LC_NUMERIC=en_CA LC_PAPER=en_CA LC_TELEPHONE=en_CA LC_TIME=en_GB LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr//bin:/bin:/usr/bin:.:/usr/local/bin:/usr/X11R6/bin:/usr/games:/home/stas/bin:/home/stas/bin:/usr/local/bin:/usr/X11R6/bin:/usr/java/j2re1.4.0/bin/ PERLDOC_PAGER=less -R PERL_BADLANG (unset) SHELL=/bin/tcsh __________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:stas@stason.org http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com ```
p5pRT commented 19 years ago

From @smpeters

[stas - Mon Jan 05 15​:15​:57 2004]​:

This is a bug report for perl from stas@​stason.org\, generated with the help of perlbug 1.34 running under perl v5.8.1.

----------------------------------------------------------------- [Please enter your report here]

Consider the following short program​:

# using Symbol to support older perls use Symbol; for (1..2) { my $dup = Symbol​::gensym(); open $dup\, "\<&DATA" or die "Can't dup DATA​: $!"; print "DATA​: " . tell(DATA) . "\n"; print "dup : " . tell($dup) . "\n"; #seek $dup\, tell(DATA)\, 0; # rewind to the beginning \<$dup>; }

__DATA__ foo bar

w/o perlio we get​:

DATA​: 309 dup : 309 DATA​: 318 dup : 318

the DATA fh pointer is correctly moved along with 'dup' as per dup(2).

w/ perlio we get​:

DATA​: 309 dup : 309 DATA​: 309 dup : 313

the DATA fh pointer is frozen and doesn't get moved to the same pointer as the 'dup' fh.

as rgs quoted on irc​:

\ that's what my dup(2) manpage says \ "After successful return of dup or dup2\, the old and new descriptors may be used interchangeably."

and Nicolas has followed up​:

\ problem (presumably) is that duping by file number means that the original file handle has buffered data\, while the new one does not. so underlying Unix fh is not at the same file offset as the return from ftell might lead you to think

This is observed with any perl 5.8.x

I wondering if either case you have above is correct. On Linux\, I see the following...

steve@​kirk​:\~$ PERLIO=​:stdio perl rt_24818.pl DATA​: 279 dup : 287 DATA​: 279 dup : 287 steve@​kirk​:\~$ PERLIO=​:perlio perl rt_24818.pl DATA​: 279 dup : 279 DATA​: 279 dup : 283

According to dup(2)\, each file descriptor should be unique\, so the handling by :stdio seems to be fine.

Looking at the PERLIO_DEBUG output\, one thing sticks out\, but I don't know if it is incorrect. It appears that the :unix layer is sending the wrong parameters to PerlIOBase_dup.

For example\, with :stdio PerlIOBase_dup stdio f=3c00e214 o=3c00e210 param=0

with :perlio PerlIOBase_dup perlio f=3c00e214 o=3c00e210 param=0

with :mmap PerlIOBase_dup mmap f=3c00e214 o=3c00e210 param=0

with :unix PerlIOBase_dup unix f=3c00e214 o=3c00c980 param=0

On :unix\, the address of the original filehandle is not getting sent in. Maybe this is a bug\, maybe not. It is something to look into further though.

p5pRT commented 19 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 19 years ago

From stas@stason.org

Steve Peters via RT wrote​:

[stas - Mon Jan 05 15​:15​:57 2004]​:

This is a bug report for perl from stas@​stason.org\, generated with the help of perlbug 1.34 running under perl v5.8.1.

----------------------------------------------------------------- [Please enter your report here]

Consider the following short program​:

# using Symbol to support older perls use Symbol; for (1..2) { my $dup = Symbol​::gensym(); open $dup\, "\<&DATA" or die "Can't dup DATA​: $!"; print "DATA​: " . tell(DATA) . "\n"; print "dup : " . tell($dup) . "\n"; #seek $dup\, tell(DATA)\, 0; # rewind to the beginning \<$dup>; }

__DATA__ foo bar

w/o perlio we get​:

DATA​: 309 dup : 309 DATA​: 318 dup : 318

the DATA fh pointer is correctly moved along with 'dup' as per dup(2).

w/ perlio we get​:

DATA​: 309 dup : 309 DATA​: 309 dup : 313

the DATA fh pointer is frozen and doesn't get moved to the same pointer as the 'dup' fh.

as rgs quoted on irc​:

\ that's what my dup(2) manpage says \ "After successful return of dup or dup2\, the old and new descriptors may be used interchangeably."

and Nicolas has followed up​:

\ problem (presumably) is that duping by file number means that the original file handle has buffered data\, while the new one does not. so underlying Unix fh is not at the same file offset as the return from ftell might lead you to think

This is observed with any perl 5.8.x

I wondering if either case you have above is correct. On Linux\, I see the following...

steve@​kirk​:\~$ PERLIO=​:stdio perl rt_24818.pl DATA​: 279 dup : 287 DATA​: 279 dup : 287

I get the same with PERLIO=​:stdio as you do\, Steve. The w/o perlio test was with perl that had no perlio enabed. Here it is again​:

/tmp> env PERLIO=​:perlio perl-5.8.6-ithread xxx DATA​: 277 dup : 277 DATA​: 277 dup : 281 /tmp> env PERLIO=​:stdio perl-5.8.6-ithread xxx DATA​: 277 dup : 285 DATA​: 277 dup : 285 /tmp> perl-5.8.6-nouseperlio xxx DATA​: 277 dup : 277 DATA​: 285 dup : 285

-- __________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http​://stason.org/ mod_perl Guide ---> http​://perl.apache.org mailto​:stas@​stason.org http​://use.perl.org http​://apacheweek.com
http​://modperlbook.org http​://apache.org http​://ticketmaster.com