Man page - vfork(2)

Packages contains this manual

Available languages:

en fr it ja ru ro

Manual

VFORK

名 前
書 式
説 明
規 格 の 説 明
LINUX で の 説 明
歴 史 的 な 説 明
準 拠
注 意
Caveats
Linux で の 注 意
歴 史
バ グ
関 連 項 目
こ の 文 書 に つ い て

名 前

vfork - 子 プ ロ セ ス を 生 成 し 親 プ ロ セ ス を 停 止 さ せ る

書 式

#include <sys/types.h>
#include <unistd.h>

pid_t vfork(void);

glibc 向 け の 機 能 検 査 マ ク ロ の 要 件 ( feature_test_macros (7) 参 照 ):

vfork ():

glibc 2.12 以 降 :

(_XOPEN_SOURCE >= 500) && ! (_POSIX_C_SOURCE >= 200809L)
|| /* glibc 2.19 以 降 : */ _DEFAULT_SOURCE
|| /* glibc 2.19 以 前 : */ _BSD_SOURCE

glibc 2.12 よ り 前 :

_BSD_SOURCE || _XOPEN_SOURCE >= 500

説 明

規 格 の 説 明

(POSIX.1 よ り 引 用 ) vfork () 関 数 は fork (2) と 同 じ 働 き を す る が 、 vfork () で 作 成 さ れ た プ ロ セ ス が vfork () か ら の 返 り 値 を 格 納 し て い る pid_t 型 の 変 数 以 外 を 変 更 し た り 、 vfork () を 呼 び 出 し て い る 関 数 か ら return し た り 、 _exit (2) や exec (3) 族 の 関 数 を コ ー ル す る 前 に 他 の 関 数 を コ ー ル し た 場 合 の 動 作 が 未 定 義 で あ る と い う 点 が 異 な る 。

LINUX で の 説 明

vfork () は fork (2) と 全 く 同 じ よ う に 呼 び 出 し た プ ロ セ ス の 子 プ ロ セ ス を 生 成 す る 。 詳 し い 説 明 と 返 り 値 、 エ ラ ー に つ い て は fork (2) を 参 照 す る こ と 。

vfork () は clone (2) の 特 殊 な 場 合 で あ る 。 親 プ ロ セ ス の ペ ー ジ テ ー ブ ル の コ ピ ー を 行 わ ず に 新 し い プ ロ セ ス を 作 成 す る た め に 使 用 す る 。 こ れ は 性 能 に 敏 感 な ア プ リ ケ ー シ ョ ン に お い て 子 プ ロ セ ス を 生 成 し て す ぐ に execve (2) す る 場 合 に 有 用 か も し れ な い 。

vfork () differs from fork (2) in that the calling thread is suspended until the child terminates (either normally, by calling _exit (2), or abnormally, after delivery of a fatal signal), or it makes a call to execve (2). Until that point, the child shares all memory with its parent, including the stack. The child must not return from the current function or call exit (3) (which would have the effect of calling exit handlers established by the parent process and flushing the parent’s stdio (3) buffers), but may call _exit (2).

fork (2) と 同 様 に 、 vfork () で 作 成 さ れ た 子 プ ロ セ ス は 、 (フ ァ イ ル デ ィ ス ク リ プ タ ー 、 シ グ ナ ル 配 送 定 義 、 カ レ ン ト ワ ー キ ン グ デ ィ レ ク ト リ な ど の ) 呼 び 出 し 元 の プ ロ セ ス の 各 種 の 属 性 を 継 承 す る 。 vfork () で は 、 上 で 説 明 し た 仮 想 ア ド レ ス 空 間 の 扱 い だ け が 異 な る 。

親 プ ロ セ ス へ 送 ら れ た シ グ ナ ル は 、 子 プ ロ セ ス が 親 プ ロ セ ス の メ モ リ ー を 解 放 し た 後 (す な わ ち 、 子 プ ロ セ ス が 終 了 す る か execve (2) を 呼 ん だ 後 ) に 到 着 す る 。

歴 史 的 な 説 明

