Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open a directory on Windows: 'Permission denied'

Tags:

python

windows

I'm trying to get a file descriptor for a directory but calling os.open on on directories always result in a "permission denied" error. I do not believe it's a permission issue because it happens on all directories, while there's no issue on files (See REPL session below). Running as administrator makes no difference.

Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.mkdir('mydir')
>>> os.access('mydir', os.F_OK)
True
>>> os.access('mydir', os.R_OK)
True
>>> os.access('.', os.R_OK)
True
>>> os.access('.', os.F_OK)
True
>>> os.open('myfile', os.O_RDWR)
3
>>> os.open('mydir', os.O_RDONLY)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 13] Permission denied: 'mydir'
>>> os.open('mydir', os.O_RDWR)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 13] Permission denied: 'mydir'
>>> open('mydir')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 13] Permission denied: 'mydir'

On linux it works as expected:

>>> os.open('mydir', os.O_RDONLY)
3

The docs does not indicate you can't nor any platform difference. Is this expected behavior? Is it not possible to get file descriptors for directories on Windows?

like image 369
gwohpq9 Avatar asked Oct 21 '25 07:10

gwohpq9


1 Answers

Edit:

This is not a permission issue, it will never work with Python 2. Python 2 is using the Win 32 API call _wopen when doing os.open() (code: https://github.com/python/cpython/blob/2.7/Modules/posixmodule.c#L6554). According to the docs, it throws an error when opening a directory:

EACCES Tried to open read-only file for writing, file's sharing mode does not allow specified operations, or given path is directory.

So:

The docs does not indicate you can't nor any platform difference. Is this expected behavior?

It is expected behavior. I would say in this case it is fine that this detail is not clarified in the Python docs.

Is it not possible to get file descriptors for directories on Windows?

On Python 2 you can use the ctypes module for calling arbitrary Win 32 API methods yourself. Python 3 uses CreateFile instead of _wopen, a more modern API call, which might enable you to do what you want, see below.

Old answer:

The most important resource for this question is the documentation for the CreateFile Win 32 API function, documented here:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx

You might want to read the relevant parts of it, e.g.

To open a directory using CreateFile, specify the FILE_FLAG_BACKUP_SEMANTICS flag as part of dwFlagsAndAttributes.

Also, there is a comment below the docs, saying

In order to open a handle to a directory you appear to need SYNCHRONIZE access, even if you aren't requesting any access rights. (Note: this doesn't apply if you have backup/restore privilege.)

Python 3 uses this function in several places, you may want to search for yourself

https://github.com/python/cpython/search?q=CreateFile&type=Code

or via git clone and using grep -HR "CreateFile(" .. In Python 3, there is the _winapi.c module which is most likely used when doing os.open() on Windows.

On Python 2, there is a call to _wopen in https://github.com/python/cpython/blob/2.7/Modules/posixmodule.c#L6554, but I am not sure where this is defined. When you follow this path, you will find the actual implementation. Then you can see how exactly Python is calling that function -- this, together with the docs, will most likely explain your observations.

like image 146
Dr. Jan-Philip Gehrcke Avatar answered Oct 23 '25 19:10

Dr. Jan-Philip Gehrcke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!