92

dup2との使い方を理解しようとしていますdup

マニュアルページから:

DESCRIPTION

dup and dup2 create a copy of the file descriptor oldfd.
After successful return of dup or dup2, the old and new descriptors may
be used interchangeably. They share locks, file position pointers and
flags; for example, if the file position is modified by using lseek on
one of the descriptors, the position is also changed for the other.

The two descriptors do not share the close-on-exec flag, however.

dup uses the lowest-numbered unused descriptor for the new descriptor.

dup2 makes newfd be the copy of oldfd, closing newfd first if necessary.  

RETURN VALUE

dup and dup2 return the new descriptor, or -1 if an error occurred 
(in which case, errno is set appropriately).  

なぜそのシステムコールが必要なのですか?ファイル記述子を複製することの使用は何ですか?

ファイル記述子がある場合、なぜそのコピーを作成したいのですか?

dup2/dupが必要な場所について説明し、例を挙げていただければ幸いです。

ありがとう

4

4 に答える 4

50

dupシステム呼び出しは、既存のファイル記述子を複製し、同じ基になるI/Oオブジェクトを参照する新しいファイル記述子を返します。

Dupを使用すると、シェルは次のようなコマンドを実装できます。

ls existing-file non-existing-file > tmp1  2>&1

2>&1は、記述子1の複製であるファイル記述子2をコマンドに与えるようにシェルに指示します(つまり、stderrとstdoutは同じfdを指します)。これで、存在しないファイルでls
を呼び出すためのエラーメッセージと、既存のファイルでのlsの正しい出力がtmp1ファイルに表示されます。

次のサンプルコードは、パイプの読み取り端に接続された標準入力を使用してプログラムwcを実行します。

int p[2];
char *argv[2];
argv[0] = "wc";
argv[1] = 0;
pipe(p);
if(fork() == 0) {
    close(STDIN); //CHILD CLOSING stdin
    dup(p[STDIN]); // copies the fd of read end of pipe into its fd i.e 0 (STDIN)
    close(p[STDIN]);
    close(p[STDOUT]);
    exec("/bin/wc", argv);
} else {
    write(p[STDOUT], "hello world\n", 12);
    close(p[STDIN]);
    close(p[STDOUT]);
}

子は読み取り終了をファイル記述子0に複製し、pのファイル記述子を閉じ、wcを実行します。wcが標準入力から読み取る場合、パイプから読み取ります。
これは、dupを使用してパイプを実装する方法です。dupを使用すると、パイプを使用して別の何かを構築できます。これは、システムコールの美しさです。すでに存在するツールを使用して次々に構築します。これらのツールは、他の何かなど..最後に、システムコールはカーネルで取得する最も基本的なツールです

乾杯 :)

于 2012-07-24T17:20:56.737 に答える
19

ファイル記述子を複製するもう1つの理由は、ファイル記述子を。と一緒に使用することfdopenです。fcloseに渡されたファイル記述子を閉じるfdopenため、元のファイル記述子を閉じたくない場合は、dup最初にそれを複製する必要があります。

于 2012-07-24T17:53:09.897 に答える
4

dup/dup2に関連するいくつかの点に注意してください

dup / dup2-技術的な目的は、異なるハンドルによって単一のプロセス内で1つのファイルテーブルエントリを共有することです。(フォークしている場合、記述子はデフォルトで子プロセスで複製され、ファイルテーブルエントリも共有されます)。

つまり、dup / dup2関数を使用して、1つの開いているファイルテーブルエントリに対して異なる属性を持つ可能性のある複数のファイル記述子を持つことができます。

(現在、FD_CLOEXECフラグのみがファイル記述子の唯一の属性であるように見えますが)。

http://www.gnu.org/software/libc/manual/html_node/Descriptor-Flags.html

dup(fd) is equivalent to fcntl(fd, F_DUPFD, 0);

dup2(fildes, fildes2); is equivalent to 

   close(fildes2);
   fcntl(fildes, F_DUPFD, fildes2);

違いは(最後に)-いくつかのerrno値を除いて、dup2とfcntl closeの後にfcntlが続くと、2つの関数呼び出しが含まれるため、競合状態が発生する可能性があります。

詳細はhttp://pubs.opengroup.org/onlinepubs/009695399/functions/dup.htmlから確認できます 。

使用例-

シェルでジョブ制御を実装する際の興味深い例の1つで、dup/dup2の使用を以下のリンクで確認できます。

http://www.gnu.org/software/libc/manual/html_node/Launching-Jobs.html#Launching-Jobs

于 2012-07-24T19:01:43.007 に答える
4

dupは、プロセスからの出力をリダイレクトできるようにするために使用されます。

たとえば、プロセスからの出力を保存する場合は、出力を複製し(fd = 1)、複製したfdをファイルにリダイレクトしてから、フォークしてプロセスを実行し、プロセスが終了したら、再度リダイレクトします。 fdを出力に保存しました。

于 2012-07-24T16:27:53.257 に答える