Développement UNIX en langage C Le C-UNIX

Download Report

Transcript Développement UNIX en langage C Le C-UNIX

Développement C-UNIX
Développement UNIX en langage C
ISR-CSYS-02-001-01
Le C-UNIX
Chapitre 3/15 : Les
ISR-CSYS-02-001-03
processus et le job control
Samir RINAZ © 2005 pour ETNA
Plan de l’UV
Développement C-UNIX
Plan de l’UV ISR-CSYS-02-001:
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
ISR-CSYS-02-001-03
01/ malloc()
02/ Les signaux
03/ Les processus et le job control
04/ pipe / redirection
05/ Les devices
06/ Gestion des entrée/sorties avancées
07/ Gestion des terminaux
08/ mmap()
09/ Les threads
10/ Communication interprocessus
11/ Communication interprocessus avancée
12/ Le format elf
13/ Le file systeme /proc
14/ L’assembleur in-line
15/ Sécurité des développement en C-UNIX
Samir RINAZ © 2005 pour ETNA
Rappel sur les processus 1
Développement C-UNIX
• Les processus sont des instances d’un programme fonctionnant.
• On peut les lister avec la commande « ps ».
• Tout les processus ont un processus parent qui donnent lieux à
l’éxecution.
• La commande « pstree » donnant l’arborescence des processus, qui est
le père du fils, les un à coté des autres.
(53 asset@odrade ~) pstree
init-+-arlad
|-artsd
|-perl
|-rpcbind
|-3*[sh---sleep]
|-sshd-+-sshd---sshd---tcsh---pstree
|
|-2*[sshd---sshd---tcsh---ssh]
|
`-sshd---sshd---tcsh---mutt
|-syslogd
|-x11vnc---x11vnc
`-xdm-+-XFree86
`-xdm
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA
Les identifiants des processus
Développement C-UNIX
• Chaque processus a des identifiants
permettant de connaître :
– pid signifie Process IDentification. C’est tout
simplement l’identifiant du programme.
– ppid signifie Parent Process IDentification. C’est
l’identifiant du processus père du processus.
– pgid signifie Process Group IDentification. C’est
un identifiant du groupe de processus.
– sid signifie Session IDentification. C’est l’identifiant
de session correspondant au processus.
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA
Les appels systèmes mis en jeux
Développement C-UNIX
• getpid(), getppid() , getpgid(), getsid(),
permet à un processus de connaître tout les
identifiants que l’on vient d’énumérer
• fork(), permet à un processus de se
dédoubler.
• wait(), permet à un processus s’étant
dédoublé d’attendre et de connaître l’état
du processus fils.
• exec(), permet d’exécuter un programme à
partir d’un autre, la plupart du temps utilisé
après un fork().
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA
Famille de get[pid,ppid,pgid,sid]()
Développement C-UNIX
• SYNOPSIS
#include <unistd.h>
pid_t
getpid(void);
pid_t
getppid(void);
[…]
• Ces fonctions ne prennent pas de paramètre, elles retournent
respectivement l’identifiant nécéssaire
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA
fork()
Développement C-UNIX
• La fonction fork() est une fonction très
importante, elle permet de dupliquer un
programme. Après son appel, il faut
distinguer que l’on aura 2 occurrence du
processus totalement identique au pid près.
• SYNOPSIS
#include <unistd.h>
pid_t
fork(void);
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA
Exemple d’utilisation de fork()
Développement C-UNIX
int
main()
{
pid_t pid;
if ((pid = fork()) < 0)
printf("fork");
if (pid)
{
printf("je suis le pere de %d\n", pid);
}
else
{
sleep(1);
printf("je suis le fils\n");
}
my_putstr("mon pid est %d\n", getpid());
}
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA
Exemple d’utilisation de fork() suite
Développement C-UNIX
• À l’exécution, on obtient :
$ ./a.out
je suis le pere de 12708
mon pid est 12707
$ je suis le fils
mon pid est 12708
• On remarque que le code en dehors des conditions
liée à pid est exécuter par les deux processus.
• Notez bien que l’occurrence pour laquelle on a
bien une valeur de pid est le père, c’est lui qui
récupère la valeur de retour de fork() avec le pid
du fils.
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA
Famille des wait()
Développement C-UNIX
• SYNOPSIS
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t wpid, int *status, int options);
#include <sys/resource.h>
pid_t wait3(int *status, int options, struct rusage *rusage);
pid_t wait4(pid_t wpid, int *status, int options, struct rusage *rusage);
• La famille des fonctions wait() permet à un
processus d’attendre la fin de l’exécution
d’un autre processus. Typiquement c’est le
cas d’un père par rapport à sont fils.
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA
Famille des exec*()
Développement C-UNIX
•
SYNOPSIS
#include <unistd.h>
extern char **environ;
•
int
execl(const char *path, const char *arg, ...);
int
execlp(const char *file, const char *arg, ...);
int
envp[]);
execle(const char *path, const char *arg, ..., char *const
int
envp[]);
exect(const char *path, char *const argv[], char *const
int
execv(const char *path, char *const argv[]);
int
execvp(const char *file, char *const argv[]);
La famille des exec*() permet d’executer un programme, l’execution de celui-ci va
« recouvrir » le processus qui fait appel à l’un des exec*().
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA
Conclusion
Développement C-UNIX
• Avec tout ces éléments, vous pouvez
gerer les processus issus de l’exécution
de vos programme ou non. Vous allez
réaliser un des meilleurs exemples de
programme qui gère des processus fils,
un interpréteur de commande UNIX
• Pour la suite, le prochain cours est
« pipe / redirection »
ISR-CSYS-02-001-03
Samir RINAZ © 2005 pour ETNA