Programmation syst`eme de commandes en C Cours de ”Programmation syst`eme”
Tuyˆet Trˆam DANG NGOC
Universit´ e de Cergy-Pontoise
2012–2013
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
1 / 31
Plan
1
Caract´eristiques d’une commande bien programm´ee
2
Programmation de commandes
3
Primitives syst`eme
4
Descripteurs de fichiers
5
Applications : r´e´ecriture de la commande ”wc”
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
2 / 31
Caract´ eristiques d’une commande bien programm´ ee
1
Caract´eristiques d’une commande bien programm´ee
2
Programmation de commandes
3
Primitives syst`eme
4
Descripteurs de fichiers
5
Applications : r´e´ecriture de la commande ”wc”
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
3 / 31
Caract´ eristiques d’une commande bien programm´ ee
Caract´eristiques d’une commande bien programm´ee Arguments en ligne de commande : La commande peut ˆetre 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 : `a la fin de l’ex´ecution de la commande, une valeur de retour est renvoy´ee (visible par dans le shell). 0 signale que la commande s’est termin´ee normalement. Gestion des erreurs : la commande v´erifie toutes les valeurs de retour des appels de primitives syst`eme (fichier inexistant, erreur de permission, etc.) Utilisation des flux d’entr´ees/sorties standards : l’affichage a lieu sur la sortie standard, les messages d’erreurs doivent ˆetre envoy´es sur l’erreur standard. Si cela est pertinent, une gestion de l’entr´ee standard doit ˆetre r´ealis´ee. Portabilit´e : La commande doit ˆetre ´ecrite en utilisant autant que possible les standards (SVr4, 4.3BSD, POSIX.1, POSIX.2, etc.). Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
4 / 31
Programmation de commandes
1
Caract´eristiques d’une commande bien programm´ee
2
Programmation de commandes
3
Primitives syst`eme
4
Descripteurs de fichiers
5
Applications : r´e´ecriture de la commande ”wc”
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme 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ˆeme argv : est un tableau contenant tous les arguments y compris la commande elle-mˆeme ./monprogramme argument1 argument2 argument3 argv [0] *argv []
argv [1]
./monprogramme
argument1
argv [2]
argv [3]
argv [argc]
argument2
argument3
NULL
argc = 4
Code source de argument.c
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
6 / 31
Programmation de commandes
Gestion des arguments : exemple argument.c
#include 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ˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
7 / 31
Programmation de commandes
R´ecup´eration d’options int getopt(int argc, char * const argv[], const char *format) ; argc et argv : Nombre et valeur des arguments. R´ecup´er´e en g´en´eral tel quel du main. format chaine de caract`eres form´ee par tous les caract`eres utilisables pour les options. Les options prenant un argument doivent ˆetre suivi du caract`ere ’ :’. 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 extern char *optarg; extern int optind ; extern int opterr ; extern int optopt;
/* /* /* /*
argument des options */ curseur option */ mis ` a 0 si pas d’erreur */ options inconnue ou en erreur (sans argumen
Code source de options.c
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
8 / 31
Programmation de commandes
Gestion des options : exemple options.c #include #include 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ˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
9 / 31
Programmation de commandes
Valeur de retour
La valeur de retour du return de la fonction main d´etermine 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 l tout s’est bien pass´ e */ } Code source de retour.c
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
10 / 31
Programmation de commandes
Renvoi d’une valeur de retour : exemple retour.c
#include #include 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ˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
11 / 31
Programmation de commandes
Gestion des erreurs Les primitives syst`emes (gestion de fichiers, gestion des processus, ...) retournent un nombre diff´erent de 0 lorsqu’elles rencontrent une erreur (pb droit d’acc`es, fichier inexistant, cr´eation de processus impossible, pb d’acc`es `a un p´eriph´erique, ...). On peut identifier l’erreur (code d’erreur et message associ´e). void perror(const char *chaine) Affiche sur l’erreur standard la chaine suivi du message d’erreur. #include void perror(const char *s); #include extern int errno ; Code source de erreur.c
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
12 / 31
Programmation de commandes
Gestion des erreurs : exemple erreur.c
#include #include #include 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ˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
13 / 31
Primitives syst` eme
1
Caract´eristiques d’une commande bien programm´ee
2
Programmation de commandes
3
Primitives syst`eme
4
Descripteurs de fichiers
5
Applications : r´e´ecriture de la commande ”wc”
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
14 / 31
Primitives syst` eme
Langage C, Primitives syst`eme et fonctions de biblioth`eques Le langage C ne d´efinit que le langage proprement dit. Ceci permet une plus grande souplesse dans le traitement des entr´ees/sorties et dans l’interface avec le syst`eme. l’acc`es aux services du syst`eme Unix est r´ealis´ee au moyen des appels syst`eme, encore appel´es primitives syst`eme : Gestion memoire, processus, interprocessus, horloge, systeme de fichier, ressources machine. Ces primitives syst`emes sont pour la plupart d´efinies dans unistd.h et sys/*.h et sont toutes document´ees dans le chapitre 2 du man (faire man 2 commande) Le programmeur dispose de nombreuses biblioth`eques C, depuis la gestion de la vid´eo jusqu’aux fonctions math´ematiques. Ces biblioth`eques sont plus ou moins standardis´ees, plus ou moins communes aux syst`emes. Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
15 / 31
Primitives syst` eme
Biblioth`eque standard
Une biblioth`eque est particuli`ere et commune : la biblioth`eque standard (libc). L’´editeur de liens la prend automatiquement. Ses fonctions peuvent ˆetre class´ees en grandes cat´egories : les fonctions d’entr´ees / sorties les fonctions de gestion de la m´emoire les fonctions sur les caract`eres et les chaˆınes les fonctions associ´ees aux sockets Berkeley les fonctions syst`eme
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
16 / 31
Descripteurs de fichiers
1
Caract´eristiques d’une commande bien programm´ee
2
Programmation de commandes
3
Primitives syst`eme
4
Descripteurs de fichiers
5
Applications : r´e´ecriture de la commande ”wc”
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
17 / 31
Descripteurs de fichiers
”Tout est fichier”
table des descripteurs
read 0
Processus
1 2 3
write write read Fichier Fichier
4 ...
write Fichier
read
18 42
read write
Internet 11 00 00 11 00 11 00 11
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme 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 ˆetre ouvert. flags : O RDONLY (lecture seule), O WRONLY (´ecriture seule), O RDWR (lecture/´ecriture), O CREAT (cr´eer le fichier), O TRUNC (tronquer le fichier), O APPEND (concat´ener au fichier), O NDELAY (lire/´ecrire sans d´elai), etc. mode : (facultatif) S I(RWX)(USR,GRP,OTH) ou 0640
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme 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ˆ et Trˆ am DANG NGOC
Programmation syst` eme 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’`a count octets depuis le descripteur de fichier fd dans le tampon point´e par buf. ssize t et size t sont des entiers. renvoie le nombre d’octets lus (0 signifiant aucune ´ecriture), ou -1 s’il ´echoue. Si le nombre renvoy´e est plus petit que le nombre demand´e, c’est que la fin du fichier a ´et´e rencontr´ee ou que la commande a ´et´e interrompue par un signal. char buf [MAX] ; ... for (i = 0 ; i < while ((n = read printf ("Voici for (i = 0 ; i } printf ("Voici ...
MAX ; i++) { buf [i] = 0 ;} (desc_orig, buf, MAX-1)) == MAX-1) { les %d caract` eres que j’ai lu : [%s] < MAX ; i++) { buf [i] = 0 ;} les %d caract` eres que j’ai lu : [%s]
n", n, buf) ;
n", n, buf) ;
Code source de lire.c Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
21 / 31
Descripteurs de fichiers
Lecture d’un fichier : exemple lire.c #include #include #include #include
#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ˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
22 / 31
Descripteurs de fichiers
Ecriture dans un descripteur
ssize t write(int fd, const void *buf, size t count) ´ecrit jusqu’`a count octets dans le fichier associ´e au descripteur fd depuis le tampon point´e par buf. ssize t et size t sont des entiers. renvoie le nombre d’octets ´ecrits (0 signifiant aucune ´ecriture), ou -1 s’il ´echoue. ... for (i = 0 ; i < MAX ; i++) { buf [i] = 0 ;} strcpy (buf, "Ca va ? n") ; n = write (desc_copie, buf, strlen ("Ca va ? printf ("Voici les %d caract` eres que j’ai ecrit : [%s] ...
n")) ; n", n, buf) ;
Code source de ecrire.c
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
23 / 31
Descripteurs de fichiers
Ecriture dans un fichier : exemple ecrire.c #include #include #include #include #include #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 : n = write (desc_copie, buf, strlen ("Ca va ?\n")) printf ("Voici les %d caracteres que j’ai ecrit :
; [%s]\n", n, buf) ; ; [%s]\n", n, buf) ;
close (desc_copie) ; return 0 ; } Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
24 / 31
Descripteurs de fichiers
Fermeture d’un fichier
int close (int fd) ferme le descripteur fd, de mani`ere `a ce qu’il ne r´ef´erence plus aucun fichier, et puisse ˆetre r´eutilis´e. 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ˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
25 / 31
Descripteurs de fichiers
Gestion d’un fichier : exemple complet copier.c #include #include #include #include
#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ˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
26 / 31
Descripteurs de fichiers
Entr´ee/Sortie/Erreur standards
Rappel : Sortie standard Entrée standard (stdin, 0)
Commande
(stdout, 1) Erreur standard (stderr, 2)
Les descripteurs 0, 1 et 2 sont ouverts par d´efaut. Code source de entreestd.c Code source de sortiestd.c
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
27 / 31
Descripteurs de fichiers
Gestion de l’entr´ee standard : exemple entreestd.c
#include #include #include #include
#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ˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
28 / 31
Descripteurs de fichiers
Gestion de la sortie et de l’erreur standard : exemple sortiestd.c #include #include #include #include #include #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ˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
29 / 31
Applications : r´ e´ ecriture de la commande ”wc”
1
Caract´eristiques d’une commande bien programm´ee
2
Programmation de commandes
3
Primitives syst`eme
4
Descripteurs de fichiers
5
Applications : r´e´ecriture de la commande ”wc”
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
30 / 31
Applications : r´ e´ ecriture de la commande ”wc”
R´e´ecriture de la commande ”wc”
Voir le cours de Pierre Andry Code source de wc2.c
Tuyˆ et Trˆ am DANG NGOC
Programmation syst` eme de commandes en C
31 / 31