Versi 2004 dari POSIX system()
dokumentasi memiliki alasan yang mungkin berlaku untuk popen()
demikian juga. Perhatikan batasan yang disebutkan pada system()
, terutama yang menyatakan "bahwa ID prosesnya berbeda":
RASIONAL
...
Ada tiga tingkat spesifikasi untuk fungsi system(). Standar ISO C memberikan yang paling dasar. Itu membutuhkan fungsi yang ada, dan menentukan cara bagi aplikasi untuk menanyakan apakah juru bahasa perintah ada. Tidak disebutkan apa pun tentang bahasa perintah atau lingkungan tempat perintah tersebut ditafsirkan.
IEEE Std 1003.1-2001 memberikan batasan tambahan pada system(). Itu membutuhkan jika ada juru bahasa perintah, lingkungan harus seperti yang ditentukan oleh fork() dan exec. Ini memastikan, misalnya, bahwa close-on-exec berfungsi, bahwa kunci file tidak diwariskan, dan ID prosesnya berbeda. Ini juga menentukan nilai kembalian dari system() saat baris perintah dapat dijalankan, sehingga memberi aplikasi beberapa informasi tentang status penyelesaian perintah.
Terakhir, IEEE Std 1003.1-2001 mengharuskan perintah untuk ditafsirkan seperti dalam bahasa perintah shell yang ditentukan dalam volume Shell and Utilities dari IEEE Std 1003.1-2001.
Perhatikan beberapa referensi ke "Standar ISO C". Versi terbaru standar C mengharuskan string perintah diproses oleh "pemroses perintah" sistem:
7.22.4.8
system
fungsiSinopsis
#include <stdlib.h> int system(const char *string);
Deskripsi
Jika
string
adalah pointer null,system
fungsi menentukan apakah lingkungan host memiliki prosesor perintah. Jikastring
bukan penunjuk null,system
fungsi melewati string yang ditunjuk olehstring
kepada pemroses perintah untuk dieksekusi dengan cara yang pelaksanaannya harus didokumentasikan; ini kemudian dapat menyebabkan program memanggilsystem
untuk berperilaku dengan cara yang tidak sesuai atau untuk menghentikan.Pengembalian
Jika argumennya adalah pointer null,
system
function mengembalikan nol hanya jika prosesor perintah tersedia. Jika argumennya bukan penunjuk nol, dansystem
functiontidak mengembalikan, mengembalikan nilai yang ditentukan implementasi.
Karena standar C mengharuskan sistem "pemroses perintah" digunakan untuk system()
panggilan, saya menduga bahwa:
- Di suatu tempat ada persyaratan di POSIX yang mengikat
popen()
kesystem()
implementasi. - Lebih mudah menggunakan kembali "pemroses perintah" sepenuhnya karena ada juga persyaratan untuk dijalankan sebagai proses terpisah.
Jadi ini adalah jawaban fasih yang dihapus dua kali.
Memanggil shell memungkinkan Anda melakukan semua hal yang dapat Anda lakukan di shell.Misalnya,
FILE *fp = popen("ls *", "r");
dimungkinkan dengan popen()
(memperluas semua file di direktori saat ini). Bandingkan dengan:
execvp("/bin/ls", (char *[]){"/bin/ls", "*", NULL});
Anda tidak dapat menjalankan ls
dengan *
sebagai argumen karena exec(2)
akan menafsirkan *
secara harfiah.
Demikian pula, pipa (|
), pengalihan (>
, <
, ...), dll., dimungkinkan dengan popen
.
Jika tidak, tidak ada alasan untuk menggunakan popen
jika Anda tidak membutuhkan shell - itu tidak perlu. Anda akan berakhir dengan proses shell ekstra dan semua hal yang bisa salah di shell bisa salah dalam program Anda (misalnya, perintah yang Anda berikan dapat diinterpretasikan secara tidak benar oleh shell dan masalah keamanan umum). popen()
dirancang seperti itu. fork
+ exec
solusi lebih bersih tanpa masalah yang terkait dengan shell.
Jawaban fasih adalah karena standar POSIX ( http://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html ) mengatakan demikian. Atau lebih tepatnya, ia mengatakan bahwa ia harus berperilaku seolah-olah argumen perintah diteruskan ke /bin/sh untuk interpretasi.
Jadi saya kira implementasi yang sesuai dapat, pada prinsipnya, juga memiliki beberapa fungsi perpustakaan internal yang akan menginterpretasikan perintah shell tanpa harus melakukan fork dan menjalankan proses shell yang terpisah. Saya sebenarnya tidak mengetahui penerapan semacam itu, dan saya menduga memperbaiki semua kasus sudut akan sangat rumit.