#3231: Permission denied error with runProcess/openFile
-----------------------------+----------------------------------------------
  Reporter:  NeilMitchell    |          Owner:  simonmar        
      Type:  bug             |         Status:  new             
  Priority:  low             |      Milestone:  7.2.1           
 Component:  Runtime System  |        Version:  6.10.4          
Resolution:                  |       Keywords:                  
  Testcase:                  |      Blockedby:                  
Difficulty:  Unknown         |             Os:  Windows         
  Blocking:                  |   Architecture:  Unknown/Multiple
   Failure:  None/Unknown    |  
-----------------------------+----------------------------------------------

Comment(by claudio):

 The basic problem is, that you have to deal with fatal and non-fatal
 errors.

 The code in Win32/File.hsc regards non-fatal errors as fatal and the user
 doesn't have any chance to check if the error was indeed fatal because
 there's no way of getting the error code.

 See http://support.microsoft.com/kb/316609

 Here's a patch which fixes this problem for removeFile:

 {{{
 #!diff
  -- File operations
  ----------------------------------------------------------------

 +foreign import stdcall unsafe "windows.h Sleep"
 +  sleep_priv :: DWORD -> IO ()
 +
  deleteFile :: String -> IO ()
  deleteFile name =
    withTString name $ \ c_name ->
 -  failIfFalse_ (unwords ["DeleteFile",show name]) $
 -    c_DeleteFile c_name
 +    let
 +      retries = 20
 +      doDelete = c_DeleteFile c_name
 +      deleteFailed = errorWin (unwords ["DeleteFile",show name])
 +      when p s = if p then s else return ()
 +      unless p s = when (not p) s
 +      retryOrFail :: Int -> IO Bool -> IO ()
 +      retryOrFail times action = do
 +        ret <- action
 +        unless ret (do
 +                       when (times <= 0) deleteFailed
 +                       err_code <- getLastError
 +                       when (err_code /= (# const ERROR_SHARING_VIOLATION
 )) deleteFailed
 +                       sleep_priv 100 >> retryOrFail (times - 1) action)
 +    in
 +      retryOrFail retries doDelete
  foreign import stdcall unsafe "windows.h DeleteFileW"
    c_DeleteFile :: LPCTSTR -> IO Bool
 }}}

 This made gitit and darcs work under Windows for me.

 Just my 2 cents.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3231#comment:40>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to