TP ‐ Appels systèmes en C - vbridonneau/CoursSysteme GitHub Wiki

Appels système en C

Gestion des erreurs

Écrivez une macro (ou une fonction) check qui prend en paramètre le retour d'uun appel système (int), vérifie si celui-ci s'est bien terminé et, si ce n'est pas le cas, affiche un message d'erreur et sort du programme avec un appel à la fonction exit. Pour vous aider, vous pourrez utiliser la fonction perror avec le paramètre "" qui affiche sur la sortie d'erreur un message d'erreur en adéquation avec l'erreur survenue. Elle est définie comme suit :

#include <stdio.h>

void perror(const char *s);

Fonctions print et scan

Dans les deux petits exercices qui suivent, on se propose d'utiliser des appels systèmes pour lire depuis le terminal et écrire dans un fichier. L'idée est d'apprendre à utiliser des appels systèmes et à gérer les potentielles erreurs qui pourrait survenir lors de leur exécution.

Lecture depuis le terminal

Implémentez une fonction scan en langage C qui utilise l'appel système read pour lire une chaîne de caractères depuis l'entrée standard. La fonction doit prendre en paramètre un pointeur vers un buffer où stocker la chaîne lue et la taille maximale du buffer. La fonction doit retourner le nombre de caractères lus. Son prototype est le suivant :

int scan(char *chaine, int taille);

Utilisez ensuite votre fonction dans un programme pour la tester.

Écriture dans le terminal

Dans cet exercice, on se propose d'écrire une fonction print en C qui utilise l'appel système write pour écrire une chaîne de caractères dans un fichier passer en paramètres :

void print(const char *nomFichier, const char *chaine);

Pour y parvenir, nous allons procéder en trois étapes. Premièrement notre fonction va ouvrir le fichier avec un appel à la fonction open et vérifier qu'il n'y a pas eu d'erreur. Deuxièmement, notre fonction écrira dans le fichier la chaine de caractères chaine. Enfin, notre fonction fermera le fichier avec un appel à close avant de sortir de la fonction. Pour nous aider, on utilisera les flags O_CREAT, O_TRUNC et O_WRONLY qui permettent respectivment de créer un fichier un fichier si celui-ci n'existe pas, de supprimer son contenue si le fichier n'est pas vide et de pouvoir seulement écrire dans un fichier.

  1. Commencez par écrire le code permettant d'ouvrir le fichier ainsi que le code permettant de vérifier que l'appel système s'est bien exécuté (on pourra utiliser la fonction check codée précedemment).
    • Comment combiner les flags O_CREAT, O_TRUNC et O_WRONLY et les utiliser simultanément ?

La fonction open renvoit un descripteur de fichier permettant de modifier le fichier ouvert.

  1. Écrivez le code permettant d'écrire dans le fichier la chaine de caractère (on pourra utiliser la fonction strlen définie dans string.h pour calculer la taille d'une chaine de caractère). Pensez à vérifier le retour de l'appel système utilisé.

Une fois notre chaine écrite, il ne nous reste plus qu'à fermer le fichier.

  1. Écrivez le code permettant de fermer le fichier.

Test

Pour tester le code vous pouvez utiliser le programme suivant :

int main(int argc, char *argv[]) {
    char *buf = "Bravo d'être arrivé jusqu'ici !\n";
    print("felicitations.txt", buf);
    return 0;
}

Création de répertoire avec mkdir

Dans cet exercice, on se propose de créer une fonction creer_repertoire en C qui utilise l'appel système mkdir pour créer un répertoire. Cette fonction aura le prototype suivant :

void creer_repertoire(const char *chemin, mode_t mode);

Le paramètre chemin sera utilisé pour donner le nom du répertoire à créer et mode contiendra l'information concernant les droits du répertoire. La fonction a pour but de créer le répertoire s'il n'existe pas et de ne rien faire s'il existe. La façon de procéder est la suivante :

  1. Appelez la fonction mkdir en utilisant les paramètres de creer_repertoire.

Si le répertoire existe, la valeur de retour de mkdir est négatif et la variable globale errno, définie dans l'entête errno.h, aura pour valeur EEXIST.

  1. Vérifiez le code de retour de mkdir afin de sortir de la fonction si le répertoire existe déjà et appeler check avec comme paramètre -1 sinon.

Test

Pour tester le code vous pouvez utiliser le programme suivant (Pensez à le lancer deux fois pour tester ce qui se passe quand le répertoire à créer existe déjà):

int main() {
  creer_repertoire("repertoireCree", 0777);
  return 0;
}

Pour aller plus loin

Liste des appels systèmes avec strace

On va maintenant utiliser un programme qui nous permet de connaître les appels systèmes réalisés par un programme. Ce programme se nomme strace. Pour illustrer son utilisation, nous allons utiliser le programme suivant :

#include <stdio.h>

int main(int argc, char *argv[]) {
  printf("Hello world!\n");
  return 0;
}
  1. Copier ce code dans un fichier C et compilez le.

Nous allons maintenant exécuter strace. Ce programme prend en argument le chemin vers votre programme et des options si celui-ci en a besoin.

  1. Exécutez strace avec le programme précédement compilé et trouvé quel appel système a effectué l'affichage de la chaîne de caractère à l'écran.
⚠️ **GitHub.com Fallback** ⚠️