I'm trying to use os.fchmod()
as specified in this tutorial. However, when I pass in a file descriptor and a mode, I get back a vague "Invalid Argument" error.
import socket
import stat
import os
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
os.fchmod(s.fileno(), stat.S_IRWXO)
How do I fix this? The goal is to create a Unix Domain Socket with changed permissions (this git issue implies its possible).
In the fchmod
man page on MacOS, one of the causes of EINVAL
is listed as:
[EINVAL] fildes refers to a socket, not to a file.
Apparently linux (but not MacOS) supports "pre-setting" the mode so that when you eventually bind
, it will get the mode you pre-set with fchmod
. That is not guaranteed to work across OSes and clearly does not on MacOS (I would guess it also doesn't work on other Unix-like OSes).
I think you will need use the umask
strategy mentioned in that git issue. You can then call os.chmod
with the socket's path name after the bind to ensure that the mode is set exactly as you want it (umask
only allows you to specify bits to be cleared from the mode).
As mentioned in the issue, the problem with umask
is that there is only a single mask value, which is shared by all threads. If you have only a single thread, or all threads can use the same mask value for all files created, that isn't a problem. Otherwise, you would either need to implement some kind of cooperative locking around umask
usage, or use the fork
hack mentioned in the issue to do the umask
/bind
in another process.