Classification des appels système
Les appels système constituent l'interface entre les programmes utilisateur et le système d'exploitation. Ils permettent aux processus de demander des services au noyau.
Les appels système peuvent être regroupés en six catégories principales :
- Contrôle de processus
- Gestion de fichiers
- Gestion de périphériques
- Maintenance des informations
- Communications
- Protection
1. Appels système pour le contrôle de processus
Contrôle de processus
Ces appels système permettent de gérer le cycle de vie des processus : création, exécution, terminaison, etc.
Terminaison de processus
Un programme en cours d'exécution doit pouvoir arrêter son exécution :
- end() - Terminaison normale du programme
- abort() - Terminaison anormale du programme
Si un appel système est effectué pour terminer anormalement le programme en cours d'exécution, ou si le programme rencontre un problème et provoque une interruption d'erreur, un vidage de la mémoire (core dump) est parfois effectué et un message d'erreur est généré.
Le vidage est écrit dans un fichier journal spécial sur le disque et peut être examiné par un débogueur - un programme système conçu pour aider le programmeur à trouver et à corriger les erreurs - afin de déterminer la cause du problème.
Dans des circonstances normales ou anormales, le système d'exploitation doit transférer le contrôle à l'interpréteur de commandes appelant. L'interpréteur de commandes lit alors la commande suivante.
Chargement et exécution de programmes
Un processus exécutant un programme peut vouloir load() et execute() un autre programme. Cette fonctionnalité permet à l'interpréteur de commandes d'exécuter un programme en fonction, par exemple, d'une commande utilisateur ou d'un clic de souris.
Une question intéressante est de savoir où rendre le contrôle lorsque le programme chargé se termine. Cette question est liée à la question de savoir si le programme existant est perdu, enregistré ou autorisé à continuer son exécution en même temps que le nouveau programme.
| Cas | Comportement | Mécanisme |
|---|---|---|
| Retour au programme appelant | Le contrôle revient au programme existant lorsque le nouveau programme se termine | Il faut sauvegarder l'image mémoire du programme existant (création d'un mécanisme permettant à un programme d'appeler un autre programme) |
| Exécution concurrente | Les deux programmes se poursuivent simultanément | Création d'un nouveau processus à multiprogrammer via create_process() |
Il y a tellement de facettes et de variations dans le contrôle des processus que nous discuterons en détail dans le cours sur la gestion des processus.
Exemples d'appels système de contrôle de processus sous Unix/Linux
| Appel système | Description |
|---|---|
fork() | Crée un nouveau processus (équivalent à create_process) |
exec() famille | Remplace l'image mémoire du processus par un nouveau programme (load + execute) |
exit() | Termine le processus en cours (end) |
wait() | Attend la terminaison d'un processus enfant |
kill() | Envoie un signal pour terminer un processus (peut provoquer abort) |
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork(); // Appel système pour créer un processus
if (pid == 0) {
// Processus enfant
printf("Je suis le processus enfant\n");
execl("/bin/ls", "ls", "-l", NULL); // Charge et exécute un nouveau programme
// Si execl échoue
perror("execl a échoué");
_exit(1); // Terminaison anormale
}
else if (pid > 0) {
// Processus parent
printf("Je suis le processus parent, mon enfant a le PID %d\n", pid);
wait(NULL); // Attend la terminaison de l'enfant
printf("L'enfant a terminé\n");
}
else {
// Erreur
perror("fork a échoué");
return 1;
}
return 0; // Terminaison normale
}2. Appels système pour la gestion de fichiers
Gestion de fichiers
Ces appels système sont responsables de la manipulation de fichiers tels que la création d'un fichier, la lecture d'un fichier, l'écriture dans un fichier, etc.
Exemples d'appels système de gestion de fichiers sous Unix/Linux
| Appel système | Description |
|---|---|
open() | Ouvre un fichier |
read() | Lit des données depuis un fichier |
write() | Écrit des données dans un fichier |
close() | Ferme un fichier |
creat() | Crée un fichier |
unlink() | Supprime un fichier |
lseek() | Déplace le pointeur de lecture/écriture |
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd;
char buffer[100];
ssize_t bytes_read, bytes_written;
// Création/ouverture d'un fichier (appel système open)
fd = open("exemple.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("Erreur d'ouverture");
return 1;
}
// Écriture dans le fichier (appel système write)
bytes_written = write(fd, "Bonjour, monde!\n", 16);
if (bytes_written == -1) {
perror("Erreur d'écriture");
}
// Fermeture du fichier (appel système close)
close(fd);
// Réouverture en lecture
fd = open("exemple.txt", O_RDONLY);
if (fd == -1) {
perror("Erreur de réouverture");
return 1;
}
// Lecture du fichier (appel système read)
bytes_read = read(fd, buffer, sizeof(buffer) - 1);
if (bytes_read == -1) {
perror("Erreur de lecture");
} else {
buffer[bytes_read] = '\0';
printf("Lu: %s", buffer);
}
close(fd);
return 0;
}3. Appels système pour la gestion des périphériques
Gestion des périphériques
Un processus peut avoir besoin de plusieurs ressources pour s'exécuter : mémoire principale, lecteurs de disque, accès aux fichiers, etc.
Si les ressources sont disponibles, elles peuvent être accordées et le contrôle peut être rendu au processus utilisateur. Sinon, le processus devra attendre que des ressources suffisantes soient disponibles.
Le contrôle de ces ressources se fait par différents appels système. Ces appels système sont responsables de la manipulation de l'appareil, comme la lecture à partir des tampons de l'appareil, l'écriture dans les tampons de l'appareil, etc.
Exemples d'appels système de gestion de périphériques
| Appel système | Description |
|---|---|
ioctl() | Contrôle de périphérique (paramètres, configuration) |
read() | Lecture depuis un périphérique |
write() | Écriture vers un périphérique |
open() | Obtention d'un accès à un périphérique |
close() | Libération d'un périphérique |
request_region() | Demande de région d'E/S (noyau) |
4. Appels système pour la maintenance des informations
Maintenance des informations
De nombreux appels système existent simplement dans le but de transférer des informations entre le programme utilisateur et le système d'exploitation.
Informations temporelles et système
La plupart des systèmes ont un appel système pour renvoyer l'heure actuelle time() et la date(). D'autres appels système peuvent renvoyer des informations sur le système, telles que :
- Le numéro de version du système d'exploitation
- La quantité de mémoire libre
- L'espace disque disponible
- Le nombre d'utilisateurs connectés
Débogage
Un autre ensemble d'appels système est utile pour déboguer un programme. De nombreux systèmes fournissent des appels système pour effectuer un vidage mémoire dump(). Cette fonction est utile pour le débogage.
Exemples d'appels système de maintenance d'informations sous Unix/Linux
| Appel système | Description |
|---|---|
time() | Retourne l'heure actuelle |
gettimeofday() | Retourne l'heure avec plus de précision |
uname() | Retourne des informations sur le système (version, nom, etc.) |
getpid() | Retourne l'identifiant du processus |
getppid() | Retourne l'identifiant du processus parent |
getuid() | Retourne l'identifiant de l'utilisateur |
sysinfo() | Retourne des informations sur le système (mémoire, processus, etc.) |
#include <stdio.h>
#include <time.h>
#include <sys/utsname.h>
#include <unistd.h>
int main() {
// Obtenir l'heure actuelle
time_t t = time(NULL);
printf("Heure actuelle : %s", ctime(&t));
// Obtenir des informations sur le système
struct utsname sys_info;
if (uname(&sys_info) == 0) {
printf("Système : %s\n", sys_info.sysname);
printf("Nom d'hôte : %s\n", sys_info.nodename);
printf("Version : %s\n", sys_info.version);
printf("Machine : %s\n", sys_info.machine);
}
// Obtenir les identifiants de processus
printf("PID : %d\n", getpid());
printf("PID parent : %d\n", getppid());
return 0;
}5. Appels système pour les communications
Communications interprocessus
Il existe deux modèles courants de communication interprocessus : le modèle de transmission de messages et le modèle de mémoire partagée.
Modèle de transmission de messages
Dans le modèle de transmission de messages, les processus communicants échangent des messages entre eux pour transférer des informations. Les messages peuvent être échangés entre les processus directement ou indirectement via une boîte aux lettres commune.
Avant que la communication puisse avoir lieu, une connexion doit être ouverte. Le nom de l'autre communicateur doit être connu, qu'il s'agisse d'un autre processus sur le même système ou d'un processus sur un autre ordinateur connecté par un réseau de communication.
Modèle de mémoire partagée
Dans le modèle de mémoire partagée, les processus utilisent les appels système shared_memory_create() et shared_memory_attach() pour créer et accéder aux régions de mémoire détenues par d'autres processus.
Cette notion sera détaillée dans un autre article.
Exemples d'appels système de communication sous Unix/Linux
| Modèle | Appel système | Description |
|---|---|---|
| Messages | pipe() | Crée un tube de communication (communication unidirectionnelle) |
msgget() | Crée ou accède à une file de messages | |
msgsnd() / msgrcv() | Envoie/reçoit des messages | |
| Mémoire partagée | shmget() | Crée un segment de mémoire partagée (équivalent à shared_memory_create) |
shmat() | Attache un segment de mémoire partagée (équivalent à shared_memory_attach) | |
| Sockets | socket() | Crée un point de communication réseau |
connect() / bind() | Établit une connexion ou lie un socket |
6. Appels système pour la protection
Protection
La protection fournit un mécanisme pour contrôler l'accès aux ressources fournies par un système informatique.
Historiquement, la protection n'était une préoccupation que sur les systèmes informatiques multiprogrammés avec plusieurs utilisateurs. Cependant, avec l'avènement des réseaux et d'Internet, tous les systèmes informatiques, des serveurs aux appareils portables mobiles, doivent être concernés par la protection.
Appels système typiques pour la protection
- set_permission() et get_permission() - manipulent les paramètres d'autorisation des ressources telles que les fichiers et les disques.
- allow_user() et deny_user() - spécifient si des utilisateurs particuliers peuvent (ou ne peuvent pas) être autorisés à accéder à certaines ressources.
Exemples d'appels système de protection sous Unix/Linux
| Appel système | Description | Équivalent conceptuel |
|---|---|---|
chmod() | Change les permissions d'un fichier | set_permission |
chown() | Change le propriétaire d'un fichier | allow_user/deny_user |
umask() | Définit le masque de création de fichiers | set_permission |
access() | Vérifie les permissions d'accès d'un fichier | get_permission |
setuid() / setgid() | Change l'identifiant utilisateur/groupe | allow_user |
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
int main() {
// Créer un fichier avec des permissions spécifiques
FILE* f = fopen("secret.txt", "w");
if (f) {
fprintf(f, "Données sensibles\n");
fclose(f);
}
// Changer les permissions (set_permission)
// rw-r--r-- (644) : lecture/écriture pour propriétaire, lecture seulement pour autres
if (chmod("secret.txt", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == 0) {
printf("Permissions modifiées avec succès\n");
}
// Vérifier les permissions (get_permission)
if (access("secret.txt", R_OK) == 0) {
printf("Le fichier est lisible\n");
}
if (access("secret.txt", W_OK) == 0) {
printf("Le fichier est accessible en écriture\n");
}
return 0;
}Récapitulatif des catégories d'appels système
| Catégorie | Fonction | Exemples d'appels |
|---|---|---|
| Contrôle de processus | Gestion du cycle de vie des processus | end(), abort(), load(), execute(), create_process() |
| Gestion de fichiers | Manipulation des fichiers (création, lecture, écriture) | open(), read(), write(), close(), creat() |
| Gestion de périphériques | Contrôle des ressources matérielles | ioctl(), read(), write() sur fichiers de périphériques |
| Maintenance des informations | Obtention d'informations système et débogage | time(), date(), dump(), getpid() |
| Communications | Communication entre processus | shared_memory_create(), shared_memory_attach(), pipe() |
| Protection | Contrôle d'accès aux ressources | set_permission(), get_permission(), allow_user(), deny_user() |
Identifier les catégories d'appels système
Pour chacun des scénarios suivants, identifiez à quelle catégorie d'appels système il appartient :
- Un programme demande à connaître l'heure actuelle.
- Un processus crée un processus enfant.
- Un éditeur de texte sauvegarde un fichier sur le disque.
- Un navigateur web envoie une requête à un serveur.
- L'utilisateur change les permissions d'un fichier avec la commande chmod.
- Un pilote de périphérique envoie une commande à une imprimante.
- Un programme affiche un message d'erreur et se termine anormalement.
- Deux processus échangent des données via un segment de mémoire partagée.
- Connaître l'heure actuelle : Maintenance des informations (time, date)
- Création d'un processus enfant : Contrôle de processus (create_process, fork)
- Sauvegarde d'un fichier : Gestion de fichiers (write, close)
- Requête réseau : Communications (socket, send)
- Changement de permissions : Protection (set_permission, chmod)
- Commande à une imprimante : Gestion de périphériques (ioctl, write)
- Terminaison anormale : Contrôle de processus (abort)
- Échange via mémoire partagée : Communications (shared_memory_create, shared_memory_attach)
- Les appels système sont regroupés en six catégories principales : contrôle de processus, gestion de fichiers, gestion de périphériques, maintenance des informations, communications et protection.
- Le contrôle de processus gère la création, l'exécution et la terminaison des processus (end, abort, load, execute, create_process).
- La gestion de fichiers permet de manipuler les fichiers (ouverture, lecture, écriture, fermeture).
- La gestion de périphériques contrôle l'accès aux ressources matérielles.
- La maintenance des informations fournit des données sur le système (heure, version, mémoire) et facilite le débogage.
- Les communications permettent aux processus d'échanger des données (messages, mémoire partagée).
- La protection gère les droits d'accès aux ressources (permissions, autorisations utilisateur).
- Chaque système d'exploitation implémente ces catégories avec des appels système spécifiques (ex: fork, exec, open, read, write sous Unix/Linux).
Discussion (0)
Soyez le premier à laisser un commentaire !
Laisser un commentaire
Votre commentaire sera visible après modération.