I know that:
- A file default mod is
666
umask
value will be removed from default mods.
So why when I set the "umask" to 555
it doesn't set newly created file's permissions to 111
? instead it's setting them to 222
I know that:
666
umask
value will be removed from default mods.So why when I set the "umask" to 555
it doesn't set newly created file's permissions to 111
? instead it's setting them to 222
Because with a 5
you are removing the read (4)
and executable (1)
bit, so you end up with only write (2)
.
With 555
you are not setting default executable bit on.
It's wrong => (6 - 5 = 1)
We got these mods:
The only way that I can create a 5
is from 4 + 1
, so 5
actually means:
4 (Read) + 1 (Executable) = 5
It means "remove" executable and read mods if they're are being set.
In other words, with umask 555
you are removing the read ( 4 ) and executable ( 1 ) bit from default file mode ( 6 ) which brings us to the ( 2 ), because in a 6 we only have a 4 and 2 to remove (not any 1):
6 = 4 + 2
You removal only effects the 4, so the file ends up with 222
.
Think of it in binary:
1 -> 001
2 -> 010
3 -> 011
4 -> 100
5 -> 101
6 -> 110
7 -> 111
File default mode is 666 (110 110 110), and our umask
value is 555
(101 101 101):
Decimal title -> 421 421 421
666 in binary -> 110 110 110
- 555 in binary -> - 101 101 101
_____________
010 010 010
2 2 2
-w- -w- -w-
See? we ended up to the -w-w-w-, or 222
.
The result umask value is mask & 0777 (bit wise and)
When mask is 0555
Than 0555 & 0777 result with 0222
nixCraft understanding-linux-unix-umask-value-usage
Task: Calculating The Final Permission For FILES
You can simply subtract the umask from the base permissions to determine the final permission for file as follows:
666 – 022 = 644 File base permissions : 666 umask value : 022 subtract to get permissions of new file (666-022) : 644 (rw-r–r–)
Task: Calculating The Final Permission For DIRECTORIES
You can simply subtract the umask from the base permissions to determine the final permission for directory as follows:
777 – 022 = 755 Directory base permissions : 777 umask value : 022 Subtract to get permissions of new directory (777-022) : 755 (rwxr-xr-x)
The source of the difference between touch file
and mkdir dir
:
Note: as specify in this Unix Q&A
how the permission bits are hard-coded into the standard utilities. Here are some relevant lines from two files in the
coreutils
package that contains the source code for bothtouch(1)
andmkdir(1)
, among others:
mkdir.c
:if (specified_mode) { struct mode_change *change = mode_compile (specified_mode); if (!change) error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode)); options.mode = mode_adjust (S_IRWXUGO, true, umask_value, change, &options.mode_bits); free (change); } else options.mode = S_IRWXUGO & ~umask_value; }
In other words, if the mode is not specified, set it to
S_IRWXUGO
(read: 0777) modified by theumask_value
.
touch.c
is even clearer:int default_permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
That is, give read and write permissions to everyone (read: 0666), which will be modified by the process
umask
on file creation, of course.You may be able to get around this programmatically only: i.e. while creating files from within either a C program, where you make the system calls directly or from within a language that allows you to make a low-level syscall (see for example Perl's
sysopen
underperldoc -f sysopen
).umask() sets the calling process's file mode creation mask (umask) to mask & 0777 (i.e., only the file permission bits of mask are used), and returns the previous value of the mask.
strace touch a |& grep open
outputs: open("a", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
, and for directories: strace mkdir a1 |& grep 777
> mkdir("a1", 0777)
.
touch
uses default 0666
mask, which added in bit wise and
with the umask_value
. While mkdir
uses a default 0777
mask which added in bit wise and
with the umask_value
.
umask
itself can be ignored by the programs like compilers, chmod
, etc.
Roughly speaking, in general, the on bits of a mask switch off (if not already off) the bits of what it is masking.
More precisely, in this particular case, the resulting mode of a newly created file or folder follows the following bitwise operation:
result = mode & !mask
where result
is the resulting mode, mode
is the usual mode (666 for files and 777 for folders), and !mask
is the bitwise negation of mask
, the set mask.
Masking write (2) permission on the left, and read (4) and execution (1) permissions on the right.
folder file folder file
(7) 111 mask 110 (6) (7) 111 mask 110 (6)
101 <-- !010 --> 101 010 <-- !101 --> 010
&----- (2) &----- &----- (5) &-----
(5) 101 100 (4) (2) 010 010 (2)
Observe from the last example that masking does not coincide with subtraction (6-5=1 in both, decimal and binary notation).