Linux Exec Sistem Çağrısı

Linux Exec System Call



Exec sistem çağrısı, aktif bir süreçte bulunan bir dosyayı yürütmek için kullanılır. exec çağrıldığında önceki yürütülebilir dosya değiştirilir ve yeni dosya yürütülür.

Daha doğrusu, exec sistem çağrısı kullanmanın, işlemdeki eski dosya veya programı yeni bir dosya veya programla değiştireceğini söyleyebiliriz. Sürecin tüm içeriği yeni bir programla değiştirilir.







exec() sistem çağrısını yürüten kullanıcı veri kesimi, exec() çağrılırken argümanda adı verilen veri dosyasıyla değiştirilir.



Yeni program aynı işlem alanına yüklenir. Mevcut süreç yeni bir sürece dönüştürülür ve bu nedenle süreç kimliği PID'si değişmez, bunun nedeni yeni bir süreç yaratmıyor olmamızdır, sadece bir süreci exec'de başka bir süreçle değiştiriyoruz.



Şu anda çalışan süreç birden fazla iş parçacığı içeriyorsa, tüm iş parçacıkları sonlandırılacak ve yeni işlem görüntüsü yüklenecek ve ardından yürütülecektir. Geçerli işlemin iş parçacıklarını sonlandıran yok edici işlevler yoktur.





Prosesin PID'si değiştirilmez ancak prosesin datası, kodu, stack, heap vs. değiştirilir ve yeni yüklenen prosesinkilerle değiştirilir. Yeni işlem giriş noktasından yürütülür.

Exec sistem çağrısı bir işlevler topluluğudur ve C programlama dilinde bu işlevlerin standart adları aşağıdaki gibidir:



  1. yürütmek
  2. yönetici
  3. execlp
  4. yürütme
  5. yürütmek
  6. execvp


Burada bu işlevlerin aynı temele sahip olduğuna dikkat edilmelidir. yürütmek ardından bir veya daha fazla harf gelir. Bunlar aşağıda açıklanmıştır:

Ve: Ortam değişkenlerine işaret eden ve yeni yüklenen işleme açıkça iletilen bir dizi işaretçidir.

NS: l, işleve bir liste geçirilen komut satırı argümanları içindir

P: p, işleme yüklenecek bir argüman olarak iletilen dosyayı bulmaya yardımcı olan yol ortam değişkenidir.

v: v komut satırı argümanları içindir. Bunlar, işleve bir dizi işaretçi olarak iletilir.

Neden exec kullanılır?

exec, kullanıcı aynı süreçte yeni bir dosya veya program başlatmak istediğinde kullanılır.

Exec'in İç Çalışması

exec'in çalışmasını anlamak için aşağıdaki noktaları göz önünde bulundurun:

  1. Mevcut süreç görüntüsünün üzerine yeni bir süreç görüntüsü yazılır.
  2. Yeni süreç görüntüsü, exec argümanı olarak ilettiğiniz görüntüdür.
  3. Şu anda devam eden süreç sona erdi
  4. Yeni süreç görüntüsü aynı süreç kimliğine, aynı ortama ve aynı dosya tanımlayıcısına sahiptir (çünkü süreç değiştirilmez, süreç görüntüsü değiştirilir)
  5. CPU durumu ve sanal bellek etkilenir. Mevcut süreç görüntüsünün sanal bellek eşlemesi, yeni süreç görüntüsünün sanal belleği ile değiştirilir.

exec ailesi işlevlerinin sözdizimi:

Aşağıdakiler, her bir exec işlevi için sözdizimleridir:

int execl(const char* yolu, const char* arg, …)
int execlp(const char* dosyası, const char* arg, …)
int execle(const char* yolu, const char* arg, …, char* const envp[])
int execv(const char* yolu, const char* argv[])
int execvp(const char* dosyası, const char* argv[])
int execvpe(const char* dosyası, const char* argv[], char *const envp[])

Açıklama:

Bu işlevlerin dönüş türü Int. İşlem görüntüsü başarıyla değiştirildiğinde, onu çağıran işlem artık çalışmadığından hiçbir şey çağıran işleve döndürülmez. Ancak herhangi bir hata varsa -1 döndürülür. Herhangi bir hata oluşursa bir hata ayarlanır.

Sözdiziminde:

  1. yol yürütülecek dosyanın tam yol adını belirtmek için kullanılır.
  1. sinirli geçirilen argümandır. Aslında süreçte yürütülecek dosyanın adıdır. Çoğu zaman argüman ve yolun değeri aynıdır.
  1. const karakter* argüman execl(), execlp() ve execle() fonksiyonlarında arg0, arg1, arg2, …, argn olarak kabul edilir. Temel olarak, sonlandırılan dizeleri geçersiz kılmak için bir işaretçi listesidir. Burada ilk argüman, 2. maddede açıklandığı gibi yürütülecek olan dosya adına işaret eder.
  1. envp ortam değişkenlerine işaret eden işaretçiler içeren bir dizidir.
  1. dosya yeni proses görüntü dosyasının yolunu tanımlayacak yol adını belirtmek için kullanılır.
  1. ile biten exec çağrısının işlevleri Ve yeni süreç görüntüsünün ortamını değiştirmek için kullanılır. Bu işlevler, bağımsız değişkeni kullanarak ortam ayarı listesini iletir. envp . Bu bağımsız değişken, boş sonlandırılmış Dize'ye işaret eden ve ortam değişkenini tanımlayan bir karakter dizisidir.

Exec ailesi işlevlerini kullanmak için C programınıza aşağıdaki başlık dosyasını eklemeniz gerekir:

#Dahil etmek

Örnek 1: C programında exec sistem çağrısını kullanma

