質問
解決
一つの例の使用は、I / Oリダイレクションだろう。このためには、子プロセスをforkし、標準入力や標準出力ファイルディスクリプタ(0と1)を閉じて、あなたは(DUPを実行します)今、この中で最低の利用可能なファイル記述子にマップされます選択した別のファイル記述子にケース0又は1である。
あなたが今、あなたのアプリケーションの可能性を知らないで、子供がデータではなく提供のファイル記述子に書き込まれます(設定済みのものは何でも、または標準入力から読み込み)標準出力に書き込まれたときに、すべての子プロセスをexecしことができます。
シェルは、例えば、パイプでコマンドを実装するためにこれを使用します他の標準入力1つのプロセスの標準出力を接続することにより/bin/ls | more
。
他のヒント
dup と dup2 を理解するための最良のシナリオはリダイレクトです。
まず知っておく必要があるのは、システムには入出力を処理する 3 つのデフォルトのファイル ID (または出力ソースまたは入力ソースを示す変数) があるということです。彼らです stdin
, stdout
, stderr
, 、整数では次のようになります。 0
,1
,2
. 。ほとんどの機能は次のようなものです fprintf
または cout
に直接出力されます stdout
.
出力をリダイレクトしたい場合の 1 つの方法は、たとえば次のとおりです。 fprintf
関数のその他の引数を示す in
そして out
.
ただし、よりエレガントな方法があります。デフォルトのファイル ID を上書きして、出力を受け取りたいファイルを指すようにすることができます。 dup
そして dup2
まさにこの状況で機能します。
簡単な例を 1 つ挙げてみましょう。の出力をリダイレクトしたいとします。 fprintf
「chinaisbetter.txt」という名前の txt ファイルに保存します。まず最初にこのファイルを開く必要があります
int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);
それなら私たちが欲しいのは stdout
dup 関数を使用して「chinaisbetter.txt」をポイントするには、次のようにします。
dup2(fw,1);
stdout(1) は、まだ 1 であっても「chinaisbetter.txt」の記述子を指しますが、出力はリダイレクトされます。
その後、使用できます printf
通常どおりですが、結果は画面に直接表示されるのではなく、txt ファイルに表示されます。
printf("Are you kidding me? \n");
PS:
これは直感的に説明しているだけなので、マンページや詳細情報を確認する必要がある場合があります。実際、ここでは「コピー」と言っていますが、すべてをコピーしているわけではありません。
ここでのファイル ID は、ファイルのハンドラーを指します。上記のファイル記述子は、ファイルの情報を記録する構造体です。
ときに気になPOSIX機能、特にそうな複製、一般的に良い チェックを標準そのもの.下部まで通常は例を見などの背後にある実装(存在)であるといえる。
この場合:
次のセクションは勉強になりました。
例
替を標準出力に出力ファイル
以下の例を閉じを標準出力に出力は、現在のプロセスの再割を標準出力に出力へのファイルによって参照される pfd
, 閉じるオリジナルファイル記述子です。
#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...
替エラーメッセージ
次の例は、リダイレクトからのメッセージ stderr
へ stdout
.
#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...
アプリケーションの使用状況
します。
格付の理由
の dup()
や dup2()
機能は冗長となります。そのサービスの提供を行っていますの fcntl()
機能です。てこの量IEEE Std1003.1-2001年主として歴史的な理由により、多くの既存アプリケーションを使用します。
なに簡単なコードセグメントは非常に類似する行動 dup2()
, は、不適合の実装に基づくその他の機能を定め、この量IEEE Std1003.1-2001年には、大きく複雑になります。少なくとも明らかなので、効果の信号をキャッチ機能が呼び出された間配分を行いまたはを修復させようとするとエラーがファイル記述子.こうすることを確認することにより、ブロック信号。
の dup2()
機能のマークがありませんobsolescentができるタイプの安全版で提供される機能には、型、安全でないバージョン fcntl()
.に使用されるのはPOSIX Adaに結合する。
の dup2()
機能は使用できませんで重要な地域としての同期機構。
の説[EBADF]の場合のファイルズ半島が外れる範囲には、指定された場合のファイルズ半島は有効になります。記述のための fildes
や fildes2
が異なるためだけのような無効との関連 fildes2
かどうかが範囲外である;それは、問いませんか fildes2
とはファイルを開く場合に dup2()
呼び出しを実行します.
今後の方向性
します。
参照
close()
, fcntl()
, open()
, 基準の定義量IEEE Std1003.1-2001年 <unistd.h>
変更履歴
初公開の課題1.由来の課題1のSVID.
実用的な一例としては、いくつかのログファイルのようないくつかの他のストリームに出力メッセージをリダイレクトしています。ここではI / Oリダイレクションのためのサンプルコードです。
ここのオリジナルのポストのを参照してください。
#include <stdio.h>
main()
{
int fd;
fpos_t pos;
printf("stdout, ");
fflush(stdout);
fgetpos(stdout, &pos);
fd = dup(fileno(stdout));
freopen("stdout.out", "w", stdout);
f();
fflush(stdout);
dup2(fd, fileno(stdout));
close(fd);
clearerr(stdout);
fsetpos(stdout, &pos); /* for C9X */
printf("stdout again\n");
}
f()
{
printf("stdout in f()");
}
I /シェルにおけるOリダイレクションは、最も可能性の高いdup2の/ fcnltシステムコールを使用して実装されるだろう。
私たちは、簡単にdup2の機能を使用したリダイレクトの$program 2>&1 > logfile.log
タイプをエミュレートすることができます。
以下のプログラムは、両方のstdoutとstderr .i.eがdup2のを使用して$program 2>&1 > output
の挙動をエミュレートリダイレクトします。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int
main(void){
int close_this_fd;
dup2(close_this_fd = open("output", O_WRONLY), 1);
dup2(1,2);
close(close_this_fd);
fprintf(stdout, "standard output\n");
fprintf(stderr, "standard error\n");
fflush(stdout);
sleep(100); //sleep to examine the filedes in /proc/pid/fd level.
return;
}
vagrant@precise64:/vagrant/advC$ ./a.out
^Z
[2]+ Stopped ./a.out
vagrant@precise64:/vagrant/advC$ cat output
standard error
standard output
vagrant@precise64:/vagrant/advC$ ll /proc/2761/fd
total 0
dr-x------ 2 vagrant vagrant 0 Jun 20 22:07 ./
dr-xr-xr-x 8 vagrant vagrant 0 Jun 20 22:07 ../
lrwx------ 1 vagrant vagrant 64 Jun 20 22:07 0 -> /dev/pts/0
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 1 -> /vagrant/advC/output
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 2 -> /vagrant/advC/output