POPEN(3)

名称
popen, pclose - 入出力処理

ライブラリ
libc

書式
#include <stdio.h> FILE * popen(const char *command, const char *type) int pclose(FILE *stream)

解説
popen() 関数は、双方向パイプフォークを作成し、シェルを起動してプロセスを “開き” ます。 親プロセスで事前に popen() を呼び出して開いたストリームは、 新しい子プロセスによってクローズされます。 以前の popen() は単方向のパイプで実装されていたため、 popen() の多くの実装は、 読み書きの両方ではなく、 type 引数が読込もしくは書込のどちらかを指定すること だけ許可していました。 現在の popen() は双方向パイプで実装しているので、 type 引数で双方向データフローを要求できます。 type 引数はヌル文字で終わる文字列のポインタで、 読取りの場合は ‘r’ 、書込みの場合は ‘w’ 、読み書きの場合は ‘r+’ である必要があります。

command 引数は、シェルコマンドラインを含む、 ヌル文字で終了する文字列のポインタです。 このコマンドは、 -c フラグで /bin/sh に渡されます。解釈がある場合、シェルで実行されます。

popen() の戻り値は通常の標準 入出力 とあらゆる点で同等のものです。 ただし、閉じるときは、 fclose() ではなく pclose() を使わなければなりません。 このようなストリームに書込むと、 コマンドの標準入力に書込まれます。 コマンドの標準出力は、 そのコマンド自体で変更しないかぎり、 popen() で呼び出したプロセスのものと同じです。 反対に、 popen() で “開かれた” ストリームからの読込みは、 コマンドの標準出力から読込まれます。 コマンドの標準入力は popen() を呼び出したプロセスのものと同じです。

出力 popen() ストリームは、デフォルトで完全にバッファ されることに注意してください。

pclose() 関数は、結び付けられたプロセスの終了を待機し、 wait4() が戻すコマンドの終了ステータスを返します。

戻り値
popen() 関数は、 fork(2) か pipe(2) でエラーが発生した場合、またはメモリを割り当てられない場合は ヌル を戻します。

pclose() 関数は、 ストリーム が popen() で “開いた” コマンドと 結び付いていなかった場合、または ストリーム がすでに pclose() で “閉じている” 場合、あるいは wait4 でエラーが発生した場合は -1 を戻します。

エラー
popen() 関数は、信頼性のある errno を設定しません。

関連項目
sh(1), fork(2), pipe(2), wait4(2), fclose(3), fflush(3), fopen(3), stdio(3), system(3)

バグ
読取り用に開いたコマンドの標準入力は、 popen() を呼び出したプロセスとシークオフセットを共有するので、 オリジナルプロセスがバッファ読取りを実行すると、 コマンドの入力位置が予想どおりにならないことがあります。 同様に、書込み用に開いたコマンドの出力は、 オリジナルプロセスのものと混ざることがあります。後者は、 popen() の前に fflush(3) を呼び出すことで回避できます。

シェルを実行しないことには、それが実行できないコマンドのシェル なのか、すぐに終了してしまうコマンドか、区別できません。 終了ステータスの 127 のみがヒントになります。

popen() の引数は常に sh(1) を呼び出し、 csh(1) は呼び出しません。

歴史
popen() 関数と pclose() 関数は、 AT&T UNIX で登場しました。

双方向機能は、 FreeBSD 2.2.6 で追加されました。