stdin, stdout, stderr -
標準入出力ストリーム
#include <stdio.h>
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
標準の環境では、 UNIX
プログラムは起動時に、オープンされているストリー
ムを 3
つ与えられる。それぞれ入力用、出力用、診断メッセージやエラーメッ
セージの表示用のものである。これらは通常ユーザーの端末
(
tty(4) を参照)
に接続されているが、親プロセスでの選択・設定によってファイル
や他のデバイスに関連づけられていることもある
(
sh(1)
の「リダイレクション」セクションも参照のこと)。
入力ストリームは "standard
input"
と呼ばれる。出力ストリームは
"standard
output"、エラーストリームは
"standard error" と呼ばれる。
これらの用語を短縮したものがそれぞれのファイルを示すシンボルとなる。つ
まり
stdin,
stdout,
stderr
である。
これらのシンボルは
stdio(3) のマクロで、 FILE
へのポインター型である。したがって
fprintf(3) や
fread(3)
などの関数とともに用いることができる。
FILE は UNIX
のファイルディスクリプターにバッファー機能を追加したラッパー
であるから、これらのマクロにも対応するファイルがあり、
UNIX の raw ファ
イルインターフェース
(
read(2) や
lseek(2) など)
によってアクセスすることもできる。
プログラムの起動時には、
ストリーム
stdin,
stdout,
stderr
に結びつけられているファイルディスクリプターの番号は、
それぞれ 0, 1, 2 である。
プリプロセッサシンボル
STDIN_FILENO,
STDOUT_FILENO,
STDERR_FILENO は
<unistd.h>
中でそれぞれこれらの値に定義されている。
(これらのストリームに対して
freopen(3)
を適用することで、そのストリームに関連付けられたファイルディスクリプター
の番号を変更することができる。)
FILE と raw
なファイルディスクリプターの併用は、予期できない結果を生じ
ることがあるので、通常は避けるべきである。
(マゾヒスティックな人に:
POSIX.1 のセクション 8.2.3
には、この混用で動作がどのようになりそう
かが詳しく記述されている。)
一般的なルールは以下の通り:
ファイルディスクリプターはカーネルによって
扱われ、 stdio
は単にライブラリによって扱われるのである。すなわち例えば
exec(3)
の後には、子プロセスはオープンされているファイルディスクリプター
をすべて継承するが、親からのストリームはすべてアクセス不可となる。
シンボル
stdin,
stdout,
stderr
はすべてマクロとして定義されているので、これらへの代入
は移植性を保証されない。標準ストリームはライブラリ関数
freopen(3)
を用いれば、別のファイルを示すように変更することもできる。
このライブラリ関数は
stdin,
stdout,
stderr
の再割り当てが可能なように特別に導入されたものである。
標準ストリームは
exit(3)
の呼び出しと、プログラムの正常終了によってクローズされる。
stdin,
stdout,
stderr マクロは C89
に準拠している。
また C89 では、これら 3
つのストリームがプログラム
の起動時にオープンされているべきであることが規定されている。
stderr
ストリームはバッファーリングされていない。
stdout
ストリームは、端末に接続されているときには行単位でバッファーリング
されている。一行に満たない内容は、
fflush(3) か
exit(3)
が呼び出されるか、改行文字が印字されるまで表示されない。これは、
特にデバッグ時において、予期しない結果を生じる原因となるかもしれない。
標準ストリームの
(あるいは他のすべてのストリームの)
バッファーリングモードは、
setbuf(3) または
setvbuf(3)
を呼び出すことによって変更できる。
ただし、
stdin
が端末に接続されているときは、端末のドライバでバッファーリングされている
可能性がある点にも注意すること。これは
stdio
のバッファーリングとは全く
関係なく存在しうる。
(実際、通常だと端末入力はカーネルによって行単位
でバッファーリングされている。)
このカーネルによる入力の扱いは
tcsetattr(3)
などの呼び出しによって変更することができる。
stty(1) と
termios(3)
も参照すること。
csh(1),
sh(1),
open(2),
fopen(3),
stdio(3)
この man ページは Linux
man-pages
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。