Linux, Ubuntu'da C programlamada exec sistem çağrısını kullandığımız aşağıdaki örneği göz önünde bulundurun: Burada iki c dosyamız var example.c ve merhaba.c:

örnek.c

KOD:

#Dahil etmek
#Dahil etmek
#Dahil etmek
intana(intargc, karakter *bağımsız değişken[])
{
baskı ('Örnek.c'nin PID'si = %d ',getpid());
karakter *argümanlar[] = {'Merhaba', 'C', 'Programlama',BOŞ};
yürütme('./Merhaba',argümanlar);
baskı ('Örnek.c'ye geri dön');
dönüş 0;
}

Merhaba C

KOD:

#Dahil etmek
#Dahil etmek
#Dahil etmek
intana(intargc, karakter *bağımsız değişken[])
{
baskı ('Hello.c'deyiz ');
baskı (merhaba.c'nin PID'si = %d ',getpid());
dönüş 0;
}

ÇIKTI:

Örnek.c'nin PID'si = 4733
Hello.c'deyiz
merhaba.c'nin PID'si = 4733

Yukarıdaki örnekte bir example.c dosyamız ve merhaba.c dosyamız var. Örnek .c dosyasında öncelikle mevcut işlemin kimliğini yazdırdık (örnek.c dosyası mevcut işlemde çalışıyor). Sonra bir sonraki satırda bir dizi karakter işaretçisi oluşturduk. Bu dizinin son elemanı, sonlandırma noktası olarak NULL olmalıdır.

Ardından, argüman olarak dosya adını ve karakter işaretçi dizisini alan execv() işlevini kullandık. Burada not edilmelidir ki dosya ismi ile birlikte ./ kullandık, dosyanın yolunu belirtir. Dosya, example.c'nin bulunduğu klasörde olduğundan, tam yolu belirtmeye gerek yoktur.

execv() işlevi çağrıldığında, işlem resmimiz değiştirilecektir, şimdi example.c dosyası işlemde değil, merhaba.c dosyası işlemde. Merhaba.c proses görüntüsü veya example.c proses imajı olsun, proses ID'sinin aynı olduğu görülebilir, çünkü proses aynıdır ve proses imajı sadece değiştirilir.

O zaman burada not etmemiz gereken başka bir şey var, execv() yürütülmedikten sonra printf() ifadesi. Bunun nedeni, yeni süreç görüntüsü onun yerini aldığında kontrolün asla eski süreç görüntüsüne geri döndürülmemesidir. Kontrol, yalnızca proses görüntüsünün değiştirilmesi başarısız olduğunda çağırma işlevine geri döner. (Bu durumda dönüş değeri -1'dir).

fork() ve exec() sistem çağrıları arasındaki fark:

fork() sistem çağrısı, çalışan bir işlemin tam bir kopyasını oluşturmak için kullanılır ve oluşturulan kopya alt işlemdir ve çalışan işlem üst işlemdir. Oysa exec() sistem çağrısı, bir süreç görüntüsünü yeni bir süreç görüntüsü ile değiştirmek için kullanılır. Bu nedenle exec() sistem çağrısında ebeveyn ve alt süreç kavramı yoktur.

fork() sisteminde ebeveyn ve alt süreçler aynı anda yürütülür. Ancak exec() sistem çağrısında, süreç görüntüsünün değiştirilmesi başarılı olursa, kontrol exec işlevinin çağrıldığı yere dönmez, bunun yerine yeni süreci yürütür. Kontrol sadece herhangi bir hata varsa geri aktarılacaktır.

Örnek 2: fork() ve exec() sistem çağrılarını birleştirme

Aynı programda hem fork() hem de exec() sistem çağrılarını kullandığımız aşağıdaki örneği göz önünde bulundurun:

örnek.c

KOD:

#Dahil etmek
#Dahil etmek
#Dahil etmek
intana(intargc, karakter *bağımsız değişken[])
{
baskı ('Örnek.c'nin PID'si = %d ',getpid());
pid_t p;
P=çatal();
Eğer(P== -1)
{
baskı ('fork() çağrılırken bir hata oluştu');
}
Eğer(P==0)
{
baskı ('Çocuk sürecindeyiz' ');
baskı ('Alt süreçten merhaba.c'yi çağırmak ');
karakter *argümanlar[] = {'Merhaba', 'C', 'Programlama',BOŞ};
yürütme('./Merhaba',argümanlar);
}
Başka
{
baskı ('Aile sürecindeyiz');
}
dönüş 0;
}

Merhaba C:

KOD:

#Dahil etmek
#Dahil etmek
#Dahil etmek
intana(intargc, karakter *bağımsız değişken[])
{
baskı ('Hello.c'deyiz ');
baskı (merhaba.c'nin PID'si = %d ',getpid());
dönüş 0;
}

ÇIKTI:

Örnek.c'nin PID'si = 4790
Ebeveyn Sürecindeyiz
Çocuk Sürecindeyiz
Alt süreçten merhaba.c'yi çağırma
merhaba.c'deyiz
merhaba.c'nin PID'si = 4791

Bu örnekte fork() sistem çağrısını kullandık. Alt süreç oluşturulduğunda, p'ye 0 atanacak ve ardından alt sürece geçeceğiz. Şimdi if(p==0) içeren ifade bloğu yürütülecek. Bir mesaj görüntülenir ve execv() sistem çağrısını kullandık ve example.c olan mevcut alt süreç görüntüsü merhaba.c ile değiştirilecektir. execv() çağrısından önce çocuk ve ebeveyn süreçleri aynıydı.

Örnek.c ve merhaba.c'nin PID'sinin artık farklı olduğu görülebilir. Bunun nedeni, example.c'nin üst süreç görüntüsü ve merhaba.c'nin alt süreç görüntüsü olmasıdır.