openFile gives "file is locked" error on Linux when creating a non-existing file

Viktor Dukhovni ietf-dane at dukhovni.org
Mon Oct 7 10:52:06 UTC 2024


On Mon, Oct 07, 2024 at 08:25:21AM +0530, Harendra Kumar wrote:

>             exists <- doesFileExist filepath
>             if not exists
>             then do
>                 putStrLn $ "Creating file: " ++ (parent </> file)
>                 openFile (parent </> file) WriteMode >>= hClose
>                 putStrLn $ "Created file: " ++ (parent </> file)
>             else error $ "File exists: " ++ filepath

This is a classic TOCTOU bug.  The file can come into existence between
the "doesFileExist" test and the attempt to create it.  To create a file
only if it does not exist, you need to use an "open" variant that
creates the file if necessary, and leaves it unmodified if it already
exists.  "AppendMode" works for this, because you're closing the file
immediately, so the fact that any writes would "append" is not material.

So replace the above with:

    openFile filepath AppendMode >>= hClose

If you need to know whether the file got created by this call, or was
found to exist already, you need a lower-level API, such as (Unix C):

    /* In some cases 0600 is more appropriate */
    int fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0666);

    if (fd >= 0) {
        /* Just created */
        (void) close(fd);
        ...
    } else if (errno == EEXIST) {
        /* Already present */
        ...
    } else {
        /* Permission or other problem */
        ...
    }

-- 
    Viktor.


More information about the ghc-devs mailing list