Linux に お い て fork (2) は 書 き 込 み 時 コ ピ ー (copy-on-write) ペ ー ジ を 使 用 し て 実 装 さ れ て い る 。 そ の た め fork (2) を 使 用 す る こ と に よ っ て 被 る 損 害 は 親 プ ロ セ ス の ペ ー ジ テ ー ブ ル を 複 製 す る た め に 必 要 な 時 間 と メ モ リ ー だ け で あ る 。 し か し な が ら 、 忌 し き 昔 に は fork (2) は 呼 び 出 し た プ ロ セ ス の デ ー タ 空 間 の 全 て の コ ピ ー し て い た が 、 こ れ は し ば し ば 不 必 要 で あ っ た 。 な ぜ な ら 、 た い て い は す ぐ 後 に exec (3) を 実 行 し て い た か ら で あ る 。 こ の 場 合 の 効 率 を 上 げ る た め に BSD は vfork () シ ス テ ム コ ー ル を 導 入 し て 親 プ ロ セ ス の ア ド レ ス 空 間 を 完 全 に コ ピ ー す る か わ り に 、 execve (2) を コ ー ル す る か exit が 起 き る ま で 親 プ ロ セ ス の メ モ リ ー と 制 御 ス レ ッ ド を 借 り る よ う に し た 。 親 プ ロ セ ス は 子 プ ロ セ ス が そ の 資 源 を 使 用 し て い る 間 は 停 止 さ れ た 。 vfork () は 使 い に く い も の で あ っ た : 例 え ば 、 親 プ ロ セ ス の 変 数 を 変 更 し な い よ う に す る た め に は ど の 変 数 が レ ジ ス タ ー に 保 持 さ れ て い る か を 知 ら な け れ ば な ら な か っ た 。

準 拠

4.3BSD; POSIX.1-2001 (廃 止 予 定 と さ れ て い る )。 POSIX.1-2008 で は vfork () の 規 定 が 削 除 さ れ て い る 。

vfork () コ ー ル は 他 の オ ペ レ ー テ ィ ン グ シ ス テ ム の 同 名 の コ ー ル と ち ょ っ と 似 て い る か も し れ な い 。 規 格 が vfork () に 要 求 し て い る こ と は 、 fork (2) に 要 求 し て い る こ と よ り は 弱 い 。 し た が っ て 、 両 者 を 同 じ も の と し て 実 装 し て も 、 規 格 に 準 拠 し て い る こ と に な る 。 特 に プ ロ グ ラ マ ー は 、 子 プ ロ セ ス が 終 了 す る か execve (2) を 呼 び 出 す ま で 親 プ ロ セ ス が 停 止 し て い る こ と や 、 メ モ リ ー を 共 有 す る こ と に よ る 特 殊 な 動 作 を あ て に す べ き で は な い 。

注 意

vfork () の 動 作 は 構 造 的 な 欠 陥 と 考 え る 人 も い る だ ろ う し 、 BSD の マ ニ ュ ア ル に は 、 「 こ の シ ス テ ム コ ー ル は 妥 当 な シ ス テ ム 共 有 機 構 が 実 装 さ れ た 場 合 に は 削 除 さ れ る 。 ユ ー ザ ー は vfork () の メ モ リ ー 共 有 機 能 に 依 存 す る べ き で は な い 。 何 故 な ら ば 、 こ の シ ス テ ム コ ー ル が 削 除 さ れ た 場 合 に は 、 そ れ は fork (2) の 同 義 語 と さ れ る か ら で あ る 。 」 と 書 か れ て い る 。 し か し な が ら 、 最 近 の メ モ リ ー 管 理 ハ ー ド ウ ェ ア に よ り fork (2) と vfork () の 間 の 性 能 差 が 減 っ た と は い え 、 Linux や 他 の シ ス テ ム で vfork () が 残 さ れ て い る の に は い く つ か 理 由 が あ る :

*

性 能 に 厳 し い ア プ リ ケ ー シ ョ ン で は 、 vfork () に よ り 得 ら れ る 小 さ な 性 能 上 の メ リ ッ ト が 必 要 な 場 合 が あ る 。

*

vfork () は メ モ リ ー 管 理 ユ ニ ッ ト (MMU) を 持 た な い シ ス テ ム で も 実 装 す る こ と が で き る が 、 そ の よ う な シ ス テ ム で fork (2) を 実 装 す る こ と は で き な い 。 (POSIX.1-2008 で は vfork () が 標 準 か ら 削 除 さ れ た 。 posix_spawn (3) 関 数 の POSIX の 原 理 (rationale) に は 、 fork (2)+ exec (3) と 等 価 な 機 能 を 提 供 す る posix_spawn (3) は 、 MMU を 持 た な い シ ス テ ム で も 実 装 で き る よ う に 設 計 さ れ た と の 注 記 が あ る 。 )

