--- name: umask signature: 'umask EXPR' since: 5.0 status: documented categories: ["Filehandles, files, directories"] --- ```{index} single: umask; Perl built-in ``` *[Filehandles, files, directories](../perlfunc-by-category)* # umask Set or read the process file-creation mode mask. `umask` controls which permission bits are **cleared** from the `MODE` argument of every file- or directory-creation call made by this process from now on. It is a property of the running process, not of any particular filehandle, and it is inherited by child processes. Call `umask EXPR` to install a new mask and receive the previous one; call bare `umask` to read the current mask without changing it. ## Synopsis ```perl umask EXPR umask ``` ## What you get back The **previous** umask as an integer, so you can save it and restore it later: ```perl my $old = umask 0077; # ... create private files ... umask $old; ``` Bare `umask` returns the current mask without changing it. If the system has no `umask(2)` call and the caller is trying to restrict access for itself (`(EXPR & 0700) > 0`), an exception is raised; if the call is not implemented and the caller is not restricting its own access, `undef` is returned. On Linux this case does not arise. ## How the mask is applied The mask is **subtractive**. Every bit set in the umask is cleared from the `MODE` passed to [`mkdir`](mkdir), [`sysopen`](sysopen), [`open`](open) in creation modes, and the underlying `creat(2)` / `mkdir(2)` system calls. The effective permissions of the new file are `MODE & ~umask`. A Unix permission like `rwxr-x---` is three sets of three bits, or three octal digits — `0750`. The leading `0` marks the literal as octal and is not itself a permission digit. A umask is written the same way and names the bits you want **disabled** for newly created files. Worked example. With `umask 0022`, asking [`sysopen`](sysopen) for `0666` actually creates a file with mode `0644`: ``` 0666 &~ 0022 = 0644 rw-rw-rw- ----w--w- rw-r--r-- ``` With `umask 0027` (group may not write, others may not read, write, or execute), the same `0666` request yields `0640` (`0666 & ~0027 == 0640`). ## Global state it touches The mask itself is process-global kernel state set via `umask(2)`. `umask` does not read or write any Perl special variable directly, but every creation call in the process observes it, and [`$!`](../perlvar) is set by the underlying system calls that *consume* the mask ([`mkdir`](mkdir), [`sysopen`](sysopen), [`open`](open)), not by `umask` itself. Child processes spawned via [`fork`](fork), [`exec`](exec), or [`system`](system) inherit the current value. ## Examples Install a mask that hides the file from everyone but the owner, keeping the previous value for restoration: ```perl my $old = umask 0077; open my $fh, ">", "secret.txt" or die "open: $!"; # secret.txt is created mode 0666 & ~0077 == 0600 close $fh; umask $old; ``` Read the current mask without changing it — useful for logging or diagnostics: ```perl printf "current umask: %04o\n", umask; # e.g. "current umask: 0022" ``` Typical values to pass — these are the three masks actually used in practice: ```perl umask 0022; # group + other: read/execute, no write (default on most systems) umask 0027; # group: read/execute; other: nothing umask 0077; # owner-only; nothing for group or other ``` Scoped change around a block of file-creating code. `umask` has no [`local`](local) magic of its own — save and restore explicitly: ```perl sub write_private_file { my ($path, $data) = @_; my $old = umask 0077; open my $fh, ">", $path or do { umask $old; die "open $path: $!"; }; print $fh $data; close $fh; umask $old; } ``` Octal literal vs. string — a common trap. A umask is a **number**, not a string of octal digits. Reading one from configuration requires [`oct`](oct): ```perl my $from_config = "0027"; # string umask oct $from_config; # correct: 0027 as a number umask $from_config; # WRONG: decimal 27 == 033 octal ``` ## Edge cases - **Bare `umask` in list context** still returns a single integer. The function is scalar-valued. - **Negative or out-of-range values** are masked to the nine low-order permission bits by the kernel; only bits `0777` survive. Passing `0777` disables all permissions on every newly created file, which is almost never what you want. - **`umask` does not affect existing files.** It only filters the `MODE` argument of *creation* calls. To change an existing file's permissions use [`chmod`](chmod). - **`umask` does not affect [`open`](open) for an existing file** — opening a file that already exists does not re-apply the mask. It applies only when a file is being created (`O_CREAT` in [`sysopen`](sysopen), or `>`/`>>`/`+>` modes creating a new pathname in [`open`](open)). - **Inheritance across `fork`/`exec`**. Children start with the parent's current umask. Setting the mask before [`system`](system) or [`exec`](exec) changes the environment the child inherits; restore it afterwards if the parent still cares. - **Threads.** The umask is a per-process attribute in the kernel, so on systems where Perl threads share a process (the usual case) every thread sees the same mask. Changing it in one thread changes it for all. - **`umask(2)` not implemented.** The POD documents a fallback path for systems without the syscall: raise on attempts to restrict the owner's own access, otherwise return [`undef`](undef). Every platform pperl targets has `umask(2)`, so this path is effectively unreachable here. - **Octal presentation**. Print the mask with `printf "%04o"`; the default `%d` prints decimal, which is unreadable as permission bits. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`chmod`](chmod) — change permissions on an **existing** file; the counterpart to the creation-time filtering `umask` performs - [`mkdir`](mkdir) — directory creation call whose `MODE` argument is filtered through the current umask - [`sysopen`](sysopen) — low-level file creation whose `MODE` argument is filtered through the current umask; the canonical place where the mask is felt - [`open`](open) — in creation modes (`>`, `>>`, `+>`) the underlying `creat(2)` applies the umask to the default `0666` - [`oct`](oct) — convert a string like `"0027"` to the integer value `umask` expects - [`$!`](../perlvar) — set by the creation calls that consume the mask, not by `umask` itself; check it after the [`open`](open) / [`sysopen`](sysopen) / [`mkdir`](mkdir) that fails