mmap - システムコールの説明 - Linux コマンド集 一覧表
- 名前
- 書式
- 説明
- 返り値
- 注意
- エラー
- 可用性
- 準拠
- バグ
- 関連項目
名前
mmap, munmap - ファイルやデバイスをメモリにマップ/アンマップする
書式
#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *start, size_t length);
説明
mmap
()関数は、ファイル記述子 (file descriptor)
fd
で指定されたファイル (もしくはその他のオブジェクト) の、オフセット
offset
から
length
バイトの範囲をメモリにマップする (張り付ける) 。
このとき、なるべくメモリ上の
start
アドレスから始めるようにマップする。実際には、このアドレスは関数に
対してのヒントでしかなく、通常は 0 を指定する。
実際にオブジェクトがマップされたアドレスは
mmap
()の返り値となり、決して 0 にはなることはない。
引き数
prot
には、メモリ保護をどのように行なうかを指定する
(ファイルのオープンモードと矛盾してはいけない)。
prot
には、
PROT_NONE
、または
その他の PROT_* フラグをひとつ以上、ビット毎に OR 演算したものの
いずれかを指定することができる。
-
PROT_EXEC
-
ページは実行可能である。
-
PROT_READ
-
ページは読み込み可能である。
-
PROT_WRITE
-
ページに書き込み可能である。
-
PROT_NONE
-
ページにはアクセスできない。
引き数
flags
には、マップされたオブジェクトのタイプ、マップ時のオプション、
マップされたページコピーへの変更を
そのプロセスだけが行えるのか (それとも他のプロセスからも可能なのか)
を指定する。
以下に示すビットデータを指定できる。
-
MAP_FIXED
-
指定されたアドレス以外のアドレスにマッピングを行なわない。
start
と
len
で指定されたメモリ領域が既存のマッピングのページと重なる場合、
既存のマッピングの重なった部分は捨てられる。
もし指定されたアドレスが使用できない場合、
mmap
()は失敗する。
MAP_FIXED
を指定した場合は
start
はページサイズの倍数でなくてはいけない。
このオプションは使用しない方が良い。
-
MAP_SHARED
-
このマッピングを、このオブジェクトをマップした他の全てのプロセスと共有する。
この領域への保存は、ファイルへの書き込みと等価である。
ただしファイルが実際に更新されるのは、
msync
(2) または
munmap
(2)が呼ばれたときである。
-
MAP_PRIVATE
-
プライベートな copy-on-write (書き込み時コピー) マップを生成する。
この領域への書き込みは、オリジナルのファイルに影響しない。
mmap
()の呼び出し後にオリジナルのファイルに対して行われた変更が、
マップ領域に反映されるかどうかは規定されていない。
MAP_SHARED
と
MAP_PRIVATE
は、必ずどちらかひとつを指定しなければならない。
上記の 3 つのフラグは POSIX.1-2001 で規定されている。
さらに、Linux では以下の非標準のフラグを使用することができる。
-
MAP_DENYWRITE
-
このフラグは無視される
(ずっと前は、マップ元のファイルへの書き込みを行おうとすると、エラー
ETXTBUSY
で失敗するようにシグナルが設定されていたが、これは denial-of-service
(サービス拒否) 攻撃の原因となった)。
-
MAP_EXECUTABLE
-
このフラグは無視される。
-
MAP_NORESERVE
-
このマッピングに対するスワップ空間の予約を行わない。
スワップ空間を予約した場合は、このマッピングの変更が必ず可能なことが
保証される。予約を行わなかった場合、物理メモリに空きがないと
書き込み時に SIGSEGV エラーを受け取ることがある。
proc
(5) の
/proc/sys/vm/overcommit_memory
ファイルについての議論も参照。
バージョン 2.6 より前のカーネルでは、このフラグは書き込み可能な
プライベート・マッピングについてのみ効果があった。
-
MAP_LOCKED
(Linux 2.5.37 以降)
-
マップされた領域のページを
mlock
()の方法でメモリ内にロックする。
それ以前のカーネルでは、このフラグは無視される。
-
MAP_GROWSDOWN
-
スタック用に使用される。マッピングをメモリ内で逆向きに行うことを
カーネル VM システムに指示する。
(訳注:マッピングは通常はメモリ・アドレスが増加する向きに行うが、
このオプションを指定すると逆向きにマッピングを行う)
-
MAP_ANONYMOUS
-
マッピングはどのファイルとも関連付けされない。
引き数
fd
と
offset
は無視される。このフラグと
MAP_SHARED
を組み合わせての利用は
カーネル 2.4 以降の Linux でのみサポートされている。
-
MAP_ANON
-
MAP_ANONYMOUS
の別名。非推奨。
-
MAP_FILE
-
互換性のためのフラグ。無視される。
-
MAP_32BIT
-
マッピングをプロセスのアドレス空間の先頭 2GB の範囲に配置する。
MAP_FIXED
がセットされている場合は、このフラグは無視される。
現在のところ、このフラグがサポートされているのは、x86-64 アーキテクチャ上
の 64 ビット・プログラムについてのみである。
-
MAP_POPULATE
(Linux 2.5.46 以降)
-
ファイルを前もって読み込む (read-ahead) ことで、
ファイルマッピング用のページテーブルを配置 (populate) する
(前もってページフォールトさせる (prefault))。
この後は、マッピングに対するアクセスがページフォールトで
ブロックされなくなる。
-
MAP_NONBLOCK
(Linux 2.5.46 以降)
-
MAP_POPULATE
と組み合わせた場合のみ意味を持つ。
read-ahead (前もって読み込むこと) を実行しない。
単に、すでに RAM 上に存在するページに対して
ページテーブルエントリを作成するだけである。
いくつかのシステムでは、上記以外にフラグとして MAP_AUTOGROW, MAP_AUTORESRV,
MAP_COPY, MAP_LOCAL が記載されている。
MAP_ANONYMOUS
がセットされなかった場合、
fd
は有効なファイル記述子でなければならない。
MAP_ANONYMOUS
がセットされた場合、 Linux では
fd
は無視される。しかし、
MAP_ANONYMOUS
(または
MAP_ANON
)を指定する場合に
fd
を -1 にする必要がある実装もあり、移植性を考慮した
アプリケーションではこのようにすべきである。
offset
は
getpagesize
(2) の返すページサイズの整数倍でなければならない。
mmap
()によってマップされたメモリの属性は
fork
(2) の際に継承される。
ファイルはページサイズの整数倍の領域にマップされる。サイズがページサイズの
整数倍でないファイルの場合、マップ時に残りの領域は 0 で埋められ、この領域へ
書きこみを行ってもファイルに書き出されることはない。マッピングを行った元
ファイルのサイズを変更した場合、元ファイルの追加されたり削除された領域に対応
するマップされたページに対してどのような影響があるかは規定されていない。
システムコール
munmap
()は指定されたアドレス範囲のマップを消去し、
これ以降のその範囲内へのメモリ参照は不正となる。
この領域は、プロセスが終了したときにも自動的にアンマップされる。
一方、ファイル記述子をクローズしても、この領域はアンマップされない。
start
アドレスはページサイズの整数倍でなければならない。指定された範囲の一部分を
含む全てのページはアンマップされ、これ以降にこれらのページへの参照があると
SIGSEGV が発生する。
指定した範囲内にマップされたページが一つも含まれていない場合でも
エラーにならない。
ファイルと関連付けられたマッピングの場合、マッピングされたファイルの
st_atime
フィールドは、
mmap
()されてからアンマップ (unmap) されるまでの間に更新されることがある。
それまでに更新が行われていなければ、マップされたページへの最初の参照があった
際に更新される。
PROT_WRITE
と
MAP_SHARED
の両方を指定してマップされたファイルの場合、書き込みがあると、
st_ctime
と
st_mtime
の両フィールドは、マップされた領域への書き込みより後で、
MS_SYNC
または
MS_ASYNC
フラグが指定して
msync
()が呼ばれる前までに更新される。
返り値
mmap
()は成功するとマップされた領域へのポインタを返す。
失敗すると値
MAP_FAILED
(つまり (void *) -1) を返し、
errno
がエラーの内容にしたがってセットされる。
munmap
()は成功すると 0 を返す。失敗すると -1 を返し、
errno
がセットされる (多くの場合
EINVAL
になるだろう)。
注意
PROT_READ
に
PROT_EXEC
が含まれるかどうかは、アーキテクチャ依存である。
移植性を考慮したプログラムでは、
新規にマップした領域でコードを実行したい場合は、常に
PROT_EXEC
をセットすべきである。
エラー
-
EACCES
-
以下のいずれかの場合。
ファイル記述子の参照先が通常のファイルではない (non-regular file) 。
MAP_PRIVATE
を要求したが
fd
は読み込み用にオープンされていない。
MAP_SHARED
を要求して
PROT_WRITE
をセットしたが
fd
は読み書きモード (O_RDWR) でオープンされていない、
PROT_WRITE
をセットしたが、ファイルは追加 (append) 専用である。
-
EAGAIN
-
ファイルがロックされている。またはロックされているメモリが多すぎる
(
setrlimit
(2)を参照)。
-
EBADF
-
fd
が有効なファイル記述子 (file descriptor) ではない
(かつ
MAP_ANONYMOUS
がセットされていない)。
-
EINVAL
-
start
か
length
か
offset
が適切でない
(例えば、大きすぎるとか、ページ境界にアラインメントされていない)。
-
ENFILE
-
オープンされたファイルの総数がシステムの制限に達した。
-
ENODEV
-
指定されたファイルが置かれているファイルシステムがメモリマッピングをサポート
していない。
-
ENOMEM
-
メモリに空きがない、または処理中のプロセスのマッピング数が最大数を超過した。
-
EPERM
-
prot
引き数は
PROT_EXEC
を行うように指定されているが、
no-exec でマウントされたファイルシステム上のファイルに
マップ領域が対応している。
-
ETXTBSY
-
MAP_DENYWRITE
がセットされているが
fd
で指定されているオブジェクトは書き込み用に開かれている。
マップ領域を利用する際に、以下のシグナルが発生することがある:
-
SIGSEGV
-
読み込み専用で mmap された領域へ書き込みを行おうとした。
-
SIGBUS
-
バッファのうち、ファイルに関連づけられていない部分
(例えばファイル末尾を越えた部分など。これには
他のプロセスがファイルを切り詰めた場合なども含まれる)
にアクセスしようとした。
可用性
mmap
(),
msync
()
munmap
()が利用可能な POSIX システムでは、
_POSIX_MAPPED_FILES
は <unistd.h> で 0 より大きな値に定義される
(
sysconf
(3)も参照のこと)。
準拠
SVr4, 4.4BSD, POSIX.1-2001.
バグ
Linux においては、上記の
MAP_NORESERVE
で述べられているような保証はない。
デフォルトでは、システムがメモリを使い切った場合には、
どのプロセスがいつ強制終了されるか分からないからである。
2.6.7 より前のカーネルでは、
prot
に
PROT_NONE
が指定された場合にのみ、
MAP_POPULATE
フラグが効力を持つ。
関連項目
getpagesize
(2),
mincore
(2),
mlock
(2),
mmap2
(2),
mremap
(2),
msync
(2),
remap_file_pages
(2),
setrlimit
(2),
shm_open
(3)
B.O. Gallmeister, POSIX.4, O'Reilly, pp. 128-129 and 389-391.
- Linux Tips 関連記事
- Linux Tips(目次)
- Linux ディストリビューション一覧
- rpm のファイル名にあるi386とかi686とは
- 自分のマシンの情報を調べる
- cron の設定
- ssh の root ログインを禁止する
- ssh を、ユーザ、IPでアクセス制限
- 鍵交換方式によるssh接続
- 鍵交換方式によるssh接続( windowsから )
- 複数ファイル内の文字列を置換して上書き保存する
- あるグループをイニシャルグループとするユーザー一覧出力
- 複数ファイルのファイル名を一括変換する
- 連番ファイルをコマンド一発で作成する
- 中身がランダムなファイルを任意のサイズで作成する
- Linux ユーザーアカウントをロック・アンロックする