Ticket #1874 (closed bug: fixed)

Opened 6 years ago

Last modified 2 years ago

getDirectoryContents yields "invalid argument" instead of "permission error"

Reported by: Orphi Owned by:
Priority: normal Milestone: _|_
Component: libraries/directory Version: 6.8.1
Keywords: Cc: fryguybob@…
Operating System: Windows Architecture: x86
Type of failure: None/Unknown Difficulty: Moderate (less than a day)
Test Case: getDirectoryContents "C:\\System Volume Information" Blocked By:
Blocking: Related Tickets:

Description

Attempting to open a file (readFile, openFile, et al) to which you do not have permission yields a permission exception. However, calling getDirectoryContents on a folder to which you do not have permission yields an "invalid argument" exception.

(Note that as per bug #1868, this particular exception is very hard to process.)

This behaviour occurs in GHC 6.6.1 and GHC 6.8.1 running on Windows XP. (I think I recall it also happening in GHC 6.6 on Windows NT as well, but I might be imagining that part.)

Change History

Changed 6 years ago by igloo

  • difficulty set to Unknown
  • milestone set to 6.10 branch

Thanks for the report. Fixing this means an interface change, so it can't happen until 6.10. Also, I wouldn't be surprised if we are just mirroring the error that the operating system gives us.

Changed 6 years ago by Orphi

Have I missed something? According to the documentation for getDirectoryContents, it should give a permission error if you don't have permission. Where do we require an interface change?

 http://haskell.org/ghc/docs/6.8.1/html/libraries/directory-1.0.0.0/System-Directory.html#v%3AgetDirectoryContents

As far as mirroring the OS... yeah, sadly I can believe that.

Changed 6 years ago by simonmar

  • difficulty changed from Unknown to Easy (1 hr)
  • component changed from libraries (other) to libraries/directory
  • milestone changed from 6.10 branch to 6.8.3

re-milestoning; it's a very minor interface change and can't cause compile-time breakage, so 6.8.3 is possible.

Changed 5 years ago by igloo

  • priority changed from normal to lowest

I can't get any exception at all out of getDirectoryContents on Windows.

$ cat q.hs

module Main (main) where

import Control.Exception
import Prelude hiding (catch)
import System.Directory

main :: IO ()
main = do
          (readFile "c:\\cygwin\\tmp\\ian\\noperm" >> return ()) `catch` print
          (getDirectoryContents "c:\\cygwin\\tmp\\ian\\npd" >> return ()) `catch` print
          putStrLn "Foo"
$ ls -l
total 643
----------  1 ian None      0 Apr 27 16:57 noperm
d---------+ 2 ian None      0 Apr 27 16:57 npd
-rwxr-xr-x  1 ian None 644760 Apr 27 16:59 q.exe
-rwxr-xr-x  1 ian None    498 Apr 27 16:59 q.exe.manifest
-rwxr-xr-x  1 ian None    305 Apr 27 16:57 q.hi
-rw-r--r--  1 ian None    324 Apr 27 16:59 q.hs
-rwxr-xr-x  1 ian None   5494 Apr 27 16:59 q.o
$ ./q.exe
c:\cygwin\tmp\ian\noperm: openFile: permission denied (Permission denied)
Foo

Can anyone tell me how I can reproduce the problem please?

Changed 5 years ago by Deewiant

What version of Windows are you using? This is on Windows XP Professional with Service Pack 2:

$ cat asdf.hs
module Main (main) where

import Control.Exception
import Prelude hiding (catch)
import System.Directory

main :: IO ()
main = do
          (getDirectoryContents "D:\\Main\\npd" >> return ()) `catch` print
          putStrLn "Foo"
$ ls -ld npd
d---------+ 2 Deewiant None 0 May  6 16:34 npd
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.8.2
$ ghc --make -fforce-recomp asdf
[1 of 1] Compiling Main             ( asdf.hs, asdf.o )
Linking asdf.exe ...
$ ./asdf.exe
D:\Main\npd: getDirectoryContents: invalid argument (Invalid argument)
Foo

Changed 5 years ago by igloo

XP Pro, according to the welcome screen.

Can you describe how you made the directory please?

Changed 5 years ago by Deewiant

One way is to use the Cygwin shell:

$ mkdir npd
$ chmod goa-rwx npd

The other way is to use the Windows GUI. In Windows Explorer: create the directory, view its Properties (via right-click or File menu), go to the Security tab, and set "Full Control" to "Deny" for all groups and user names (I think setting any one which applies to you is sufficient, but I set all just in case).

In either case, I get "invalid argument" out of getDirectoryContents.

Changed 5 years ago by simonmar

  • priority changed from lowest to low
  • milestone changed from 6.8.3 to 6.10 branch

This is really a bug in MinGW's readdir():

#include <dirent.h>
#include <errno.h>

main()
{
    DIR *pdir;
    struct dirent *pdirent;

    pdir = opendir("foo");
    printf("%x %d\n", pdir, errno);
    pdirent = readdir(pdir);
    printf("%x %d\n", pdirent, errno);
}

yields:

$ ls -ld foo
d---------+ 2 simonmar mkgroup-l-d 0 Jun  3 10:19 foo/
$ a.exe
3d2c48 0
0 22

where 22 is EINVAL. We should really be using the native Win32 API instead of MinGW here.

Changed 5 years ago by simonmar

  • difficulty changed from Easy (1 hr) to Moderate (1 day)

Changed 4 years ago by igloo

  • milestone changed from 6.10 branch to 6.12 branch

Changed 4 years ago by simonmar

  • difficulty changed from Moderate (1 day) to Moderate (less than a day)

Changed 3 years ago by igloo

  • milestone changed from 6.12 branch to 6.12.3

Changed 3 years ago by igloo

  • priority changed from low to normal
  • failure set to None/Unknown
  • milestone changed from 6.12.3 to _|_

Changed 2 years ago by fryguybob

  • cc fryguybob@… added
  • status changed from new to closed
  • resolution set to fixed

Looks like this was addressed with the changes for #3300.

libraries/directory:

 Thu Jun 18 06:48:58 PDT 2009  Simon Marlow <marlo...@gmail.com>
   * Windows: Unicode getDirectoryContents and setPermissions

Both 7.0 and 7.1 work for me:

> getDirectoryContents "C:\\System Volume Information\\"
*** Exception: C:\System Volume Information\: getDirectoryContents: permission denied (Access is denied.)
Note: See TracTickets for help on using tickets.