Skip to content

createDirectory: permission denied

The following program results in an odd "permission denied" error from createDirectory on Windows. It is derived from the createDirectoryIfMIssing001 test, but doesn't involve calling createDirectoryIfMissing, only createDirectory.

There are two threads, each of which is repeatedly creating a directory and using removeDirectoryRecursive to remove it.

Test program:

import System.IO
import System.Directory
import Control.Monad
import Control.Concurrent
import Control.Exception
import System.IO.Error

testdir = "foo"

main = do
  cleanup
  m <- newEmptyMVar
  forkIO $ do replicateM_ 1000 (do create; cleanup); putMVar m ()
  forkIO $ do replicateM_ 1000 (do create; cleanup); putMVar m ()
  replicateM_ 2 $ takeMVar m
  cleanup

create =
  tryJust (guard . isAlreadyExistsError) $ createDirectory testdir

cleanup =
  tryJust (guard . isDoesNotExistError) $ removeDirectoryRecursive testdir

The result is usually:

test.exe: CreateDirectory: permission denied (Access is denied.)

It's not clear (to me at least) why we get this error. Running the program under !ProcMon shows that there is a CreateFile call that returns DELETE PENDING, but as far as I can tell this doesn't give rise to an ERROR_DELETE_PENDING return from CreateDirectory, because that would give a different error message. Perhaps somewhere in the bowels of the Win32 API a DELETE_PENDING is being turned into a permission denied, or something.

This deserves investigation, because I think it might be related to other spurious "permission denied" errors we occasionally see on Windows.

Trac metadata
Trac field Value
Version 6.10.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/directory
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information