Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       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 が有効なファイルディスクリプターで、 newfdoldfd と同じ値の場合、 dup2()  は何
          もせず、 newfd を返す。

   dup3()
       dup3()  は dup2()  と同じだが、以下の点が異なる。

       *  呼び出し元が、新しいファイルディスクリプターに対して close-on-exec フラグを強制的に設定
          することができる。 これを行うには、 flagsO_CLOEXEC を指定する。  このフラグが役に立
          つ理由については、 open(2)  の O_CLOEXEC フラグの説明を参照のこと。

       *  oldfdnewfd と同じ場合、 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()) oldfdnewfd と同じであった。

       EMFILE The per-process limit on the number of open file descriptors has been reached  (see
              the discussion of RLIMIT_NOFILE in getrlimit(2)).

バージョン

       dup3()   はバージョン  2.6.27 で Linux に追加された。 glibc によるサポートはバージョン 2.9
       以降で利用できる。

準拠

       dup(), dup2(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

       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), pidfd_getfd(2)

この文書について

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