ASR31-valarche-2021/ASR31-Cours4.md
2021-09-29 12:27:31 +02:00

161 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 dans les répertoires spécifiés dans la variable ```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.