2つのディスクリプタはファイルディスクリプタフラグ (close\-on\-exec flag) を共有しない。複製されたディスクリプタの
close\-on\-exec flag (\fBfcntl\fP(2) 参照) は off となる。
.SS dup2()
-The \fBdup2\fP() system call performs the same task as \fBdup\fP(), but instead
-of using the lowest\-numbered unused file descriptor, it uses the descriptor
-number specified in \fInewfd\fP. If the descriptor \fInewfd\fP was previously
-open, it is silently closed before being reused.
+\fBdup2\fP() システムコールは \fBdup\fP() と同じ処理を実行するが、
+番号が最も小さい未使用のファイルディスクリプタを使用する代わりに、
+\fInewfd\fP で指定されたディスクリプタ番号を使用する。
+ディスクリプタ \fInewfd\fP が以前にオープンされていた場合には、
+黙ってそのディスクリプタをクローズしてから再利用する。
-The steps of closing and reusing the file descriptor \fInewfd\fP are performed
-\fIatomically\fP. This is important, because trying to implement equivalent
-functionality using \fBclose\fP(2) and \fBdup\fP() would be subject to race
-conditions, whereby \fInewfd\fP might be reused between the two steps. Such
-reuse could happen because the main program is interrupted by a signal
-handler that allocates a file descriptor, or because a parallel thread
-allocates a file descriptor.
+ファイルディスクリプタ \fInewfd\fP をクローズして再利用する処理は
+\fIアトミック(不可分)に\fP実行される。これは重要な点である。 なぜなら、
+等価な機能を \fBclose\fP(2) と \fBdup\fP() を使って実装しようとすると、
+2 つの処理の間に \fInewfd\fP が再利用されてしまうという、
+競合状態にさらされることになるからだ。
+このような再利用が起こるのは、
+メインプログラムがファイルディスクリプタを割り当てる
+シグナルハンドラーにより割り込まれたり、並行動作するスレッドが
+ファイルディスクリプタを割り当てたりすることがあるからだ。
以下の点について注意すること:
.IP * 3
\fInewfd\fP が範囲を超えた時に返されるエラーは、 \fBdup2\fP() と \fBfcntl(\fP..., \fBF_DUPFD\fP, ...\fB)\fP
では異っている。 \fBdup2\fP() が \fBF_DUPFD\fP と同じように \fBEINVAL\fP を返すシステムもある。
-If \fInewfd\fP was open, any errors that would have been reported at
-\fBclose\fP(2) time are lost. If this is of concern, then\(emunless the
-program is single\-threaded and does not allocate file descriptors in signal
-handlers\(emthe correct approach is \fInot\fP to close \fInewfd\fP before calling
-\fBdup2\fP(), because of the race condition described above. Instead, code
-something like the following could be used:
+\fInewfd\fP がオープンされていた場合、
+\fBclose\fP(2) 時に報告されることになるエラーはすべて失われる。
+これが心配で、シングルスレッドかつシグナルハンドラーで
+ファイルディスクリプタを割り当てるようなプログラムでない場合には、
+正しい方法は \fBdup2\fP() を呼び出す前に
+\fInewfd\fP をクローズ「しない」ことである。
+なぜなら、上で説明した競合状況があるからである。
+代わりに、以下のようなコードが使用できることだろう。
.nf
- /* Obtain a duplicate of 'newfd' that can subsequently
- be used to check for close() errors; an EBADF error
- means that 'newfd' was not open. */
+ /* あとで close() エラーをチェックするのに使用できる
+ ように 'newfd' の複製を取得する。 EBADF エラーは
+ 'newfd' がオープンされていないことを意味する。 */
tmpfd = dup(newfd);
if (tmpfd == \-1 && errno != EBADF) {
- /* Handle unexpected dup() error */
+ /* 予期しない dup() のエラーを処理する */
}
- /* Atomically duplicate 'oldfd' on 'newfd' */
+ /* アトミックに 'oldfd' を 'newfd' に複製する */
if (dup2(oldfd, newfd) == \-1) {
- /* Handle dup2() error */
+ /* dup2() のエラーを処理する */
}
- /* Now check for close() errors on the file originally
- referred to by 'newfd' */
+ /* ここでもともと 'newfd' で参照されていたファイルの
+ close() エラーをチェックする */
if (tmpfd != \-1) {
if (close(tmpfd) == \-1) {
- /* Handle errors from close */
+ /* close からのエラーを処理する */
}
}
.fi