I know this pattern to read the umask in Python:
current_umask = os.umask(0) # line1
os.umask(current_umask) # line2
return current_umask # line3
But this is not thread-safe.
A thread which executes between line1 and line2 will have a different umask.
Is there a thread-safe way to read the umask in Python?
Related: https://bugs.python.org/issue35275
if your system has Umask
field in /proc/[pid]/status
, you could read from on it:
import os
def getumask():
pid = os.getpid()
with open(f'/proc/{pid}/status') as f:
for l in f:
if l.startswith('Umask'):
return int(l.split()[1], base=8)
return None
tested under CentOS 7.5, Debian 9.6.
or, you could add a thread lock :)
umask is inherited by child processes. You could create a pipe, fork a child process, get the umask there and write the result to the pipe so the parent can read it.
Quite expensive, but without any special requirements like /proc
virtual filesystem. An example with just low-level OS calls (all async-safe) and no error checking below:
import os
import struct
def get_umask():
pipe = os.pipe()
pid = os.fork()
if pid == 0:
os.close(pipe[0])
umask = os.umask(0)
os.write(pipe[1], struct.pack('H', umask))
os.close(pipe[1])
os._exit(0)
else:
os.close(pipe[1])
value = os.read(pipe[0], 2)
os.close(pipe[0])
os.waitpid(pid, 0)
return struct.unpack('H', value)[0]
print("umask {:03o}".format(get_umask()))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With