web-dev-qa-db-ja.com

誰かがCのdup()が何をしているのか説明できますか?

Dup、dup2、dup3「ファイル記述子oldfdのコピーを作成する」(manページから)と知っています。しかし、私はそれを消化することができません。

私が知っているように、ファイル記述子はファイルの場所とその方向(入力/出力)を追跡するためのnumbersです。それだけの方が簡単ではないでしょうか

fd=fd2;

ファイル記述子を複製したいときはいつですか?

そして、何か他のもの。

dup()は、新しい記述子に、番号が最も小さい未使用の記述子を使用します。

これは、値stdinstdoutまたはstderrclose()-edのいずれかがそれら?

20
Pithikos

少し実験した後、2番目の質問で自分に返答したかっただけです。

答えは[〜#〜] yes [〜#〜]です。 stdin、stdout、またはstderrが閉じている場合、作成するファイル記述子の値は0、1、2になります。

例:

close(1);     //closing stdout
newfd=dup(1); //newfd takes value of least available fd number

これがファイル記述子に起こる場所:

0 stdin     .--------------.     0 stdin     .--------------.     0 stdin
1 stdout   =|   close(1)   :=>   2 stderr   =| newfd=dup(1) :=>   1 newfd
2 stderr    '--------------'                 '--------------'     2 stderr
15
Pithikos

ファイル記述子は、数より少し多いです。また、さまざまな半隠し状態(開いているかどうか、どのファイルの説明を参照しているか、いくつかのフラグも含む)も保持します。 dupはこの情報を複製するので、たとえば2つの記述子を個別に閉じます。 fd=fd2 ではない。

11
n.m.

Dup()の最も重要なことは、新しいファイル記述子に使用できる最小の整数を返すことです。これがリダイレクトの基本です。

int fd_redirect_to = open("file", O_CREAT);
close(1); /* stdout */
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */
close(fd_redirect_to); /* we don't need this */

この後、ファイル記述子1(stdout)に何かが書き込まれると、魔法のように「ファイル」に入ります。

6
SzG

シェルプログラムを作成していて、実行するプログラムでstdinとstdoutをリダイレクトするとします。次のようになります。

fdin = open(infile, O_RDONLY);
fdout = open(outfile, O_WRONLY);
// Check for errors, send messages to stdout.
...
int pid = fork(0);
if(pid == 0) {
    close(0);
    dup(fdin);
    close(fdin);
    close(1);
    dup(fdout);
    close(fdout);
    execvp(program, argv);
}
// Parent process cleans up, maybe waits for child.
...

dup2()は、close()dup()を次のように置き換えることができる、もう少し便利な方法です。

dup2(fdin, 0);
dup2(fdout, 1);

これを実行する理由は、エラーをstdout(またはstderr)に報告して、それらを閉じて子プロセスで新しいファイルを開くだけで済むようにするためです。第2に、open()呼び出しのいずれかがエラーを返した場合、フォークを行うのは無駄です。

5

これを参照してください ページ 、stdoutはdup(1)...としてエイリアス化できます.

2
Karel Frajták

dup()およびdup2()システムコール

•dup()システムコールは、開いているファイル記述子を複製し、新しいファイル記述子を返します。

•新しいファイル記述子には、元のファイル記述子と共通の次のプロパティがあります。1.同じ開いているファイルまたはパイプを指します。 2.同じファイルポインターを持っている-つまり、両方のファイル記述子が1つのファイルポインターを共有します。 3.読み取り、書き込み、または読み取りと書き込みにかかわらず、同じアクセスモードを使用します。

•dup()は、利用可能な最小の整数値を持つファイル記述子を返すことが保証されています。これは、プロセスがI/Oリダイレクトを実行するために、利用可能な最小の未使用のファイル記述子を返すこの機能のためです。

int dup(file_descriptor)

int dup2(file_descriptor1、file_descriptor2)

0
Mahendra suthar

"標準出力の複製"に関するヒントです。

一部のUnixシステム(ただし、GNU/Linuxは除く)

fd = open("/dev/fd/1", O_WRONLY);

これは次と同等です。

fd = dup(1);
0
b3h3m0th

例:

_close(1);     //closing stdout
newfd=dup(1); //newfd takes value of least available fd number
_

これがファイル記述子に起こる場所:

_0 stdin     .--------------.     0 stdin     .--------------.     0 stdin
1 stdout   =|   close(1)   :=>   2 stderr   =| newfd=dup(1) :=>   1 newfd
2 stderr    '--------------'                 '--------------'     2 stderr
_

もう一度質問がありました。どうすればすでに閉じたファイル記述子をdup()できますか?

標準に準拠していないため、上記の実験で示された結果が得られたとは思いません。 dup

の 重複()関数は次の場合に失敗します:

[EBADF]
の フィルデス 引数は有効なオープンファイル記述子ではありません。

したがって、表示されたコードシーケンスの後、newfdは_1_ではなく、_-1_およびerrnoEBADFである必要があります。

0
Armali