Handle seeked to the end after duplication and reading from the copy
Summary
Not sure if this is a bug report or more of a help (documentation?) request.
I expect the following program to work, but it doesn’t:
h <- openFile "/etc/passwd" ReadMode
h2 <- hDuplicate h
hGetLine h >>= putStrLn
hGetLine h2 >>= putStrLn
##
foo: /etc/passwd: hGetLine: end of file
The issue is that after I hDuplicate
a handle and try to read from one of the two, the other one apparently gets seeked to the end. If I seek it back to where I need, then it keeps working just fine:
λ> import System.IO
λ> import GHC.IO.Handle
λ> h <- openFile "/etc/passwd" ReadMode
λ> hGetLine h
"##"
λ> hGetLine h
"# User Database"
λ> hGetPosn h
{handle: /etc/passwd} at position 19
λ> h2 <- hDuplicate h
λ> hGetPosn h
{handle: /etc/passwd} at position 19
λ> hGetPosn h2
{handle: /etc/passwd} at position 19
λ> hGetLine h
"# "
λ> hGetPosn h2
{handle: /etc/passwd} at position 6946
λ> hSeek h2 AbsoluteSeek 0
λ> hGetPosn h2
{handle: /etc/passwd} at position 0
λ> hGetLine h
"# Note that this file is consulted directly only when the system is running"
λ> hGetPosn h2
{handle: /etc/passwd} at position 0
λ> hGetLine h2
"##"
λ> hGetLine h2
"# User Database"
The documentation for hDuplicate
mentions that it flushes the buffer before duplicating, which, IIUC, should not be externally observable, and, even more strangely, this seek to the end happens not on duplication, but after the first read.
Environment
- GHC version used: 8.6.5
Optional:
- Operating System: macOS