Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Mar 2020 23:48:58 +0100
From:      Michael Osipov <1983-01-06@gmx.net>
To:        freebsd-questions@freebsd.org
Subject:   Behavior of stat(2) on /dev/stdin with redirected input
Message-ID:  <eeda9258-5bbe-ca9c-1df8-72d70d7cb9a1@gmx.net>

next in thread | raw e-mail | index | archive | help
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=3Dcr-xr-xr-x ,inode=3D3,size=3D0,bl=
ksize=3D4096 },0x0) =3D 0 (0x0)
> openat(AT_FDCWD,"/dev/stdin",O_RDONLY,00)    =3D 3 (0x3)
> ioctl(1,TIOCGWINSZ,0x7fffffffe7a0)       =3D 0 (0x0)
> write(1,"Archive:  /dev/stdin\n",21)         =3D 21 (0x15)
> lseek(3,0x0,SEEK_SET)                =3D 0 (0x0)
> read(3,0x800681000,0)                =3D 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 =3D 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=3D8557, st_ino=3D3, st_dev=3D1493237505, st_nlink=
=3D1, st_uid=3D0, st_gid=3D0, st_size=3D0, st_atime=3D1580763765, st_mtime=
=3D1580763765, st_ctime=3D1580763765)

Surprisingly on a RHEL 7 box:
>  python3 stat.py /dev/stdin < zip-test.jar
> -rw-r--r--
> os.stat_result(st_mode=3D33188, st_ino=3D1057848, st_dev=3D41, st_nlink=
=3D1, st_uid=3D722, st_gid=3D121, st_size=3D1921, st_atime=3D1583620033, s=
t_mtime=3D1566220183, st_ctime=3D1583523427)
>
> $ python3 stat.py /proc/self/fd/0 < zip-test.jar
> -rw-r--r--
> os.stat_result(st_mode=3D33188, st_ino=3D1057848, st_dev=3D41, st_nlink=
=3D1, st_uid=3D722, st_gid=3D121, st_size=3D1921, st_atime=3D1583620033, s=
t_mtime=3D1566220183, st_ctime=3D1583523427)
>
> $ python3 stat.py /dev/pts/0 < zip-test.jar
> crw--w----
> os.stat_result(st_mode=3D8592, st_ino=3D3, st_dev=3D12, st_nlink=3D1, st=
_uid=3D722, st_gid=3D5, st_size=3D0, st_atime=3D1583620976, st_mtime=3D158=
3620976, st_ctime=3D1583619302)

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/p=
ts/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/diff=
oscope/comparators/zip.py#L45-49



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?eeda9258-5bbe-ca9c-1df8-72d70d7cb9a1>