exec (Unix)
exec*()er en gruppe systemopkald under Unix og Unix-lignende operativsystemer . Det, de alle har til fælles, er at starte en ny proces i miljøet for en eksisterende proces og dermed erstatte den. (Denne proces kaldes også overlay .) I POSIX- standarden er følgende funktionsprototyper defineret i headerfilen unistd.h :
int execl(char const *path, char const *arg0, ...);
int execle(char const *path, char const *arg0, ..., char const *envp[]);
int execlp(char const *file, char const *arg0, ...);
int execv(char const *path, char const *argv[]);
int execve(char const *path, char const *argv[], char const *envp[]);
int execvp(char const *file, char const *argv[]);
Betyde:
- arg0
- det første (faktisk: nul, fordi det er implicit angivet) argumentet på kommandolinjen og konventionelt navnet på den eksekverbare fil, der udføres. Dårligt programmeret software kan stole på disse oplysninger for at bestemme den nøjagtige placering i filsystemet, hvorfra det kørende program blev indlæst. Dette er dog ikke kun garanteret af standarden, men også ikke konsekvent reguleret på tværs af platforme.
- envp []
- en række markører, der peger på strenge af formvariablen = værdi og repræsenterer processens miljø
- sti
- stienavnet på den fil, der skal køres. (Dette skal bruges til disse oplysninger i stedet for arg0 .)
- argv []
- en række markører, der peger på de kommandolinjeargumenter, der er sendt.
Begge arrays er involveret envp[]og argv[]indeholder henvisninger til nulterminerede strenge. Det sidste element i arrayet er traditionelt en nul pointer, der angiver slutningen af arrayet.
Bivirkninger
Åbne filbeskrivelser for opkaldsprocessen forbliver også åbne i den nye proces. Miljøet er også grundlæggende bevaret. I modsætning hertil ødelægges (private) data og kode for opkaldsprocessen af overlayet og erstattes af dataene og koden for overlayet. I modsætning til udelukkende brugt hukommelse påvirkes ikke delt hukommelse .
Returkoden for et vellykket udført exec*()opkald kan ikke forespørges af opkaldsprocessen, da dette er blevet erstattet af opkaldet. Udskiftning af en proces med et exec * () opkald afslutter ikke processen, som fortsætter med at eksistere (kun i en ændret tilstand). I tilfælde af et mislykket opkald (i dette tilfælde kører den proces, der skal udskiftes stadig), returneres -1 og indstilles errnotil en af følgende værdier (se errno.h):
| E2BIG | Listen over argumenter er større end den relevante systemgrænse tillader. |
| EACCES | Adgang til den eksekverbare blev nægtet. (Mulige årsager kan være: fil låst, manglende rettigheder, ...) |
| ENOENT | Den eksekverbare fil, der skulle startes, blev ikke fundet. |
| ENOMEM | Der er ikke nok hukommelse til rådighed til at starte programmet. |
Historie, nuværende brug
Den originale Unix kunne ikke starte en ny, anden proces end en eksisterende i et trin. I stedet blev en kopi af den eksisterende proces oprettet med fork (), og derefter blev en af exec*()funktionerne brugt til at give den oprettede kopi et (andet) overlay. Denne gruppe systemopkald var derfor af stor betydning.
I mellemtiden har POSIX defineret en gruppe systemopkald posix_spawn*()som en (valgfri) udvidelse, hvormed sekvensen fork()- kan exec*()undgås, men med tab af en del af den fleksibilitet, som denne mekanisme tilbyder.
exec som en shell-kommando
Mange almindelige Unix-skaller implementerer også en kommando, execder grundlæggende gør det samme som systemopkaldet: den kørende proces (eller det kørende script) erstattes af en forekomst af den specificerede nye eksekverbare. I det givne eksempel bruges denne mekanisme til at afslutte et X11- start-script efter at have ringet til vinduesadministratoren:
#!/bin/ksh
xclock &
xsetroot -solid black
exec mwm -multiscreen -xrm "ShowFeedback: -quit"
Weblinks
- Beskrivelse af den åbne gruppe fra 2016