develooper Front page | perl.perl5.porters | Postings from July 2011

[perl #94034] perlio and stdio inconsistent about "wrong way" fd open

From:
Nicholas Clark
Date:
July 4, 2011 02:55
Subject:
[perl #94034] perlio and stdio inconsistent about "wrong way" fd open
Message ID:
rt-3.6.HEAD-16080-1309773314-97.94034-75-0@perl.org
# New Ticket Created by  Nicholas Clark 
# Please include the string:  [perl #94034]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=94034 >



This is a bug report for perl from nick@ccl4.org,
generated with the help of perlbug 1.39 running under perl 5.15.0.


-----------------------------------------------------------------
[Please describe your issue here]

$ PERLIO=stdio ./perl -le 'open B, "<&1" or die $!' >/dev/null
Invalid argument at -e line 1.
$ ./perl -le 'open B, "<&1" or die $!' >/dev/null 
$

as perlio is the default, I could write that as:

$ PERLIO=perlio ./perl -le 'open B, "<&1" or die $!' >/dev/null
$

I don't think that they should differ in behaviour. 

The above is repeatable on at least Linux, FreeBSD and OS X, so my hunch is
that it's going to be fairly common across different *nix stdio
implementations.

The difference is because the stdio library uses fcntl() to determine the
file handle's direction, and fails the open if the requested stdio mode is
nonsensical.

Linux:

dup(1)                                  = 3
fcntl64(3, F_GETFL)                     = 0x8001 (flags O_WRONLY|O_LARGEFILE)
close(3)                                = 0
write(2, "Invalid argument at -e line 1.\n", 31Invalid argument at -e line 1.
) = 31

FreeBSD:

 19880 perl     CALL  dup(0x1)
 19880 perl     RET   dup 3
 19880 perl     CALL  fcntl(0x3,F_GETFL,0)
 19880 perl     RET   fcntl 1
 19880 perl     CALL  close(0x3)
 19880 perl     RET   close 0
 19880 perl     CALL  write(0x2,0x800e08430,0x1f)
 19880 perl     GIO   fd 2 wrote 31 bytes
       "Invalid argument at -e line 1.
       "

PerlIO doesn't:

dup(1)                                  = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfaf1358) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR)            = 0
fstat64(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0

 19990 perl     CALL  dup(0x1)
 19990 perl     RET   dup 3
 19990 perl     CALL  ioctl(0x3,TIOCGETA,0x7fffffffe4e0)
 19990 perl     RET   ioctl -1 errno 25 Inappropriate ioctl for device
 19990 perl     CALL  lseek(0x3,0,SEEK_CUR)
 19990 perl     RET   lseek 0
 19990 perl     CALL  fstat(0x3,0x6b8300)
 19990 perl     STRU  struct stat {dev=33619712, ino=8, mode=crw-rw-rw- , nlink=1, uid=0, gid=0, rdev=8, atime=1309741384, stime=1309772705, ctime=1309772705, birthtime=-1, size=0, blksize=4096, blocks=0, flags=0x0 }
 19990 perl     RET   fstat 0
 19990 perl     CALL  fcntl(0x3,F_SETFD,FD_CLOEXEC)
 19990 perl     RET   fcntl 0


My initial feeling is that PerlIO should do the fnctl() check [on any POSIX
platform], as F_GETFL is standard POSIX.

Nicholas Clark

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
    category=core
    severity=low
---
Site configuration information for perl 5.15.0:

Configured by nick at Wed Jun 22 12:46:38 BST 2011.

Summary of my perl5 (revision 5 version 15 subversion 0) configuration:
  Commit id: d220eb00ef3acc7b8eb92c164c58ff946a556955
  Platform:
    osname=linux, osvers=2.6.32-5-686-bigmem, archname=i686-linux
    uname='linux ceres 2.6.32-5-686-bigmem #1 smp wed may 18 07:33:52 utc 2011 i686 gnulinux '
    config_args='-Dusedevel=y -Dcc=ccache gcc -Dld=gcc -Ubincompat5005 -Uinstallusrbinperl -Dcf_email=nick@ccl4.org -Dperladmin=nick@ccl4.org -Dinc_version_list=  -Dinc_version_list_init=0 -UDEBUGGING -Doptimize=-Os -Uusethreads -Uuselongdouble -Uuse64bitall -Uusemymalloc -Duseperlio -Dprefix=~/Sandpit/snap5.9.x-v5.15.0-50-gd220eb0 -Uusevendorprefix -Uvendorprefix=~/Sandpit/snap5.9.x-v5.15.0-50-gd220eb0 -Dinstallman1dir=none -Dinstallman3dir=none -Uuserelocatableinc -Umad -Dnoextensions=IPC/SysV -de'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='ccache gcc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-Os',
    cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.4.5', 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 =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib/../lib /usr/lib/../lib /lib /usr/lib /lib64 /usr/lib64
    libs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/lib/libc-2.11.2.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.11.2'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -Os -L/usr/local/lib -fstack-protector'

Locally applied patches:
    

---
@INC for perl 5.15.0:
    lib
    /home/nick/Sandpit/snap5.9.x-v5.15.0-50-gd220eb0/lib/perl5/site_perl/5.15.0/i686-linux
    /home/nick/Sandpit/snap5.9.x-v5.15.0-50-gd220eb0/lib/perl5/site_perl/5.15.0
    /home/nick/Sandpit/snap5.9.x-v5.15.0-50-gd220eb0/lib/perl5/5.15.0/i686-linux
    /home/nick/Sandpit/snap5.9.x-v5.15.0-50-gd220eb0/lib/perl5/5.15.0
    .

---
Environment for perl 5.15.0:
    HOME=/home/nick
    LANG (unset)
    LANGUAGE=en_GB:en
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/nick/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/sbin:/sbin:/usr/sbin
    PERL_BADLANG (unset)
    SHELL=/bin/bash




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About