23 Ocak 2017 Pazartesi

exec ailesi

Not : fork() sistem çağrısı başlıklı yazıda std::system() çağrısının altta execl sistem çağrısını kullandığını görebilirsiniz.

Not 2: Windows'ta C kütüphanesinden _spawn, _wspawn ailesine ait metodlar exec ailesine çok benziyor.

exec sistem çağrısı ailesi
exec ailesindeli metodlar şöyle. v ile bitenler çalıştırılacak uygulamaya geçilecek parametreleri bir char dizisi ile alıyorlar. l ile bitenler ise parametreleri variable argument list olarak alıyorlar.
execl
execle
execlp
execv
execve
execvp
Aşağıdaki şekli buradan aldım. Şekilde execlp ve execvp'nin çalıştırılmak istenen uygulamayı $PATH ortam değişkeni altında arayacağı görülebilir.


execl
execl metodu yazısına taşıdım.

execle
Örnek ver

execlp
Çalıştırılmak istenen uygulam $PATH dizininde olmalıdır. Şöyle yaparız.
std::string str("...");
execlp("curl", "-b", "cookie.txt", "-d", str.c_str());

execv
execv metodu yazısına taşıdım.

execve
execve yazısına taşıdım.

execvpe
execvpe Linux üzerinde bulunuyor ancak standart bir metod değil.

execvp - Programı path içinde arar
Şu satırın dahil edilmesi gerekir.
#include <unistd.h>
Metodun imzası şöyle
int execvp(const char *file, char *const argv[]);
argv bir char* array. Son elemanının null olması gerekiyor.  C tarzı programlarda şöyle yaparız. Önce parametre dizisini doldururuz.
// The argument list to pass to the “ls” command.
 char* arg_list[] = { 
   “-l”, 
    “/”,
    NULL // The argument list must end with a NULL
  };
Daha sonra execvp'yi çağırırız.
execvp ("ls", arg_list);
C++ ile parametrelerin büyüklüğünü tam bilmediğimiz bir argv dizisini oluşturmak için bir yöntem şöyle
// given:
std::vector<std::string> args = the_args();
std::vector<char*> argv(args.size() + 1);
std::transform(args.begin(), args.end(), argv.begin(),
  [](std::string& s) { return const_cast<char*>(s.c_str()); });

int error = execvp(path, argv.data());
exec ailesi ve threadler
exec ailesinden bir metod çalıştırılınca eski uygulamadaki exec() metodunu çağıran thread hariç geri kalan tüm threaler kapatılır. man exec sayfasında şu yazıyor.
All threads other than the calling thread are destroyed during an execve().
Bir sınav sorusu şöyle
What happens to the other threads, if one of many threads within a process makes an exec() call? Why?
Cevabı ise şöyle
A call to any exec function from a process with more than one thread shall result in all threads being terminated and the new executable image being loaded and executed. No destructor functions or cleanup handlers shall be called.
Yani exec(...) çağrısından sonra tek bir thread yaşamaya devam ediyor.

exec ailesi ve sinyaller
Set ignored signals to SIG_DFL before execvp() sorusunda da anlatıldığı gibi yeni açılan uygulama eski uygulamadaki dikkate alınmayan sinyalleri dikkate almıyor. Ancak eski uygulamadaki atanmış sinyalleri SIG_DFL olarak atıyor. Yani default handler'ı geri atıyor.


exec ailesi ve programı çıktısı
Bu konudaki en önemli doküman Process sınıfındaki açıklama.Yani çıktısı olan programların çıktılarını okumakta fayda var.


3 yorum:

  1. http://pstreams.sourceforge.net/doc/

    YanıtlaSil

  2. Selamlar haci abi,

    Blogunuzu uzun zamandir ilgiyle ve imrenerek takip ediyorum. En cok istedigim seylerden biridir, bu sekilde duzenli not tutup, paylasmak; ama olmadi, belki bir gun olur diye kendimi karamsarliga dusurmemeye calisiyorum :)

    Bu arada bu yaziyi yazma amacim, hem paylasimlar icin tesekkur etmek, hem de arada bir boyle sadece link iceren yorum yazarken niyetimin, "abi konuyla ilgili boyle bir sey gormustum, bi bak belki isine yarar" oldugunu izah etmek.

    Sen o kadar yaz, vatandasin biri gelsin altina link yapistirip kacsin :)
    Dedigim gibi bu sekilde anlasilmis olabilirim diye durumu aciklamak istedim.

    Biraz bakindim ve iletisim icin baska bir kanal bulamadigim icin dogrudan buraya yazdim.

    Tekrardan tesekkurler, iyi calismalar.

    Savas - savas.kpln@gmail.com

    YanıtlaSil
  3. Ben de yorumlarınız ve paylaştığınız linkler için teşekkür ederim. Faydalı oluyorsa ne mutlu bana.

    YanıtlaSil