Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
`encodeFile` does not truncate an existing file on Windows #178
Demo repository at https://github.com/mtolly/yaml-no-truncate
module Main where import qualified Data.Yaml as Y main :: IO () main = do Y.encodeFile "test-output" "this is a somewhat long string" Y.encodeFile "test-output" "this is shorter"
with this stack.yaml (pointed at current
resolver: lts-14.6 packages: - . extra-deps: - git: https://github.com/snoyberg/yaml.git commit: 485df7bb08d7ed17a0be363ff493ed27e77fda13 subdirs: [yaml, libyaml]
produces this file on Windows 7:
and this on macOS Mojave:
If I replace
@snoyberg it seems you're completely right. Line https://github.com/snoyberg/yaml/pull/91/files#diff-fe4d8812ce1a1d403f51795fa362f96bR618 is missing O_TRUNC. I'm not sure why it "works" on macOS, but fdopen("w") could assume O_TRUNC was already passed, so it could be getting confused. (According to docs, this shouldn't work correctly on Linux either).
Huh, interesting. Then I'm not sure what's going on.
@mtolly a great next step here would be a PR that reproduces this problem on CI. One concern I have is that you mention Windows 7 as the test OS, which is not a supported operating system (Microsoft has closed the support window), so I'd rather see a repro that we can see ourselves on a supported OS version.
Sure enough, it seems to be a regression in GHC 8.6. Sample code:
import System.Posix.Internals as Posix import Control.Exception import Data.Bits std_flags = Posix.o_NOCTTY output_flags = std_flags .|. Posix.o_CREAT .|. Posix.o_TRUNC write_flags = output_flags .|. Posix.o_WRONLY main = do writeFile "test.txt" "foobarbazbin" withFilePath "test.txt" $ \fp -> bracket (c_open fp write_flags 0o644) c_close print readFile "test.txt" >>= print
On Windows with GHC 8.6.5, this prints out
I'm going to try a workaround of removing the file before opening for GHC 8.6 and later on Windows.