#include <stdlib.h> int system(const char *command);
execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() が返るのはコマンドが完了した後である。
コマンドの実行中は、 system() を呼び出したプロセスでは、 SIGCHLD はブロックされ、 SIGINT と SIGQUIT は無視される (command を実行する子プロセスでは、これらのシグナルはデフォルトの処理方法にしたがって処理される)。
command が NULL の場合、 system() はそのシステムでシェルが利用可能かを示すステータスを返す。
最後の 2 つの場合、返り値は "wait status" であり、 waitpid(2) に書かれているマクロ (つまり WIFEXITED() や WEXITSTATUS() などのマクロ) を使って検査することができる。
system() は他の子プロセスのウエイトステータスには影響を与えない。
(「どの」ヘッダーファイルをインクルードするよりも前に) 機能検査マクロ _XOPEN_SOURCE が定義された場合には、 waitpid(2) で説明されているマクロ群 (WEXITSTATUS() 等) が <stdlib.h> をインクルードすると利用可能になる。
既に述べたように、 system() は SIGINT と SIGQUIT を無視する。 よってループから system()
を呼ぶプログラムは、 以下の例のように子プロセスの終了状態を自分でチェックしておかないと、 中断できなくなるかもしれない。
while (something) { int ret = system("foo"); if (WIFSIGNALED(ret) && (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT)) break; }
set-user-ID や set-group-ID の特権をもつプログラムの中では system() を使ってはいけない。なぜなら、ある環境変数の未知の値によって システムの安全が損なわれるからである。代わりに exec(3) 関連の関数群の中で execlp(3) と execvp(3) 以外の関数を使用すべきである。 実際のところ、 system() は /bin/sh が bash バージョン 2 であるシステムでは、 set-user-ID や set-group-ID の特権を持つプログラムからは正しく動作しない。 なぜなら、bash バージョン 2 はスタートアップ時に特権を落とすからである。 (Debian では、sh として起動された時にはこのような動作を行なわないように 修正された bash を用いている)
glibc 2.1.3 より前のバージョンでは、 command が NULL の場合に /bin/sh が利用可能かどうかのチェックは実際には行わず、 いつでも利用可能であるとみなしていた。 system() はこの場合に常に 1 を返していた。 POSIX.1-2001 ではシェルが提供されているという標準に準拠した実装を 要求しているが、glibc 2.1.3 以降ではシェルのチェックを実行している。 なぜなら、呼び出し元のプログラムが system() を呼び出すより前に (POSIX.1-2001 では規定されていない) chroot(2) を呼び出していた時には、シェルが利用可能でない場合や実行可能ファイル でない場合があるからである。
シェルコマンドがステータス 127 で終了することもある。 この場合、system() の返り値は、子プロセスでシェルが実行できなかった場合と区別できない。