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

  • 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 '19 at 15:40
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.

| improve this answer | |
  • 1
    good explanation as always.... – solfish Aug 13 '17 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.

| improve this answer | |
  • 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 '17 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 '17 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 '17 at 6:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.