Sistemski klic Linux Exec

Linux Exec System Call



Sistemski klic exec se uporablja za izvajanje datoteke, ki je v aktivnem procesu. Ko se pokliče exec, se zamenja prejšnja izvršljiva datoteka in izvede nova datoteka.

Natančneje, lahko rečemo, da bo uporaba sistemskega klica exec nadomestila staro datoteko ali program iz procesa z novo datoteko ali programom. Celotna vsebina postopka se nadomesti z novim programom.







Segment uporabniških podatkov, ki izvaja sistemski klic exec (), se nadomesti s podatkovno datoteko, katere ime je v argumentu med klicem exec ().



Novi program se naloži v isti procesni prostor. Trenutni proces se je pravkar spremenil v nov proces, zato se PID ID -ja procesa ne spremeni, to je zato, ker ne ustvarjamo novega procesa, ampak samo zamenjamo proces z drugim procesom v exec.



Če trenutno izvajani proces vsebuje več kot eno nit, se vse niti končajo, nova slika procesa pa se naloži in nato izvede. Ni funkcij destruktorja, ki bi končale niti trenutnega procesa.





PID procesa se ne spremeni, spremenijo pa se podatki, koda, sklad, kup itd. In se nadomestijo s podatki na novo naloženega procesa. Novi postopek se izvede od vstopne točke.

Sistemski klic Exec je zbirka funkcij in v programskem jeziku C so standardna imena teh funkcij naslednja:



  1. execl
  2. execle
  3. execlp
  4. execv
  5. execve
  6. execvp


Tu je treba opozoriti, da imajo te funkcije isto osnovo exec sledi ena ali več črk. Te so razložene spodaj:

In: To je niz kazalcev, ki kaže na spremenljivke okolja in se izrecno posreduje na novo naloženemu procesu.

the: l je za argumente ukazne vrstice, ki funkciji posredujejo seznam

p: p je spremenljivka okolja poti, ki pomaga najti datoteko, posredovano kot argument za nalaganje v proces.

v: v je za argumente ukazne vrstice. Ti se posredujejo kot niz kazalcev na funkcijo.

Zakaj se uporablja exec?

exec se uporablja, ko želi uporabnik v istem postopku zagnati novo datoteko ali program.

Notranje delo exec

Za razumevanje delovanja exec upoštevajte naslednje točke:

  1. Trenutna slika procesa je prepisana z novo sliko procesa.
  2. Nova slika procesa je tista, ki ste jo posredovali kot argument exec
  3. Postopek, ki se trenutno izvaja, je končan
  4. Nova slika procesa ima isti ID procesa, isto okolje in isti deskriptor datoteke (ker proces ni zamenjan, slika procesa se zamenja)
  5. To vpliva na stanje procesorja in navidezni pomnilnik. Preslikavo navideznega pomnilnika trenutne podobe procesa nadomesti navidezni pomnilnik nove podobe procesa.

Sintakse funkcij družine exec:

Sledijo sintakse za vsako funkcijo exec:

int execl (const char* pot, const char* arg, ...)
int execlp (datoteka const char*, const char* arg, ...)
int execle (const char* pot, const char* arg,…, char* const envp [])
int execv (const char* pot, const char* argv [])
int execvp (datoteka const char*, const char* argv [])
int execvpe (datoteka const char*, const char* argv [], char* const envp [])

Opis:

Vrnitev teh funkcij je Int. Ko je slika procesa uspešno zamenjana, se klicni funkciji nič ne vrne, ker proces, ki jo je poklical, ne deluje več. Če pa pride do napake, se vrne -1. Če pride do napake errno je nastavljeno.

V sintaksi:

  1. pot se uporablja za določitev celotnega imena poti datoteke, ki jo je treba izvesti.
  1. jezen je argument sprejet. To je dejansko ime datoteke, ki se bo izvajala v postopku. V večini primerov je vrednost arg in poti enaka.
  1. const char* arg v funkcijah execl (), execlp () in execle () velja za arg0, arg1, arg2,…, argn. To je v bistvu seznam kazalcev na ničelno zaključene nize. Tu prvi argument kaže na ime datoteke, ki bo izvedeno, kot je opisano v točki 2.
  1. envp je matrika, ki vsebuje kazalce, ki kažejo na spremenljivke okolja.
  1. mapa se uporablja za podajanje imena poti, ki bo identificiralo pot do nove datoteke slike procesa.
  1. Funkcije exec kličejo s In se uporabljajo za spreminjanje okolja za novo podobo procesa. Te funkcije posredujejo seznam nastavitev okolja z uporabo argumenta envp . Ta argument je niz znakov, ki kaže na ničelno zaključen niz in definira spremenljivko okolja.

Če želite uporabljati funkcije družine exec, morate v svoj program C vključiti naslednjo datoteko glave:

#vključi

Primer 1: Uporaba sistemskega klica exec v programu C

