Programmation système de commandes en C Cours de Programmation système Tuyêt Trâm DANG NGOC <dntt@u-cergy.fr> Université de Cergy-Pontoise 2012 2013 Tuyêt Trâm DANG NGOC Programmation système de commandes en C 1 / 31
Plan 1 Caractéristiques d une commande bien programmée 2 Programmation de commandes 3 Primitives système 4 Descripteurs de fichiers 5 Applications : réécriture de la commande wc Tuyêt Trâm DANG NGOC Programmation système de commandes en C 2 / 31
Caractéristiques d une commande bien programmée 1 Caractéristiques d une commande bien programmée 2 Programmation de commandes 3 Primitives système 4 Descripteurs de fichiers 5 Applications : réécriture de la commande wc Tuyêt Trâm DANG NGOC Programmation système de commandes en C 3 / 31
Caractéristiques d une commande bien programmée Caractéristiques d une commande bien programmée Arguments en ligne de commande : La commande peut être suivie de 0, 1 ou plusieurs arguments. Options : Le comportement de la commande peut varier en fonction d options pouvant chacune prendre ou non des arguments. Valeur de retour : à la fin de l exécution de la commande, une valeur de retour est renvoyée (visible par dans le shell). 0 signale que la commande s est terminée normalement. Gestion des erreurs : la commande vérifie toutes les valeurs de retour des appels de primitives système (fichier inexistant, erreur de permission, etc.) Utilisation des flux d entrées/sorties standards : l affichage a lieu sur la sortie standard, les messages d erreurs doivent être envoyés sur l erreur standard. Si cela est pertinent, une gestion de l entrée standard doit être réalisée. Portabilité : La commande doit être écrite en utilisant autant que possible les standards (SVr4, 4.3BSD, POSIX.1, POSIX.2, etc.). Tuyêt Trâm DANG NGOC Programmation système de commandes en C 4 / 31
Programmation de commandes 1 Caractéristiques d une commande bien programmée 2 Programmation de commandes 3 Primitives système 4 Descripteurs de fichiers 5 Applications : réécriture de la commande wc Tuyêt Trâm DANG NGOC Programmation système de commandes en C 5 / 31
Programmation de commandes Gestion des arguments int main (int argc, char *argv []) argc : contient le nombre total d arguments de la commande y compris la commande elle-même argv : est un tableau contenant tous les arguments y compris la commande elle-même./monprogramme argument1 argument2 argument3 argv [0] argv [1] argv [2] argv [3] argv [argc] *argv []./monprogramme argument1 argument2 argument3 NULL argc = 4 Code source de argument.c Tuyêt Trâm DANG NGOC Programmation système de commandes en C 6 / 31
Programmation de commandes Gestion des arguments : exemple argument.c #include <stdio.h> int main (int argc, char *argv []) { int i ; printf ("Nombre d arguments : %d\n", argc) ; for (i = 0 ; i < argc ; i ++) { printf ("Argument %d : [%s]\n", i, argv [i]) ; return 0 ; Tuyêt Trâm DANG NGOC Programmation système de commandes en C 7 / 31
Programmation de commandes Récupération d options int getopt(int argc, char * const argv[], const char *format) ; argc et argv : Nombre et valeur des arguments. Récupéré en général tel quel du main. format chaine de caractères formée par tous les caractères utilisables pour les options. Les options prenant un argument doivent être suivi du caractère :. Avec le format : abc :de : $./monprogramme -a -b -c argumentc -d -e argumente arg1 arg2 arg3 $./monprogramme -bd -c argumentc -e argumente arg1 arg2 #include <unistd.h> extern char *optarg; /* argument des options */ extern int optind ; /* curseur option */ extern int opterr ; /* mis à 0 si pas d erreur */ extern int optopt; /* options inconnue ou en erreur (sans argumen Code source de options.c Tuyêt Trâm DANG NGOC Programmation système de commandes en C 8 / 31
Programmation de commandes Gestion des options : exemple options.c #include <unistd.h> #include <stdio.h> extern char *optarg; extern int optind ; int main(int argc, char *argv[]) { int options; char format[] = "abc:d:"; while ((options = getopt(argc, argv, format))!= -1) switch (options) { case a : printf ("Parametre a rencontre\n"); break; case b : printf ("Parametre b rencontre\n"); break; case c : printf ("Parametre c rencontre avec argument %s\n", optarg); break; case d : printf ("Parametre d rencontre avec argument %s\n", optarg); break; printf ("Le reste des arguments :\n") ; for (; optind < argc; ++optind) printf ("argv[%d] : %s\n", optind, argv[optind]); return 0; Tuyêt Trâm DANG NGOC Programmation système de commandes en C 9 / 31
Programmation de commandes Valeur de retour La valeur de retour du return de la fonction main détermine la valeur de retour du programme. int main () { if (il_y_a_des_erreurs ) return une_valeur_differente_de_zero ; return 0 ; /* valeur de retour du programme quand tout s est bien passé */ Code source de retour.c $ $ l Tuyêt Trâm DANG NGOC Programmation système de commandes en C 10 / 31
Programmation de commandes Renvoi d une valeur de retour : exemple retour.c #include <fcntl.h> #include <stdio.h> int main (int argc, char *argv []) { int desc ; if ((desc = open (argv [1], O_RDONLY)) == -1) { printf ("Ouverture du fichier echoue\n") ; return 1 ; printf ("Ouverture du fichier reussi\n") ; close (desc) ; return 0 ; Tuyêt Trâm DANG NGOC Programmation système de commandes en C 11 / 31
Programmation de commandes Gestion des erreurs Les primitives systèmes (gestion de fichiers, gestion des processus,...) retournent un nombre différent de 0 lorsqu elles rencontrent une erreur (pb droit d accès, fichier inexistant, création de processus impossible, pb d accès à un périphérique,...). On peut identifier l erreur (code d erreur et message associé). void perror(const char *chaine) Affiche sur l erreur standard la chaine suivi du message d erreur. #include <stdio.h> void perror(const char *s); #include <errno.h> extern int errno ; Code source de erreur.c Tuyêt Trâm DANG NGOC Programmation système de commandes en C 12 / 31
Programmation de commandes Gestion des erreurs : exemple erreur.c #include <errno.h> #include <stdio.h> #include <fcntl.h> extern int errno ; int main (int argc, char *argv []) { int desc ; if ((desc = open (argv [1], O_RDONLY)) == -1) { printf ("Erreur %d\n", errno) ; perror ("Erreur documentee") ; return errno ; else { printf ("Le fichier %s a bien ete ouvert\n", argv [1]) ; close (desc) ; return 0 ; Tuyêt Trâm DANG NGOC Programmation système de commandes en C 13 / 31
Primitives système 1 Caractéristiques d une commande bien programmée 2 Programmation de commandes 3 Primitives système 4 Descripteurs de fichiers 5 Applications : réécriture de la commande wc Tuyêt Trâm DANG NGOC Programmation système de commandes en C 14 / 31
Primitives système Langage C, Primitives système et fonctions de bibliothèques Le langage C ne définit que le langage proprement dit. Ceci permet une plus grande souplesse dans le traitement des entrées/sorties et dans l interface avec le système. l accès aux services du système Unix est réalisée au moyen des appels système, encore appelés primitives système : Gestion memoire, processus, interprocessus, horloge, systeme de fichier, ressources machine. Ces primitives systèmes sont pour la plupart définies dans unistd.h et sys/*.h et sont toutes documentées dans le chapitre 2 du man (faire man 2 commande) Le programmeur dispose de nombreuses bibliothèques C, depuis la gestion de la vidéo jusqu aux fonctions mathématiques. Ces bibliothèques sont plus ou moins standardisées, plus ou moins communes aux systèmes. Tuyêt Trâm DANG NGOC Programmation système de commandes en C 15 / 31
Primitives système Bibliothèque standard Une bibliothèque est particulière et commune : la bibliothèque standard (libc). L éditeur de liens la prend automatiquement. Ses fonctions peuvent être classées en grandes catégories : les fonctions d entrées / sorties les fonctions de gestion de la mémoire les fonctions sur les caractères et les chaînes les fonctions associées aux sockets Berkeley les fonctions système Tuyêt Trâm DANG NGOC Programmation système de commandes en C 16 / 31
Descripteurs de fichiers 1 Caractéristiques d une commande bien programmée 2 Programmation de commandes 3 Primitives système 4 Descripteurs de fichiers 5 Applications : réécriture de la commande wc Tuyêt Trâm DANG NGOC Programmation système de commandes en C 17 / 31
Descripteurs de fichiers Tout est fichier Fichier Fichier Fichier table des descripteurs Processus 0 1 2 3 read write write read 4... 18 42 write read read write Internet 00 11 00 11 00 11 00 11 Tuyêt Trâm DANG NGOC Programmation système de commandes en C 18 / 31
Descripteurs de fichiers Ouverture d un fichier int open(const char *pathname, int flags) int open(const char *pathname, int flags, mode t mode) Ouvre un fichier et retourne un descripteur sur ce fichier. Renvoi -1 si le fichier n a pu être ouvert. flags : O RDONLY (lecture seule), O WRONLY (écriture seule), O RDWR (lecture/écriture), O CREAT (créer le fichier), O TRUNC (tronquer le fichier), O APPEND (concaténer au fichier), O NDELAY (lire/écrire sans délai), etc. mode : (facultatif) S I(RWX)(USR,GRP,OTH) ou 0640 Tuyêt Trâm DANG NGOC Programmation système de commandes en C 19 / 31
Descripteurs de fichiers Ouverture d un fichier int desc_orig, desc_copie ; if ((desc_orig = open ("fichier", O_RDONLY)) == -1) { perror ("Erreur fichier source") ; return 1 ; if ((desc_copie = open ("copie", O_CREAT O_TRUNC O_WRONLY, S_IRUSR S_IWUSR S_IRGRP)) == -1) { perror ("Erreur fichier destination") ; return 1 ;... Code source de copier.c Tuyêt Trâm DANG NGOC Programmation système de commandes en C 20 / 31
Descripteurs de fichiers Lecture d un descripteur ssize t read(int fd, void *buf, size t count) lit jusqu à count octets depuis le descripteur de fichier fd dans le tampon pointé par buf. ssize t et size t sont des entiers. renvoie le nombre d octets lus (0 signifiant aucune écriture), ou -1 s il échoue. Si le nombre renvoyé est plus petit que le nombre demandé, c est que la fin du fichier a été rencontrée ou que la commande a été interrompue par un signal. char buf [MAX] ;... for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; while ((n = read (desc_orig, buf, MAX-1)) == MAX-1) { printf ("Voici les %d caractères que j ai lu : [%s] n", n, buf) ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; printf ("Voici les %d caractères que j ai lu : [%s] n", n, buf) ;... Code source de lire.c Tuyêt Trâm DANG NGOC Programmation système de commandes en C 21 / 31
Descripteurs de fichiers Lecture d un fichier : exemple lire.c #include <errno.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #define MAX 10 extern int errno ; int main () { int desc_orig ; int i, n ; char buf [MAX] ; if ((desc_orig = open ("fichier", O_RDONLY)) == -1) { perror ("Erreur fichier source") ; return 1 ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; while ((n = read (desc_orig, buf, MAX-1)) == MAX-1) { printf ("Voici les %d caracteres que j ai lu : [%s]\n", n, buf) ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; printf ("Voici les %d caracteres que j ai lu : [%s]\n", n, buf) ; close (desc_orig) ; return 0 ; Tuyêt Trâm DANG NGOC Programmation système de commandes en C 22 / 31
Descripteurs de fichiers Ecriture dans un descripteur ssize t write(int fd, const void *buf, size t count) écrit jusqu à count octets dans le fichier associé au descripteur fd depuis le tampon pointé par buf. ssize t et size t sont des entiers. renvoie le nombre d octets écrits (0 signifiant aucune écriture), ou -1 s il échoue.... for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; strcpy (buf, "Ca va? n") ; n = write (desc_copie, buf, strlen ("Ca va? n")) ; printf ("Voici les %d caractères que j ai ecrit : [%s] n", n, buf) ;... Code source de ecrire.c Tuyêt Trâm DANG NGOC Programmation système de commandes en C 23 / 31
Descripteurs de fichiers Ecriture dans un fichier : exemple ecrire.c #include <errno.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #define MAX 10 extern int errno ; int main () { int desc_copie ; int i, n ; char buf [MAX] ; if ((desc_copie = open ("copie", O_CREAT O_TRUNC O_WRONLY, S_IRUSR S_IWUSR S_IRGRP)) == -1) { perror ("Erreur fichier destination") ; return 1 ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; strcpy (buf, "Bonjour\n") ; n = write (desc_copie, buf, strlen ("Bonjour\n")) ; printf ("Voici les %d caracteres que j ai ecrit : [%s]\n", n, buf) ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; strcpy (buf, "Ca va?\n") ; n = write (desc_copie, buf, strlen ("Ca va?\n")) ; printf ("Voici les %d caracteres que j ai ecrit : [%s]\n", n, buf) ; n = write (desc_copie, buf, strlen ("Ca va?\n")) ; printf ("Voici les %d caracteres que j ai ecrit : [%s]\n", n, buf) ; close (desc_copie) ; return 0 ; Tuyêt Trâm DANG NGOC Programmation système de commandes en C 24 / 31
Descripteurs de fichiers Fermeture d un fichier int close (int fd) ferme le descripteur fd, de manière à ce qu il ne référence plus aucun fichier, et puisse être réutilisé. int desc_orig, desc_copie ;... desc_orig = open ("fichier", O_RDONLY) ; desc_copie = open ("copie", O_CREAT O_TRUNC O_WRONLY, S_IRUSR S_IWUSR S_IRGRP) ;... close (desc_orig) ; close (desc_copie) ; Code source de copier.c Tuyêt Trâm DANG NGOC Programmation système de commandes en C 25 / 31
Descripteurs de fichiers Gestion d un fichier : exemple complet copier.c #include <errno.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #define MAX 10 extern int errno ; int main () { int desc_orig, desc_copie ; int i, n ; char buf [MAX] ; if ((desc_orig = open ("fichier", O_RDONLY)) == -1) { perror ("Erreur fichier source") ; return 1 ; if ((desc_copie = open ("copie", O_CREAT O_TRUNC O_WRONLY, S_IRUSR S_IWUSR S_IRGRP)) == -1) { perror ("Erreur fichier destination") ; return 1 ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; while ((n = read (desc_orig, buf, MAX-1)) == MAX-1) { printf ("Voici les %d caracteres que j ai lu : [%s]\n", n, buf) ; write (desc_copie, buf, n) ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; printf ("Voici les %d caracteres que j ai lu : [%s]\n", n, buf) ; write (desc_copie, buf, n) ; close (desc_orig) ; close (desc_copie) ; return 0 ; Tuyêt Trâm DANG NGOC Programmation système de commandes en C 26 / 31
Descripteurs de fichiers Entrée/Sortie/Erreur standards Rappel : Entrée standard (stdin, 0) Commande Sortie standard (stdout, 1) Erreur standard (stderr, 2) Les descripteurs 0, 1 et 2 sont ouverts par défaut. Code source de entreestd.c Code source de sortiestd.c Tuyêt Trâm DANG NGOC Programmation système de commandes en C 27 / 31
Descripteurs de fichiers Gestion de l entrée standard : exemple entreestd.c #include <errno.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #define MAX 10 extern int errno ; int main () { int i, n ; char buf [MAX] ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; while ((n = read (0, buf, MAX-1)) == MAX-1) { printf ("Voici les %d caracteres que j ai lu : [%s]\n", n, buf) ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; printf ("Voici les %d caracteres que j ai lu : [%s]\n", n, buf) ; return 0 ; Tuyêt Trâm DANG NGOC Programmation système de commandes en C 28 / 31
Descripteurs de fichiers Gestion de la sortie et de l erreur standard : exemple sortiestd.c #include <errno.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #define MAX 10 extern int errno ; int main () { int i, n ; char buf [MAX] ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; strcpy (buf, "En sortie\n") ; n = write (1, buf, strlen ("En sortie\n")) ; for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ; strcpy (buf, "En erreur\n") ; n = write (2, buf, strlen ("En erreur\n")) ; return 0 ; Tuyêt Trâm DANG NGOC Programmation système de commandes en C 29 / 31
Applications : réécriture de la commande wc 1 Caractéristiques d une commande bien programmée 2 Programmation de commandes 3 Primitives système 4 Descripteurs de fichiers 5 Applications : réécriture de la commande wc Tuyêt Trâm DANG NGOC Programmation système de commandes en C 30 / 31
Applications : réécriture de la commande wc Réécriture de la commande wc Voir le cours de Pierre Andry Code source de wc2.c Tuyêt Trâm DANG NGOC Programmation système de commandes en C 31 / 31