umask

ファイル生成のモードのマスクをセットする

構文

解説

umask は、自身のプロセスに対して umask を EXPR にセットし、前の値を返します。 EXPR が省略されたら、何もせずに現在の umask の値を返します。

umask とはファイルやディレクトリ作成時のパーミッションの制限を設定するものです。 具体的に umask にはどのような値がセットされているのかを知るために、 umask 関数に引数を与えず、現在の umask の値を取り出してみましょう。 一般的に umask は 8 進数 3 桁で表します。 そのため、以下のコードでも 8 進数 3 桁で出力します。

print sprintf( '%03o', umask );    # 022

環境によって異なりますが、022 が umask としてセットされていることが多いのではないでしょうか。

では、次に新規にファイルを生成して、そのファイルパーミッションを見てみましょう。

# ファイルを新規に生成
open my $fh, '>', './sample.txt';
close $fh;

# ファイルパーミッションを表示
my $mode = ( stat('./sample.txt') )[2];
print substr( sprintf( '%03o', $mode ), -3 );    # 644

生成されたファイルのパーミッションは 644 になりました。 この 644 というのは umask の設定によって決まったパーミッションなのですが、 そのルールは至ってシンプルです。 すべての権限が付与されたパーミッション 666 から、umask の値を引いたものが、 新規に生成されたファイルのパーミッションになります。 ここでは 666 - 022 = 644 になったわけです。 10 進数ではなく 8 進数による引き算ですので注意してください。 とはいえ、各桁を別々に引くだけですので、計算そのものは簡単です。

なお、なぜ 666 なのかという疑問が出てくるでしょう。 これは open によって新規にファイルを生成する際に、 パーミッション 666 で生成しようとするからです。 生成時に指定したパーミッションはそのまま受け入れられるわけではなく、 umask の値で制限されたうえで、最終的なパーミッションが決定されます。

同じ論理で、ディレクトリの生成に当てはめることができます。 ディレクトリの生成は mkdir を使いますが、 デフォルトのパーミッションは 777 です。 そのため、mkdir でディレクトリを生成すると、 そのパーミッションは 777 - 022 = 755 となります。

# ディレクトリを新規に生成
mkdir './sample';

# ディレクトリパーミッションを表示
my $mode = ( stat('./sample') )[2];
print substr( sprintf( '%03o', $mode ), -3 );    # 755

実際にファイルやディレクトリが新規に生成される際に使われるパーミッションは、 前述の通り引き算で求められますが、前述の例なら、厳密には、ファイルなら 0666 &~ 0022、 ディレクトリなら 0777 &~ 0022 というビット演算が行われます。

ファイルの生成には open のほか、 sysopen もあります。 この sysopenmkdir は、生成するファイルやディレクトリのパーミッションを指定することができます。 しかし、そこで指定するパーミッションは、一般のファイルなら 0666 を、ディレクトリなら 0777 を指定するのが良いと言われています。 実際には、そのパーミッションでファイルやディレクトリが生成されるわけではなく、 そこから umask の値を引いたパーミッションが適用されます。 プログラム側では sysopenmkdir に最大限に緩いパーミッションを与えておき、利用者に umask を通して実際のパーミッションを決定できる余地を残す方が良いでしょう。 ただし、メールファイルなど機密性が高いファイルやディレクトリはその限りではありません。

なお、umask に与える EXPR は数値でなければならない点に注意してください。 一般的には 8 進数が使われます。8 進数の文字列ではありません。 もし文字列で値を持っているなら、oct を使って数値に変換してください。