John92
John92

Reputation: 17

mkdir not setting permissions correctly

I am trying to make a directory that has the "set group ID on execution" set in Python

In the shell:

$ mkdir --mode 2775 mail
$ ls -ld mail
drwxrwsr-x 1 john john 0 May  3 08:34 mail
      ^

In Python I am using pathlib.Path.mkdir, and it seems there some bits for mode are not taken into account, even when the umask is cleared:

from pathlib import Path
import os

os.umask(0)
md = Path('mail')
md.mkdir(mode=0o2775)    

drwxrwxr-x 1 john john 0 May  3 08:35 mail
       ^

Is there some cut-off at nine bits that is not documented

Upvotes: 1

Views: 1099

Answers (2)

Anthon
Anthon

Reputation: 76652

pathlib's mkdir essentially just calls os.mkdir(). The documentation there includes the section:

On some systems, mode is ignored. Where it is used, the current umask value is first masked out. If bits other than the last 9 (i.e. the last 3 digits of the octal representation of the mode) are set, their meaning is platform-dependent. On some platforms, they are ignored and you should call chmod() explicitly to set them.

So only the last 9 bits are guaranteed to be used. You'll have to do (no need to set umask):

md.mkdir()
md.chmod(0o2775)

It would be better if pathlib would not silently ignore extra bits, but actually threw a ValueError.

Upvotes: 1

ShadowRanger
ShadowRanger

Reputation: 155458

Ultimately, on non-Windows systems, Path.mkdir calls os.mkdir which in turn invokes the C system call mkdirat. That call's behavior is defined in terms of mkdir, which, on Linux, documents the mode with:

The argument mode specifies the permissions to use. It is modified by the process's umask in the usual way: the permissions of the created directory are (mode & ~umask & 0777)

Note that the permissions explicitly mask off all bits above 0777; this is just how mkdir system calls behave on some OSes. You'll just have to chmod it after the fact.

Upvotes: 4

Related Questions