There are a zillion pages explaining how umask works from the user’s point of view, usually with great charts and tables explaining all the bits.
However in all my years I’ve never seen umask explained from the
developer’s point of view. What do you provide to
creat()/open()/mkdir() (in C) or
(in Go) so that the user’s umask is in control.
The Linux manpage open(7) says:
The effective mode is modified by the process's umask in the usual way: in the absence of a default ACL, the mode of the created file is (mode & ~umask).
Clear as mud.
The FreeBSD manpage open(2) says:
the file is created with mode mode as described in chmod(2) and modified by the process' umask value (see umask(2)).
umask(2) is not more clear.
Today (yes, after 25+ years of coding on unix systems) I finally fully understood what those mean.
Here’s how I’d describe it in plain English:
“Set the perm to the most permissive permissions you think are appropriate. The user’s umask will shrink that down based on their personal preferences/needs.”
That’s it! It’s that simple!
When creating a file, the permission are typically:
0600== This file is just for the user.
0660== This file is for the user and their group.
0664== Like the previous but others can view the file.
0640== This file is for the user; group can read.
6 to a
7 if the file should be executable (are you
writing a compiler?)
Likewise, typically when creating a directory the permissions would be:
0700== This directory is just for the user.
0770== This directory is for the user and their group.
0750== Like 0770 but their group can only view.
7 to a
6 (or a
5 to a
4) if you want the user, group,
or others to be able to open files if they know the name, but can’t
find out what files are there. In your entire career you will never do
that (unless you are writing a queue submission system that only uses
the local file system… at which point you shouldn’t need this blog
Typical umask settings
I typically set my umask to
0027 which strips out the “other” bits
completely (why should I lets me collaborate with people in my team in
a safe way (they can read, but not change).
I once met a woman who’s name on Yahoo and AIM (this was a long time
ago) was her first name followed by
700. Once day I asked if she
was trying to tell people, in a very Unix-y way that she was a very
private person. Turns out I was the first to ever guess correctly! We
can assume her umask is
Setting/reading the umask
What if you want to override the umask?
Well, you shouldn’t.
However, if you do, remember to set it back to the original value. That’s why the umask system call (which sets the umask) returns the old value: so that you can
In Go, here’s how you temporarily set the umask:
savedUmask := unix.Umask(forcedUmask) // Do your thing here. _ = unix.Umask(savedUmask) // Return the umask to the original
Or, if you just want to know the umask, set it then set it back right away:
umaskValue := unix.Umask(0) _ = unix.Umask(umaskValue)