1

I know that:

  1. A file default mod is 666
  2. 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

1
  • You cannot normally create an executable file using umask; you can only change a file's permissions to make it executable. The only exceptions to this rule are when creating a directory or compiling a program to create an executable binary.
    – S.Duygun
    Jan 22, 2019 at 15:40

3 Answers 3

3

Short answer:

Because with a 5 you are removing the read (4) and executable (1) bit, so you end up with only write (2).


Explanation:

With 555 you are not setting default executable bit on.

It's wrong          =>          (6 - 5 = 1)

We got these mods:

  • 4 = Read
  • 2 = Write
  • 1 = Executable

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.

In binary

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.

1
  • 1
    good explanation as always....
    – solfish
    Aug 13, 2017 at 6:59
2

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 both touch(1) and mkdir(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 the umask_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 under perldoc -f sysopen).

man umask

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.

3
  • For the files it's not 777, it's 666 ... 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) .
    – Ravexina
    Aug 13, 2017 at 6:00
  • @Ravexina - as mentioned in the Unix & Linux Q&A which I added to my answer, 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.
    – Yaron
    Aug 13, 2017 at 6:38
  • Yeah, the default mod depends on the program, also umask itself can be ignored by the programs like compilers, chmod, etc.
    – Ravexina
    Aug 13, 2017 at 6:40
1

Definition

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.

Examples

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)

Notes

Observe from the last example that masking does not coincide with subtraction (6-5=1 in both, decimal and binary notation).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .