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);
これらのシステムコールは、ファイル・ディスクリプタ
oldfd の複製を作る。
dup()
は最も小さい番号の未使用のディスクリプタを
新しいディスクリプタとして使用する。
dup2() は
newfd を
oldfd
の複製として作成する。
必要であれば最初に
newfd をクローズする。
以下の点に注意すること。
- *
- oldfd
が有効なファイルディスクリプタでない場合、その呼び出しは失敗し、
newfd
はクローズされない。
- *
- oldfd
が有効なファイルディスクリプタで、
newfd が oldfd
と同じ値の場合、
dup2() は何もせず、
newfd を返す。
これらのシステムコールのいずれかが成功を返した場合には、
古いファイル・ディスクリプタと新しいファイル・ディスクリプタは
互いに可換なものとして使うことができる。
2つのファイル・ディスクリプタは同じファイル記述
(description) (
open(2) 参照)
を参照しており、したがってファイルオフセットやファイル状態フラグが
共有される。例えば、一方のディスクリプタに対して
lseek(2)
を使ってファイルオフセットを変更した場合、もう一方のディスクリプタの
オフセットも変化する。
2つのディスクリプタはファイル・ディスクリプタ・フラグ
(close-on-exec flag)
を共有しない。複製されたディスクリプタの
close-on-exec flag (
fcntl(2) 参照) は off
となる。
dup3() は
dup2()
と同じだが、以下の点が異なる。
- *
- 呼び出し元が、新しいファイル・ディスクリプタに対して
close-on-exec
フラグを強制的に設定することができる。
これを行うには、
flags に O_CLOEXEC
を指定する。
このフラグが役に立つ理由については、
open(2) の O_CLOEXEC
フラグの説明を参照のこと。
- *
- oldfd が newfd
と同じ場合、 dup3() は
EINVAL
エラーで失敗する。
返り値¶
成功すると、これらのシステムコールは新しいディスクリプタを返す。
エラーの場合、-1
を返し、
errno
を適切に設定する。
エラー¶
- EBADF
- oldfd
がオープンされたファイル・ディスクリプタでないか、
newfd
がファイル・ディスクリプタとして許される範囲から外れている。
- EBUSY
- (Linux のみ) open(2) や
dup()
との競合状態の場合に、
dup2() や dup3()
はこのエラーを返すかもしれない。
- EINTR
- dup2() や dup3()
の呼び出しがシグナルにより割り込まれた。
signal(7) 参照。
- EINVAL
- (dup3()) flags
に無効な値が入っている。
もしくは、 oldfd が
newfd
と同じであった。
- EMFILE
- プロセスがすでにオープンできる最大数までファイル・ディスクリプタ
を開いていて、さらに新しいものを開こうとした。
バージョン¶
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() や
dup3()
を使う前に先ず
newfd
をクローズするようにした方がいいだろう。
関連項目¶
close(2),
fcntl(2),
open(2)
この文書について¶
この man ページは Linux
man-pages
プロジェクトのリリース
3.41 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。