Burada kısa cevap system()
ya da popen()
yerine execl()
kullanmaktır. Jason zaten popen()
, bunu atlayın ve sadece aslında bakım durumda execl()
nasıl kullanılacağını anlatacağız kullanma konusunda iyi bir cevap yazmamış gibi görüyorum. Büyük olasılıkla, bu gereksiz bütün teknik put - ama kahretsin, ben bu en popen()
tartışmadan önce uzun bir başlangıcı olarak zaten yazmış ve ben şimdi uzağa atma değilim!
Firstly...
Çağrılırken execl()
komut satırı argümanları da ayrı ayrı kabul edilmesi gerekir. Ayrıca, ilk argüman programın herhangi bir programın main()
geleneksel olarak adı argv[0]
olarak tekrar edilmelidir. Böylece sabit arama gibi görünmelidir:
execl("/usr/bin/php", "/usr/bin/php", "-q",
"/var/www/html/phpinfo.php", (char *) NULL);
NULL
{olarak tanımlanabilir olursa (I [(2)], bir null işaretçi son argüman yerine tamsayı 0 olarak geçirilir sağlamak için (char *)
için döküm eklendi } olup (void *) 0
, yasal olan.)
However...
Bu execl()
sağ çağrı alır, ama büyük bir sorun var. Fonksiyonlarının exec
etti hemen hemen her zaman fork()
ve bazı karmaşık pipe()
hokkabazlık ile bir arada kullanılmaktadır. exec
fonksiyonları aslında ayrı bir işlemde programı çalıştırmak değil çünkü bu; aslında mevcut süreci değiştirin! Eğer execl()
kez çağrı Yani, kodunuzu yapılır. Bitirdi. execl()
geri dönmedi. Yaptığın gibi sadece onu aramak eğer programı sihirli bir /usr/bin/php
sürecine dönüşecektir olarak ne olacağını görmek için olsun asla.
Tamam, peki bu konuda fork()
bulunuyor ve pipe()
? Yüksek bir düzeyde, ne yapmak lazım iki süreç içine süreci olarak bölünmüş. Ana süreç, alt süreç hemen execl()
çağırır ve /usr/bin/php
kendisini dönüştürecek iken, "sizin" süreç olmaya devam edecektir. Doğru birlikte üst ve alt süreçleri kablolu ettik sonra onlar birbirleri ile iletişim mümkün olacak.
Hala buradasın ve başını salladı değil eğer tüm bu konuda yol daha fazla bilgi için bilge torpil Google danışmalısınız, uzun lafın kısası. fork
/ exec
dansı yapmak nasıl (!) Derinlemesine bilgi daha veriyor Orada web siteleri bol vardır.
Ama asılı bırakmayacağım. İşte ben açıkladık yok tam olarak ne kendi programları için kullanabileceğiniz bir fonksiyon. Bu arayan ek olarak çocuğun stderr
akışı erişebilmesi popen()
, aslında, tek fark olarak çok benzer stdin
ve {[(3) }].
Code...
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
pid_t execute(const char *command, FILE **in, FILE **out, FILE **err)
{
pid_t pid;
int fd[6];
pipe(&fd[0]);
pipe(&fd[2]);
pipe(&fd[4]);
switch (pid = fork()) {
case -1:
perror("unable to fork()");
exit(1);
case 0:
close(fd[1]); // Close write end of stdin.
close(fd[2]); // Close read end of stdout.
close(fd[4]); // Close read end of stderr.
dup2(fd[0], STDIN_FILENO); // Have stdin read from the first pipe.
dup2(fd[3], STDOUT_FILENO); // Have stdout write to the second pipe.
dup2(fd[5], STDERR_FILENO); // Have stderr write to the third pipe.
execlp("/bin/sh", "/bin/sh", "-c", command, (char *) NULL);
perror("execlp() failed");
_exit(1);
default:
close(fd[0]); // Close read end of stdin.
close(fd[3]); // Close write end of stdout.
close(fd[5]); // Close write end of stderr.
if (in) *in = fdopen(fd[1], "wb"); else close(fd[1]);
if (out) *out = fdopen(fd[2], "rb"); else close(fd[2]);
if (err) *err = fdopen(fd[4], "rb"); else close(fd[4]);
return pid;
}
}