Behavior of stat(2) on /dev/stdin with redirected input

Michael Osipov 1983-01-06 at gmx.net
Sat Mar 7 22:49:04 UTC 2020


Folks,

I am currently analyzing an issue with sysutils/py-diffoscope which
relies on zipinfo/unzip -Z.

It does execute "zipinfo /dev/stdin" [1] and the file in question is
redirected to stdin. The shell equivalent is "zipinfo /dev/stdin <
file.zip" Sadly, this fails:

> fstatat(AT_FDCWD,"/dev/stdin",{ mode=cr-xr-xr-x ,inode=3,size=0,blksize=4096 },0x0) = 0 (0x0)
> openat(AT_FDCWD,"/dev/stdin",O_RDONLY,00)    = 3 (0x3)
> ioctl(1,TIOCGWINSZ,0x7fffffffe7a0)       = 0 (0x0)
> write(1,"Archive:  /dev/stdin\n",21)         = 21 (0x15)
> lseek(3,0x0,SEEK_SET)                = 0 (0x0)
> read(3,0x800681000,0)                = 0 (0x0)

Read unzip's ugly source code and it does read st_size from the stat
struct which is zero for the character file. A quick prototype in Python
confirms this:
> $ cat stat.py
> import os, stat, sys
> stat2 = os.stat(sys.argv[1])
> print(stat.filemode(stat2.st_mode))
> print(stat2)
>
> $ python3 stat.py /dev/stdin < zip-test.jar
> cr-xr-xr-x
> os.stat_result(st_mode=8557, st_ino=3, st_dev=1493237505, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1580763765, st_mtime=1580763765, st_ctime=1580763765)

Surprisingly on a RHEL 7 box:
>  python3 stat.py /dev/stdin < zip-test.jar
> -rw-r--r--
> os.stat_result(st_mode=33188, st_ino=1057848, st_dev=41, st_nlink=1, st_uid=722, st_gid=121, st_size=1921, st_atime=1583620033, st_mtime=1566220183, st_ctime=1583523427)
>
> $ python3 stat.py /proc/self/fd/0 < zip-test.jar
> -rw-r--r--
> os.stat_result(st_mode=33188, st_ino=1057848, st_dev=41, st_nlink=1, st_uid=722, st_gid=121, st_size=1921, st_atime=1583620033, st_mtime=1566220183, st_ctime=1583523427)
>
> $ python3 stat.py /dev/pts/0 < zip-test.jar
> crw--w----
> os.stat_result(st_mode=8592, st_ino=3, st_dev=12, st_nlink=1, st_uid=722, st_gid=5, st_size=0, st_atime=1583620976, st_mtime=1583620976, st_ctime=1583619302)

The behavior on RHEL 7 looks erractic too as if it is replacing the stat
struct of /dev/stdin with the stat truct of zip-test.jar although:
> $ ll /dev/stdin
> lrwxrwxrwx. 1 root root 15 2020-02-20 12:15 /dev/stdin -> /proc/self/fd/0
>
> $ ll /proc/self/fd/0
> lrwx------. 1 osipovmi cad 64 2020-03-07 23:15 /proc/self/fd/0 -> /dev/pts/0
>
> $ ll /dev/pts/0
> crw--w----. 1 osipovmi tty 136, 0 2020-03-07 23:15 /dev/pts/0

I am on
> 12.1-STABLE #5 r357318

unzip is from ports.

Can someone explain this behavior on FreeBSD? Any help is appreciated.
If this is expected behavior I will file an issue with diffoscope
upstream because the code is not portable.

Michael

[1]
https://salsa.debian.org/reproducible-builds/diffoscope/-/blob/master/diffoscope/comparators/zip.py#L45-49


More information about the freebsd-questions mailing list