2012-01-31 22 views
23

引数を指定するとstdoutをファイルにリダイレクトするか、stdinをファイルから読み込みます。これを行うには、stdoutまたはstdinに関連付けられているファイル記述子を閉じます。そのファイルを開くと、ただ閉じたディスクリプタの下に開きます。これはうまくいきますが、問題が解決すると、stdoutとstdinを元に戻す必要があります。stdoutとstdinファイル記述子を閉じた後で再オープン

私がstdoutのためにできることはopen( "/ dev/tty"、O_WRONLY)です。しかし、なぜこれが機能するのか分かりませんし、もっと重要なのは、stdinの同等のステートメントがわからないことです。

だから私は標準出力

close(1); 
if (creat(filePath, O_RDWR) == -1) 
{ 
    exit(1); 
} 

close(0); 
if (open(filePath, O_RDONLY) == -1) 
{ 
    exit(1); 
} 
+2

man 'dup'と' dup2' –

+0

'O_RDWR'は' open' 'flags'パラメータの' creat' 'mode'パラメータではありません。 –

答えて

34

dup()とdup2()を使用してファイル記述子をクローンする必要があります。

int stdin_copy = dup(0); 
int stdout_copy = dup(1); 
close(0); 
close(1); 

int file1 = open(...); 
int file2 = open(...); 

< do your work. file1 and file2 must be 0 and 1, because open always returns lowest unused fd > 

close(file1); 
close(file2); 
dup2(stdin_copy, 0); 
dup2(stdout_copy, 1); 
close(stdin_copy); 
close(stdout_copy); 

しかし、あなたは(から男性DUP)に注意してくださいすることがありますマイナーな詳細があります:

2つのディスクリプタが共有していないが、ファイルディスクリプタのフラグ( 近いオンexecflag) 。重複記述子のclose-on-execフラグ(FD_CLOEXEC; fcntl(2)参照) はオフです。

これが問題であるならば、あなたは(おそらくdup3を使用して、close-on-execフラグを復元する必要がある場合があります)の代わりにdup2のの()競合状態を避けるために。

また、プログラムがマルチスレッドの場合、他のスレッドが誤って再マッピングされたstdin/stdoutに書き込み/読み込みする可能性があることに注意してください。

+0

ありがとう、これは本当に私を助けた! –

+2

マルチスレッドの場合、他のスレッドが 'close(0)'(または 'close(1)')と対応する 'open(...)'の間でファイルを開くと、そのファイルstdin(またはstdout)になります。 「最も未使用の」動作に頼るのではなく、ファイル記述子を強制的に0(または1)にするには、 'dup2()'または 'dup3'を使う方がはるかに優れています。 – psmears

14

を標準入力のために、私はあなたがをリダイレクトする前に記述子を "保存" することができると思うのために、持っている:

int save_in, save_out; 

save_in = dup(STDIN_FILENO); 
save_out = dup(STDOUT_FILENO); 

後でdup2を使用して復元することができます。

/* Time passes, STDIN_FILENO isn't what it used to be. */ 
dup2(save_in, STDIN_FILENO); 

私はその一例でチェックエラーは致しておりません - あなたがする必要があります。

0

子プロセスを作成し、子プロセス内でのみリダイレクトを設定することができます。その後、子プロセスが終了するのを待って、親プロセスで作業を続行します。そうすれば、リダイレクトを全く逆にすることについて心配する必要はありません。

fork()とwait()を使用してコードの例を探してください。

関連する問題