dup (システムコール)
Unix 系オペレーティング システムでは、 dup (「duplicate」の略) およびdup2システム コールによって、指定されたファイル記述子のコピーが作成されます。この新しい記述子は、実際にはコピーのように動作するのではなく、古い記述子の エイリアスのように動作します。
CライブラリPOSIX定義
dup および dup2 呼び出しは、POSIX仕様によって標準化されています。[1]ポインターと同様に (ロジックに従うと)、新しいファイル記述子は古いファイル記述子の単なるエイリアスであり、両方のファイル記述子は互換的に使用できます。 dup() システム コールの両方のファイル記述子は、同じオープン ファイル記述子を参照します。つまり、ファイル オフセットとファイル ステータス フラグを共有します。ポインターで使用されるロジック、浅いコピーまたは深いコピーまたは参照と似ていますが同一ではありません。ファイル記述子の 1 つのオフセットを変更すると、他のファイル記述子のオフセットも変更されます。 dup() を使用する場合、2 つのファイル記述子は同じファイル記述子フラグを共有しません。呼び出しプロセスでは、番号が最も小さい未使用のファイル記述子が新しいファイル記述子番号に使用されます。 dup2()システム コールを使用する場合、呼び出しの newfd 変数で指定されたファイル記述子番号を使用することを除いて dup() と同じタスクを実行します。つまり、newfd は oldfd ファイル記述子を参照するように調整されます。この関数群の最後のシステムコールはdup3()で、これはdup2()と同じですが、oldfdがnewfdと等しい場合、システムコールはEINVALエラーで失敗し、呼び出し元はフラグにO_CLOEXECを指定してclose-on-execフラグを強制的に設定できます。[2] dup3()はLinux カーネルバージョン2.6.27に正式に追加されました(glibcサポートはバージョン2.9以上で利用可能です)。
int dup ( int oldfd ); int dup2 ( int oldfd , int newfd );
前者は、open()の動作と同様に、最初に利用可能な記述子を割り当てます。ファイル記述子を指定されていない場所に複製する別の方法は、コマンドを使用したfcntlシステム コールですF_DUPFD
。
後者はコピーを newfd に配置します。newfd が開いている場合は、最初に閉じられます。
入出力リダイレクト用の dup2
Unix シェルは、入出力のリダイレクトにdup2 を使用します。 とともに、これはUnix パイプが依存するツールです。
pipe()
次の例では、Unix パイプを使用して 2 つの別々のプロセス ( program1とprogram2 )を接続するためにpipe()
と を使用します。
dup()
#include <stdio.h> #include <stdlib.h> #include <unistd.h>
/* 関数プロトタイプ */
void die ( const char * ); int main ( int argc , char ** argv ) { int pdes [ 2 ]; pid_t child ; if ( pipe ( pdes ) == -1 ) die ( "pipe()" ); child = fork (); if ( child == ( pid_t )( -1 )) die ( "fork()" ); /* fork 失敗 */ if ( child == ( pid_t ) 0 ) { /* 子プロセス */
close ( 1 ); /* stdout を閉じる */ if ( dup ( pdes [ 1 ]) == -1 ) die ( "dup()" ); /* これで stdout と pdes[1] は同等になる (dup は最も小さい空き記述子を返す) */
if (( execlp ( "program1" , "program1" , "arg1" , NULL )) == -1 ) die ( "execlp()" );
_exit ( EXIT_SUCCESS );
} else { /* 親プロセス */
close ( 0 ); /* stdinを閉じる */ if ( dup ( pdes [ 0 ]) == -1 ) die ( "dup()" );
/* これでstdinとpdes[0]は同等になります(dupは最も低い空き記述子を返します)*/
if (( execlp ( "program2" , "program2" , "arg1" , NULL )) == -1 ) die ( "execlp()" );
終了( EXIT_SUCCESS );
} 0 を返す; }
void die ( const char * msg ) { perror ( msg ); exit ( EXIT_FAILURE ); }
参照
- ファイル記述子 - その仕組みとオープンに関連するその他の機能
参考文献
- ^ "dup、dup2".オープングループ.org。
- ^ 「Linux マニュアルページ」。
- UNIX 環境における高度なプログラミング W. Richard Stevens 著ISBN 81-7808-096-6