ASR31-valarche-2021/ASR31-Cours4.md

161 lines
5.1 KiB
Markdown
Raw Normal View History

2021-09-29 11:31:40 +02:00
# Cours 3
La création de processus via la commande ```fork``` est intéressante mais son utilisation
est limitée. Le système fourni un compagnon à ```fork``` l'appel système ```exec```. Son rôle est
de permettre à un processus de _changer son code_ (recouvrir). On parle souvent des appels ```fork/exec```.
## La famille ```exec```
Il existe six primitives de préfixe commun ```exec``` qui se différencient :
- par la manière dont les arguments récupérés via largument ```argv``` sont transmis.
- soit directement sous forme dun tableau ou vecteur (doù le ```v```) contenant
les différents paramètres. Il sagit des primitives ```execv```, ```execvp``` et ```execve``` qui ont un nombre fixe de paramètres ;
- soit sous forme dune liste (doù le ```l```) ```arg0, arg1, ..., argn, NULL``` dans
les primitives ```execl```, ```execlp``` et ```execle``` qui ont ainsi un nombre variable de paramètres ;
- par la manière dont le fichier à charger est recherché dans le système de fichiers :
- avec ```execlp``` et ```execvp``` le fichier est recherché dans les répertoires spécifiés via la variable ```PATH``` de lenvironnement (et dans lordre dapparition) ;
- avec les autres primitives, le fichier, sil nest pas désigné par une référence absolue, nest recherché que relativement au répertoire de travail du processus appelant ;
- par lenvironnement conservé par le processus au cours du recouvrement :
- avec les primitives ```execve``` et ```execle``` un nouvel environnement transmis en
paramètre se substitue à lancien ;
- avec les autres primitives, lenvironnement reste inchangé.
Le code de retour peut-être $-1$ en cas d'erreur.
### Description
```c
int execl (const char *reference, const char *arg0, ..., NULL);
```
Le fichier de ```reference``` absolue ou relative (au répertoire de travail du processus) donnée est chargé et la fonction ```main``` correspondante est appelée avec les paramètres de la liste constituée par les autres paramètres. Le paramètre ```arg0``` est récupéré dans la fonction ```main``` dans ```argv[0]```.
#### Par exemple
```c
execl("/bin/ls", "ls", "-l", "/", NULL)
```
correspond à ```ls -l /```.
```c
int execlp (const char *reference, const char *arg0, ..., NULL);
```
se comporte comme la précédente sauf que si la ```reference``` est relative la recherche de la référence se fait dasn les répertoires spécifiés dans la varaible ```PATH``` de votre environnement.
```c
int execle (const char *reference, const char *arg0, ..., NULL, const char **arge);
```
même comportement que ```execl``` mais le dernier paramètre pointe sur un environnement à substituer à l'ancien. Un environnement est constitué d'un ensemble de pointeurs sur des chaines de la forme *nom=valeur* (la fin de la liste est marquée par le pointeur ```NULL```).
#### Exemple
```c
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
int main(int argc, char *argv[]) {
int ind;
char **ptr;
for (ind = 0; ind < argc; ind++) printf("%s\n", argv[ind]);
ptr = environ;
while (*ptr != NULL) printf("%s\n", *ptr++);
return EXIT_SUCCESS;
}
```
Dont voici une exécution :
```sh
bash-4.4$ ./recouvrante a s d f fg g=8
./recouvrante
a
s
d
f
fg
g=8
CONDA_SHLVL=1
CONDA_EXE=/anaconda3/bin/conda
LANG=fr_FR.UTF-8
XPC_FLAGS=0x0
DISPLAY=/private/tmp/com.apple.launchd.3687PRnHur/org.macosforge.xquartz:0
TERM_SESSION_ID=03974C81-0A61-46AD-80DE-7F8E93D00974
CONDA_PREFIX=/anaconda3
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.VXQ8jzyBiw/Listeners
USER=pvalarcher
PWD=/Users/pvalarcher/git/ASR31/notes_de_cours/Cours3
HOME=/Users/pvalarcher
CONDA_PYTHON_EXE=/anaconda3/bin/python
TERM_PROGRAM=Apple_Terminal
TERM_PROGRAM_VERSION=421.2
Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.MVmgyBLeD8/Render
TMPDIR=/var/folders/fz/3908mpd559x0cywbp_kvkhx00000gn/T/
CONDA_PROMPT_MODIFIER=
XPC_SERVICE_NAME=0
TERM=xterm-256color
SHELL=/bin/bash
SECURITYSESSIONID=186aa
SHLVL=2
LOGNAME=pvalarcher
PATH=/anaconda3/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Users/pvalarcher/anaconda/bin:/opt/local/bin:/opt/local/sbin:/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/opt/X11/bin
CONDA_DEFAULT_ENV=base
_=./recouvrante
OLDPWD=/Users/pvalarcher/git/ASR31/notes_de_cours
bash-4.4$
```
```c
int execv(const char *reference, const char *argv[]);
```
charge ```reference``` et appelle ```main``` avec les paramètres ```argc``` et ```argv```.
#### Exemple
```c
#include <stdio.h>
#include <unistd.h>
#define NMAX 5
main() {
char *argv[NMAX]; /* NMAX > 3 */
argv[0] = "ls"; argv[1] = "-l"; argv[2]="/"; argv[3]=NULL;
execv("/bin/ls", argv);
perror("execv");
}
```
#### Exercice
Montrer que ```argc``` contient bien la bonne valeur.
```c
int execvp(const char *reference, const char *argv[]);
```
comme ```execv``` mais avec recherche dans le cas ou ```reference``` est relative dans ```PATH```.
```c
int execvp(const char *reference, const char *argv[], const char **arge);
```
comme ```execv``` mais avec installation d'un nouvel environnement.
On peut modifier des attributs du processus après recouvrement.