popen, pclose - プロセスとの入力/出力用のパイプストリーム
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
popen(), pclose():
_POSIX_C_SOURCE >= 2
|| /* glibc 2.19 以前: */ _BSD_SOURCE || _SVID_SOURCE
popen() 関数は、プロセスをオープンする。具体的には、 パイプを生成し、フォークを行い、シェルを起動する。 定義から分かるように、パイプは一方向なので、 type 引数には読み込みか書き込みのどちらか一方だけを指定できる (両方は指定できない)。 生成されるストリームは、この指定に対応して、読み取り専用または 書き込み専用のいずれかとなる。
command 引数は、シェルのコマンドラインを含むヌル終端された文字列へのポインターである。 このコマンドは -c フラグを用いて /bin/sh に渡される。 コマンドの解釈は (もし必要ならば) シェルによって行われる。
type 引数は、ヌル終端された文字列へのポインターで、 読み込みを示す文字 'r' か、書き込みを示す文字 'w' の どちらか一方を指定しなければならない。 glibc 2.9 以降では、この引数に文字 'e' を追加で指定できる。 文字 'e' を指定すると、 対応するファイルディスクリプターにおいて、 close-on-exec フラグ (FD_CLOEXEC) がセットされる。 これが役に立つ理由については、 open(2) の O_CLOEXEC フラグの説明を参照のこと。
popen() からの返り値は、通常の標準 I/O ストリームと同じであるが、 fclose(3) ではなく pclose() で閉じなくてはならないことだけが異なる。 このストリームへ書き込んだ結果はコマンドの標準入力に書き込まれる。 そして、コマンドの標準出力は、 コマンドそのものが置き換わってしまわない限り、 popen() を呼んだプロセスの標準出力と同じことになる。 逆に、 ストリームからの読み込みは、 そのコマンドの標準出力を読み込むことになる。 そして、そのコマンドの標準入力は popen() を呼んだプロセスの標準入力と同一である。
デフォルトでは、 popen() の出力ストリームは block buffered であることに注意すること。
pclose() 関数は、(パイプに) 関連づけられたプロセスが終了するのを待ち、 wait4(2) によって返されたコマンドの終了状態を返す。
popen(): on success, returns a pointer to an open stream that can be used to read or write to the pipe; if the fork(2) or pipe(2) calls fail, or if the function cannot allocate memory, NULL is returned.
pclose(): on success, returns the exit status of the command; if wait4(2) returns an error, or some other error is detected, -1 is returned.
Both functions set errno to an appropriate value in the case of an error.
popen() 関数は、メモリーアロケーションに失敗しても errno をセットしない。 popen() が中で呼び出す fork(2) や pipe(2) が失敗した場合には、 errno が適切にセットされる。 引数 type が無効であり、この状態が検知された場合には、 errno が EINVAL にセットされる。
pclose() が、子プロセスの状態を取得できなかった場合、 errno が ECHILD にセットされる。
この節で使用されている用語の説明については、 attributes(7)EN を参照。
| インターフェース | 属性 | 値 |
| popen(), pclose() | Thread safety | MT-Safe |
POSIX.1-2001, POSIX.1-2008.
type に指定できる 'e' は Linux での拡張である。
読み込みのために開かれたコマンドの標準入力は popen(), を呼んだプロセスと一緒に、その読み取り位置を共有する。 そのため、もとのプロセスがバッファーリングされた読み取りを終了したら、 そのコマンドの入力位置は予想されたものには なっていないかもしれない。 同様に、書き込みのために開かれたコマンドからの出力は、 もとのプロセスの出力と混ざり合うことになるかもしれない。 後者は popen() の前に fflush(3) を呼び出すことによって回避可能である。
シェルの実行の失敗は、 シェルがコマンドの実行に失敗したことや、 コマンドがすぐに終了してしまったことと、区別がつかない。 唯一のヒントは終了状態が 127 になることである。
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。