Provided by: manpages-ja-dev_0.5.0.0.20180315+dfsg-1_all
名前
dup, dup2, dup3 - ファイルディスクリプターを複製する
書式
#include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); #define _GNU_SOURCE /* feature_test_macros(7) 参照 */ #include <fcntl.h> /* 定数 O_* の定義の取得 */ #include <unistd.h> int dup3(int oldfd, int newfd, int flags);
説明
dup() システムコールは、 ファイルディスクリプター oldfd のコピーを作成し、 最も小さい番号 の未使用のディスクリプターを 新しいディスクリプターとして使用する。 成功が返された場合には、 古いファイルディスクリプターと新しいファイルディスクリプターは 互 いに可換なものとして使うことができる。 2つのファイルディスクリプターは同じファイル記述 (description) (open(2) 参照) を参照しており、したがってファイルオフセットやファイル状態 フラグが 共有される。例えば、一方のディスクリプターに対して lseek(2) を使ってファイルオフ セットを変更した場合、もう一方のディスクリプターの オフセットも変化する。 2つのディスクリプターはファイルディスクリプターフラグ (close-on-exec flag) を共有しな い。複製されたディスクリプターの close-on-exec flag (fcntl(2) 参照) は off となる。 dup2() dup2() システムコールは dup() と同じ処理を実行するが、 番号が最も小さい未使用のファイル ディスクリプターを使用する代わりに、 newfd で指定されたディスクリプター番号を使用する。 ディスクリプター newfd が以前にオープンされていた場合には、 黙ってそのディスクリプターをク ローズしてから再利用する。 ファイルディスクリプター newfd をクローズして再利用する処理は アトミック(不可分)に実行され る。これは重要な点である。 なぜなら、 等価な機能を close(2) と dup() を使って実装しようと すると、 2 つの処理の間に newfd が再利用されてしまうという、 競合状態にさらされることにな るからだ。 このような再利用が起こるのは、 メインプログラムがファイルディスクリプターを割り 当てる シグナルハンドラーにより割り込まれたり、並行動作するスレッドが ファイルディスクリプ ターを割り当てたりすることがあるからだ。 以下の点について注意すること: * oldfd が有効なファイルディスクリプターでない場合、その呼び出しは失敗し、 newfd はクロー ズされない。 * oldfd が有効なファイルディスクリプターで、 newfd が oldfd と同じ値の場合、 dup2() は何 もせず、 newfd を返す。 dup3() dup3() は dup2() と同じだが、以下の点が異なる。 * 呼び出し元が、新しいファイルディスクリプターに対して close-on-exec フラグを強制的に設定 することができる。 これを行うには、 flags に O_CLOEXEC を指定する。 このフラグが役に立 つ理由については、 open(2) の O_CLOEXEC フラグの説明を参照のこと。 * oldfd が newfd と同じ場合、 dup3() は EINVAL エラーで失敗する。
返り値
成功すると、これらのシステムコールは新しいディスクリプターを返す。 エラーの場合、-1 を返 し、 errno を適切に設定する。
エラー
EBADF oldfd がオープンされたファイルディスクリプターではない。 EBADF newfd がファイルディスクリプターとして許可されている範囲ではない (getrlimit(2) の RLIMIT_NOFILE の議論を参照)。 EBUSY (Linux のみ) open(2) や dup() との競合状態の場合に、 dup2() や dup3() はこのエ ラーを返すかもしれない。 EINTR dup2() や dup3() の呼び出しがシグナルにより割り込まれた。 signal(7) 参照。 EINVAL (dup3()) flags に無効な値が入っている。 EINVAL (dup3()) oldfd が newfd と同じであった。 EMFILE プロセスがすでにオープンできる最大数までファイルディスクリプター を開いていて、さら に新しいものを開こうとした (getrlimit(2) のリソース上限 RLIMIT_NOFILE を参照)。
バージョン
dup3() はバージョン 2.6.27 で Linux に追加された。 glibc によるサポートはバージョン 2.9 以降で利用できる。
準拠
dup(), dup2(): SVr4, 4.3BSD, POSIX.1-2001. dup3() は Linux 固有である。
注意
newfd が範囲を超えた時に返されるエラーは、 dup2() と fcntl(..., F_DUPFD, ...) では異って いる。 dup2() が F_DUPFD と同じように EINVAL を返すシステムもある。 newfd がオープンされていた場合、 close(2) 時に報告されることになるエラーはすべて失われる。 これが心配で、シングルスレッドかつシグナルハンドラーで ファイルディスクリプターを割り当て るようなプログラムでない場合には、 正しい方法は dup2() を呼び出す前に newfd をクローズ「し ない」ことである。 なぜなら、上で説明した競合状況があるからである。 代わりに、以下のような コードが使用できることだろう。 /* あとで close() エラーをチェックするのに使用できる ように 'newfd' の複製を取得する。 EBADF エラーは 'newfd' がオープンされていないことを意味する。 */ tmpfd = dup(newfd); if (tmpfd == -1 && errno != EBADF) { /* 予期しない dup() のエラーを処理する */ } /* アトミックに 'oldfd' を 'newfd' に複製する */ if (dup2(oldfd, newfd) == -1) { /* dup2() のエラーを処理する */ } /* ここでもともと 'newfd' で参照されていたファイルの close() エラーをチェックする */ if (tmpfd != -1) { if (close(tmpfd) == -1) { /* close からのエラーを処理する */ } }
関連項目
close(2), fcntl(2), open(2)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。