[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Reading from a file by using its FD returns its contents only once

From: mike b
Subject: Reading from a file by using its FD returns its contents only once
Date: Mon, 31 Dec 2018 02:36:43 +0100

Configuration Information:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu'
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL
-DHAVE_CONFIG_H   -I.  -I../. -I.././include -I.././lib  -Wdate-time
-D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/build/bash-7fckc0/bash-4.4=.
-fstack-protector-strong -Wformat -Werror=format-security -Wall -no-pie
-Wno-parentheses -Wno-format-security
uname output: Linux debian9 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2
(2018-10-27) x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 4.4
Patch Level: 12
Release Status: release

I am not quite sure if this is a bug, but here's what I find as a bit odd

# modprobe zram num_devices=0
# exec {add}</sys/class/zram-control/hot_add
# read -r id <&"$add"; echo "$id"
# read -r id <&"$add"; echo "$id" # <- $id ends up empty, no data is read

# read -r id </sys/class/zram-control/hot_add; echo "$id"
# read -r id </sys/class/zram-control/hot_add; echo "$id"
# readlink -f "/proc/$$/fd/$add"

The above sysfs interface is used for creating a zram device by performing
a read on the hot_add file. The value that should be returned is the id of
the newly created device. In first instance file is opened by dynamically
allocating the fd to use "$add" (the fd) across reads instead of
referencing the file directly. But from the above example you can see that
$id is assigned an actual value only on first read. On every next one, $id
would become empty - when using $add, that is. However, when file is read
in a standard way, by using it directly, everything works as it should.

The above is just an example. Doing reads on any other regular file like
this yields same behavior:
# echo bla >./t
# exec 10<./t
# read -r <&10
# echo $REPLY
# read -r <&10
# echo $REPLY

Playing with something like:
# zram=/sys/class/zram/control/hot_add
# c=0; while  ((++c <= 3)); do read -r; echo "${REPLY:-NULL}"; done <"$zram"
also gets same results. In contrast to:
# c=0; while (( ++c <= 3 )); do read -r; echo "out: ${REPLY:-NULL}"; done
out: foo
out: foo
out: foo
which keeps reading from default stdin (terminal in this case) without any
hiccups (as expected).

So, considering all the above, any hints on why subsequent reads in these
scenarios don't get any data from a file would be really appreciated. :)

Same behavior is seen in 4.3.30 and 5.0 versions.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]