hSetBuffering appears to do nothing
Summary
It seems that hSetBuffering
has almost none of the expected effects.
Sample code:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.ByteString (hPut)
import Data.Foldable (for_)
import System.IO
main = do
withBinaryFile "myfile" WriteMode $ \h -> do
hSetBuffering h (BlockBuffering (Just (1024 * 1024))) -- unexpectedly makes write syscalls smaller than 1 MiB
-- hSetBuffering h (BlockBuffering (Just (1024))) -- unexpectedly makes write syscalls larger than 1 KiB
-- hSetBuffering h LineBuffering -- unexpectedly flushes every `hPut
for_ [1..10000] $ \_ -> do
hPut h "abcdefghijklmn123456789"
On GHC 9.0.2
and 9.5.20220921
respectively on NixOS Linux, as described in the code comments:
- When I set a 1 MiB buffer, I continue to observe
write()
syscalls instrace
that are too small (8188 Bytes):write(4</home/niklas/src/haskell/hSetBuffering/myfile>, "abcdefghijklmn123456789abcdefghi"..., 8188) = 8188 write(4</home/niklas/src/haskell/hSetBuffering/myfile>, "abcdefghijklmn123456789abcdefghi"..., 8188) = 8188
- When I set a 1 KiB buffer, the same (now the writes are larger than desired).
- When I set
LineBuffering
, I observe that write syscalls are being done even though no\n
is encountered:write(4</home/niklas/src/haskell/hSetBuffering/myfile>, "abcdefghijklmn123456789", 23) = 23 write(4</home/niklas/src/haskell/hSetBuffering/myfile>, "abcdefghijklmn123456789", 23) = 23
Am I missing something?