コマンドの引数の一部にユーザー入力がある場合は、system()ではなくfork()/ exec()/ wait()を使用するため、ユーザーは次のようなものを入力できません...
&rm -rf /home/* && echo HAHA
...引数として。
popenはsystem()と同じくらい危険だと思います。これは、execファミリーの関数のように文字列のリストではなく、単一の文字列を受け取るためです。
ただし、exec関数からのみ戻り値を取得できます。ユーザー入力で実行し、親プロセスでstdout / stderrを処理できる「安全な」バージョンのpopenはありますか?