STDIN inheritance during exec and difference between getc and sysread

Hi all!

I’ve accidentally found that “getc” and “sysread” behave differently
after “exec”
getc does not get remaining data from the STDIN but sysread does it

[email protected] ~ $
[email protected] ~ $
[email protected] ~ $ echo -n ab | ruby -e “p STDIN.getc; exec ‘ruby’,
‘-e’, ‘p STDIN.getc’”
“a”
nil
[email protected] ~ $
[email protected] ~ $ echo -n ab | ruby -e “p STDIN.sysread(1); exec
‘ruby’, ‘-e’, ‘p STDIN.sysread(1)’”
“a”
“b”
[email protected] ~ $
[email protected] ~ $
[email protected] ~ $

why so? where is “b” in the first case?

Dmitry B. [email protected] wrote:

“a”
why so? where is “b” in the first case?
getc uses Ruby I/O buffering in user space, so the process read
more bytes than it needed the first time getc was called.

Buffered I/O leads to surprises like this behavior across fork/exec.