Skip to content

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
Edited by Kirill Elagin
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information