名前
stdin, stdout, stderr - 標準 I/O ストリーム
書式
.Fd #include <stdio.h>
.Fd extern FILE *stdin;
.Fd extern FILE *stdout;
.Fd 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の後には、子プロセスはオープンされているファイルディスクリプタ をすべて継承するが、親からのストリームはすべてアクセス不可となる。
シンボル stdin, stdout, stderr はすべてマクロとして定義されているので、これらへの代入 は移植性を保証されない。標準ストリームはライブラリ関数 freopen(3) を用いれば、別のファイルを示すように変更することもできる。 このライブラリ関数は stdin, stdout, stderr の再割り当てが可能なように特別に導入されたものである。 標準ストリームは exit(3) の呼び出しと、プログラムの正常終了によってクローズされる。
考察
stderr ストリームはバッファリングされていない。 stdout ストリームは、端末に接続されているときには行単位でバッファリングされて いる。一行に満たない内容は、 fflush(3) か exit(3) が呼び出されるか、改行文字が印字されるまで表示されない。これは、特にデ バッグ時において、予期しない結果を生じる原因となるかもしれない。 標準ストリームの (あるいは他のすべてのストリームの) バッファリングモードは、 setbuf(3) または setvbuf(3) を呼び出すことによって変更できる。 ただし stdin が端末に接続されているときは、端末のドライバでバッファリングされている 可能性がある点にも注意すること。これは stdio のバッファリングとは全く 関係なく存在しうる。 (実際、通常だと端末入力はカーネルによって行単位 でバッファリングされている。) このカーネルによる入力の扱いは tcsetattr(3) などの呼び出しによって変更することができる。 stty(1) と termios(3) も参照すること。
準拠
stdin, stdout, stderr マクロは -ansiC に準拠している。また ANSI C では、これら 3 つのストリームがプログラム の起動時にオープンされているべきであることが規定されている。