*

On systems where memory is constrained, vfork () avoids the need to temporarily commit memory (see the description of /proc/sys/vm/overcommit_memory in proc (5)) in order to execute a new program. (This can be especially beneficial where a large parent process wishes to execute a small helper program in a child process.) By contrast, using fork (2) in this scenario requires either committing an amount of memory equal to the size of the parent process (if strict overcommitting is in force) or overcommitting memory with the risk that a process is terminated by the out-of-memory (OOM) killer.

Caveats

The child process should take care not to modify the memory in unintended ways, since such changes will be seen by the parent process once the child terminates or executes another program. In this regard, signal handlers can be especially problematic: if a signal handler that is invoked in the child of vfork () changes memory, those changes may result in an inconsistent process state from the perspective of the parent process (e.g., memory changes would be visible in the parent, but changes to the state of open file descriptors would not be visible).

When vfork () is called in a multithreaded process, only the calling thread is suspended until the child terminates or executes a new program. This means that the child is sharing an address space with other running code. This can be dangerous if another thread in the parent process changes credentials (using setuid (2) or similar), since there are now two processes with different privilege levels running in the same address space. As an example of the dangers, suppose that a multithreaded program running as root creates a child using vfork (). After the vfork (), a thread in the parent process drops the process to an unprivileged user in order to run some untrusted code (e.g., perhaps via plug-in opened with dlopen (3)). In this case, attacks are possible where the parent process uses mmap (2) to map in code that will be executed by the privileged child process.

Linux で の 注 意

pthread_atfork (3) を 使 っ て 設 定 さ れ た fork ハ ン ド ラ ー は NPTL ス レ ッ ド ラ イ ブ ラ リ コ ー ル を 採 用 し た マ ル チ ス レ ッ ド プ ロ グ ラ ム で は 呼 び 出 さ れ な い 。 一 方 、 LinuxThreads ス レ ッ ド ラ イ ブ ラ リ を 使 っ た プ ロ グ ラ ム で は 、 fork ハ ン ド ラ ー は 呼 び 出 さ れ る 。 (Linux の ス レ ッ ド ラ イ ブ ラ リ の 説 明 は pthreads (7) を 参 照 。 )

vfork () の 呼 び 出 し は 、 以 下 の flags を 指 定 し て clone (2) を 呼 び 出 す の と 等 価 で あ る 。

CLONE_VM | CLONE_VFORK | SIGCHLD

歴 史

vfork () シ ス テ ム コ ー ル は 3.0BSD に 現 わ れ た 。 4.4BSD に お い て fork (2) の 同 義 語 と な っ た が 、 NetBSD で は 再 び 導 入 さ れ た 。 http://www.netbsd.org/Documentation/kernel/vfork.html を 参 照 。 Linux で は 2.2.0-pre6 あ た り ま で は fork (2) と 等 価 で あ っ た 。 (i386 で は ) 2.2.0-pre9 か ら (他 の ア ー キ テ ク チ ャ ー で は 少 し 遅 れ て ) 独 立 し た シ ス テ ム コ ー ル と な っ た 。 glibc で の サ ポ ー ト は glibc-2.0.112 で 追 加 さ れ た 。

バ グ

シ グ ナ ル の 扱 い の 詳 細 は 不 明 瞭 で シ ス テ ム ご と に 異 っ て い る 。 BSD の マ ニ ュ ア ル に は 、 「 デ ッ ド ロ ッ ク 状 態 に な る 可 能 性 が あ る の で vfork () の 途 中 の 子 プ ロ セ ス に SIGTTOU SIGTTIN シ グ ナ ル を 送 信 し て は な ら な い ; さ ら に 出 力 や ioctl は 許 さ れ る が 、 入 力 を 試 み た 場 合 に は 結 果 は フ ァ イ ル 終 端 (EOF) に な る 。 」 と 書 か れ て い る 。

関 連 項 目

clone (2), execve (2), fork (2), unshare (2), wait (2)

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man-pages プ ロ ジ ェ ク ト の リ リ ー ス 5.10 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は https://www.kernel.org/doc/man-pages/ に 書 か れ て い る 。