Razmislite o naslednjem primeru, v katerem smo uporabili sistemski klic exec v programiranju C v Linuxu, Ubuntu: Tukaj imamo dve datoteki c example.c in hello.c:

primer.c

KODA:

#vključi
#vključi
#vključi
intglavni(intargc, char *argv[])
{
printf ('PID primera. C = %d n',getpid());
char *args[] = {'Zdravo', 'C', 'Programiranje',NIČ};
execv('./zdravo',args);
printf ('Nazaj na example.c');
vrnitev 0;
}

zdravo.c

KODA:

#vključi
#vključi
#vključi
intglavni(intargc, char *argv[])
{
printf ('Smo v Hello.c n');
printf ('PID hello.c = %d n',getpid());
vrnitev 0;
}

IZHOD:

PID primera.c = 4733
Smo v Hello.c
PID hello.c = 4733

V zgornjem primeru imamo datoteko example.c in datoteko hello.c. V datoteki primer .c smo najprej natisnili ID trenutnega procesa (datoteka example.c se izvaja v trenutnem procesu). Nato smo v naslednji vrstici ustvarili niz kazalcev na znake. Zadnji element tega niza mora biti NULL kot zaključna točka.

Nato smo uporabili funkcijo execv (), ki za argument vzame ime datoteke in niz kazalcev znakov. Tukaj je treba opozoriti, da smo uporabili ./ z imenom datoteke, ki določa pot do datoteke. Ker je datoteka v mapi, kjer je example.c, ni treba navesti celotne poti.

Ko se pokliče funkcija execv (), bo naša slika procesa zdaj zamenjana z datoteko example.c, ki ni v procesu, ampak datoteka hello.c je v postopku. Vidimo lahko, da je ID procesa enak, ne glede na to, ali je hello.c slika procesa ali primer. C je slika procesa, ker je proces enak in se slika procesa le zamenja.

Potem moramo tukaj opozoriti še na to, da je stavek printf () po tem, ko execv () ni izveden. To je zato, ker se nadzor nikoli ne vrne na staro sliko procesa, ko jo zamenja nova slika procesa. Nadzor se vrne k klicni funkciji šele, ko zamenjava slike procesa ni uspela. (Vrnjena vrednost je v tem primeru -1).

Razlika med sistemskimi klici fork () in exec ():

Sistemski klic fork () se uporablja za ustvarjanje natančne kopije izvajanega procesa, ustvarjena kopija pa je podrejeni proces, tekaški proces pa je nadrejeni proces. Medtem ko se sistemski klic exec () uporablja za zamenjavo slike procesa z novo podobo procesa. Zato v sistemskem klicu exec () ni koncepta starševskih in podrejenih procesov.

V sistemskem klicu fork () se nadrejeni in podrejeni proces izvedeta hkrati. Toda v sistemskem klicu exec (), če je zamenjava slike procesa uspešna, se nadzor ne vrne tja, kjer je bila poklicana funkcija exec, temveč bo izvedel nov proces. Nadzor se prenese nazaj le, če pride do napake.

Primer 2: Združevanje sistemskih klicev fork () in exec ()

Razmislite o naslednjem primeru, v katerem smo v istem programu uporabili sistemske klice fork () in exec ():

primer.c

KODA:

#vključi
#vključi
#vključi
intglavni(intargc, char *argv[])
{
printf ('PID primera. C = %d n',getpid());
pid_t p;
str=vilice();
če(str== -1)
{
printf ('Pri klicanju fork () je prišlo do napake');
}
če(str==0)
{
printf ('Smo v procesu otroka n');
printf ('Klicanje hello.c iz otroškega procesa n');
char *args[] = {'Zdravo', 'C', 'Programiranje',NIČ};
execv('./zdravo',args);
}
drugače
{
printf ('Smo v starševskem procesu');
}
vrnitev 0;
}

zdravo.c:

KODA:

#vključi
#vključi
#vključi
intglavni(intargc, char *argv[])
{
printf ('Smo v Hello.c n');
printf ('PID hello.c = %d n',getpid());
vrnitev 0;
}

IZHOD:

PID primera.c = 4790
Smo v procesu staršev
Smo v procesu otroka
Klicanje hello.c iz otroškega procesa
Smo v hello.c
PID hello.c = 4791

V tem primeru smo uporabili sistemski klic fork (). Ko je ustvarjen podrejeni proces, bo 0 dodeljeno p, nato pa se premaknemo na podrejeni proces. Zdaj bo izveden blok stavkov z if (p == 0). Prikaže se sporočilo in uporabili smo sistemski klic execv () in trenutno podrejeno sliko procesa, ki je example.c, bomo nadomestili s hello.c. Pred klicem execv () sta bila podrejena in nadrejena procesa enaka.

Vidimo lahko, da sta PID za example.c in hello.c zdaj drugačna. To je zato, ker je example.c slika nadrejenega procesa in hello.c podoba podrejenega procesa.