Download as pdf or txt
Download as pdf or txt
You are on page 1of 32

Unix/Linux Programmation Système C

Unix/Linux Programmation Système C

Yann Catanese

ISEN
XX Octobre 2023
Unix/Linux Programmation Système C

Sommaire

1 Entrées sorties
Acces aux chiers
Fichiers normaux
Les répertoires, les liens et les inodes

2 Les appels systèmes sur les chiers


Exemple d'entrées-sorties sur un chier
Descripteur de chier
creat(), open(), read(), write(), close()

3 Programmation
Gérer les erreurs
Portabilité
Unix/Linux Programmation Système C
Entrées sorties
Acces aux chiers

Entrées-sorties : Accès à un chier 1/2

ˆ Fichier : abstraction fondamentale Unix

ˆ Principe "tout est chier"


ˆ Toute entrée-sortie est réalisée sur un chier quelle que soit sa nature

ˆ Pour accéder à un chier, il doit être ouvert


ˆ Correspondance entre le processus et le chier lui-même : Le noyau
maintient une table des chiers ouverts indexée par des descripteurs (entier)
Unix/Linux Programmation Système C
Entrées sorties
Acces aux chiers

Entrées-sorties : Accès à un chier 2/2

ˆ Diérents types de chiers

ˆ Fichiers normaux : nos chiers de données (utilisateur)


ˆ Répertoires
ˆ Liens symboliques ou physiques(équivalents à des raccourcis)
ˆ Fichiers spéciaux :

ˆ Périphériques de type block


ˆ Périphériques de type char
ˆ Tubes nommés de communication entre processus
ˆ Socket Unix (communication réseau)
Unix/Linux Programmation Système C
Entrées sorties
Fichiers normaux

Fichiers normaux

ˆ Abstraction du Système d'Exploitation

ˆ Vision uniforme et logique indépendante du support


ˆ Correspondance entre une vision utilisateur et des caractéristiques
physiques
ˆ Plus petite unité d'allocation ayant un nom logique, visible par les
applications

ˆ Espace d'adressage logique contigu non typé (ot d'octets)


Unix/Linux Programmation Système C
Entrées sorties
Les répertoires, les liens et les inodes

Les répertoires et les liens

ˆ Les chiers sont référencés par des inodes dans le système de chiers
ˆ Structure de données de gestion de chier
ˆ Répéré par un entier unique dans le système de chiers
ˆ Système de chiers = espace d'adressage

ˆ Nécessité d'une fonction annuaire : les répertoires


ˆ Répertoire = chier contenant des couples (nom chier, numéro inode)
Unix/Linux Programmation Système C
Entrées sorties
Les répertoires, les liens et les inodes

Les répertoires et les liens (suite)

ˆ Trois répertoires point d'entrée :

ˆ La racine du SGF : le nom commence par '/' > désignation absolue


ˆ Le répertoire courant '.' désignation relative
ˆ Le répertoire précédent '..' désignation relative

ˆ Liens symboliques Fichier spécial contenant une désignation (nom de


chier)
Unix/Linux Programmation Système C
Entrées sorties
Les répertoires, les liens et les inodes

Structure de gestion : inode

ˆ Chaque chier est repéré par un


inode

ˆ type, mode, droits, accès,taille,


etc...

ˆ Données contenues dans des blocs

ˆ L'inode contient la liste indexée des


blocs alloués

ˆ Numéro d'inode unique par SGF

ˆ Stockés sur disque et en mémoire


noyau
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
Exemple d'entrées-sorties sur un chier

Modèle universel d'entrées-sorties

On retrouve les mêmes appels système pour tous les types de chiers, y compris
les périphériques.

ˆ open() : ouverture d'un chier

ˆ read() : lecture d'octets à partir d'un chier

ˆ write() : écriture d'octets vers un chier

ˆ close() : fermeture d'un chier

include
#include <sys / types . h>
#include <sys / stat . h>
#include <unistd . h>
#include <f c n t l . h>
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
Exemple d'entrées-sorties sur un chier

Exemple d'entrées-sorties sur un chier


ˆ creat() : création d'un chier
ˆ open() : ouverture d'un chier
ˆ read() : lecture d'octets à partir d'un chier
ˆ write() : écriture d'octets vers un chier
ˆ close() : fermeture d'un chier
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
Descripteur de chier

Descripteur de chier (le descriptor)

ˆ Référence à un chier ouvert

ˆ Entier (short) non négatif


ˆ Obtenu par un appel à open() avec un chemin d'accès

ˆ Chaque processus hérite de 3 descripteurs de chier ouvert

ˆ 0 : entrée standard (POSIX : STDIN_FILENO) (stdio : stdin)

ˆ 1 : entrée standard (POSIX : STDOUT_FILENO) (stdio : stdout)

ˆ 2 : entrée standard (POSIX : STDERR_FILENO) (stdio : stderr)


Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
Descripteur de chier

Descripteur de chier (suite)

ˆ Lien avec les entrées-sorties standards (prototypes dans <stdio.h>)


ˆ fopen(), fclose(), scanf(), printf(), fread(), fwrite() ...
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Descriptif creat
Include
sys/types.h
sys/stat.h
But : Création d'un chier. Si la création réussit, le chier est
fcntl.h
disponible via son le descritor pour des actions de
lecture/écriture suivant les options de ag. ATTENTION
Si le chier
existe, il sera
écrasé
Signature :
int creat(const char *pathname, int ags);
Paramètres :
const char *pathname : Chemin de création du chier
int ags : Type d'acces au chier
O_RDONLY,O_WRONLY,O_RDWR etc.
Valeur de retour int : Retourne le plus petit descripteur de chier (3 au
début) , ou -1 en cas d'erreur
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Exemple creat
Code Creat.c
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <s y s / t y p e s . h>
#i n c l u d e <s y s / s t a t . h>
#i n c l u d e < f c n t l . h>
i n t main ( i n t a r g c , c h a r ** a r g v , c h a r ** envp )
{
int iFileDescripteur ;
i F i l e D e s c r i p t e u r=c r e a t ( " . / New . t x t " ,O_RDONLY) ;
i f ( i F i l e D e s c r i p t e u r == =1 ) {
p e r r o r ( " I m p o s s i b l e de c r e e r l e f i c h i e r " ) ;
exit (1);
}
p r i n t f ( " F i c h i e r c r e e r o u v e r t , l e f i l e d e s c r i p t o r e s t %d \n" , i F i l e D e s c r i p t e u r ) ;
exit (0);
// REMARQUE : l e s y s t e m e c l o s automatiquement l e s
// f i l e d e s c r i p t o r o u v e r t s s u r f i n de p r o c e s s u s
}

Execution Creat
$ >./ C r e a t
F i c h i e r c r e e r ouvert , l e f i l e d e s c r i p t o r est 3
$>l s = l New . t x t
=rwx ====== 1 c a t a n e s e c a t a n e s e 0 j u i l . 12 1 5 : 2 2 New . t x t
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Descriptif open

But : Ouvrir un chier, attention comme tout est chier dans


Include
linux, cette fonction de base permet également d'ouvrir un pipe, sys/types.h

un socket réseau etc. sys/stat.h


fcntl.h

Signatures :
int open(const char *pathname, int ags);
int open(const char *pathname, int ags, mode_t mode);
Paramètres :
const char *pathname : Chemin d'accès au chier
int ags : Type d'acces au chier
O_RDONLY,O_WRONLY,O_RDWR etc.
mode_t mode : Droits attribué à un nouveau chier
S_IRWXU,S_IRUSR etc.

Valeur de retour int : Retourne le plus petit descripteur de chier (3 au


début) , ou -1 en cas d'erreur
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Exemple open
Code Open.c
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <s y s / t y p e s . h>
#i n c l u d e <s y s / s t a t . h>
#i n c l u d e < f c n t l . h>
i n t main ( i n t a r g c , c h a r ** a r g v , c h a r ** envp )
{
int iFileDescripteur ;
i F i l e D e s c r i p t e u r=open ( " . / Open . t x t " ,O_RDONLY) ;
i f ( i F i l e D e s c r i p t e u r == =1 ) {
perror (" Impossible d ' ouvrir le f i c h i e r " );
exit (1);
}
p r i n t f ( " F i c h i e r o u v e r t , l e f i l e d e s c r i p t o r a p o u r v a l e u r %d \n" , i F i l e D e s c r i p t e u r ) ;
exit (0);
// REMARQUE : l e s y s t e m e c l o s automatiquement l e s f i l e d e s c r i p t o r o u v e r t s s u r f i n de p r
}

Execution Open
$ >./Open
I m p o s s i b l e d ' o u v r i r l e f i c h i e r : No s u c h f i l e o r d i r e c t o r y
$>echo " t o t o " > Open . t x t
$ >./Open
F i c h i e r ouvert , l e f i l e d e s c r i p t o r a pour v a l e u r 3
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Exemple open avec création d'un nouveau chier


Code OpenNew.c
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <s y s / t y p e s . h>
#i n c l u d e <s y s / s t a t . h>
#i n c l u d e < f c n t l . h>
i n t main ( i n t a r g c , c h a r ** a r g v , c h a r ** envp )
{
int iFileDescripteur ;
i F i l e D e s c r i p t e u r=open ( "/New . t x t " ,O_RDWR|O_CREAT,S_IRWXU ) ;
i f ( i F i l e D e s c r i p t e u r == =1 ) {
p e r r o r ( " I m p o s s i b l e de c r e e r l e f i c h i e r " ) ;
}
i F i l e D e s c r i p t e u r=open ( " . / New . t x t " ,O_RDWR|O_CREAT,S_IRWXU ) ;
i f ( i F i l e D e s c r i p t e u r == =1 ) {
p e r r o r ( " I m p o s s i b l e de c r e e r l e f i c h i e r " ) ;
}
p r i n t f ( " F i c h i e r c r e e , l e f i l e d e s c r i p t o r a p o u r v a l e u r %d \n" , i F i l e D e s c r i p t e u r ) ;
exit (0);
}

Execution OpenNew
$ >./OpenNew
I m p o s s i b l e de c r e e r l e f i c h i e r : P e r m i s s i o n d e n i e d
F i c h i e r cree , l e f i l e d e s c r i p t o r a pour v a l e u r 3
$>l s = l New . t x t
=rwx ====== 1 c a t a n e s e c a t a n e s e 0 j u i l . 12 1 1 : 3 9 New . t x t
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Descriptif close

But : Ferme un chier, cette opération est réalisée par le


système quand le programme se termine normalement, il est Include
cependant souhaitable de l'utiliser pour libérer au plus tôt les
unistd.h
le descriptor non utlisés.
Signatures :
int close(int fd);
Paramètres :
int fd : descripteur du chier (ouvert) à fermer
Valeur de retour int : Retourne 0 en cas de succès, ou -1 en cas d'erreur
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Exemple close

Code Close.c
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <s y s / t y p e s . h>
#i n c l u d e <s y s / s t a t . h>
#i n c l u d e < f c n t l . h>
#i n c l u d e <u n i s t d . h>
i n t main ( i n t a r g c , c h a r ** a r g v , c h a r ** envp )
{
i n t i F i l e D e s c r i p t e u r , iRetourSystem ;
i F i l e D e s c r i p t e u r=open ( " . / Open . t x t " ,O_RDONLY) ;
i f ( i F i l e D e s c r i p t e u r == =1 ) {
perror (" Impossible d ' ouvrir le f i c h i e r " );
exit (1);
}
p r i n t f ( " F i c h i e r o u v e r t , l e f i l e d e s c r i p t o r a p o u r v a l e u r %d \n" , i F i l e D e s c r i p t e u r ) ;
i R e t o u r S y s t e m=c l o s e ( i F i l e D e s c r i p t e u r ) ;
i f ( i R e t o u r S y s t e m == =1) {
perror (" Impossible d ' ouvrir le f i c h i e r " );
exit (1);
}
p r i n t f ( " F i c h i e r ferme , l e f i l e d e s c r i p t o r a i v a i t p o u r v a l e u r %d \n" , i F i l e D e s c r i p t e u r ) ;
exit (0);
}
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Exemple close

Execution Close
$ >./ C l o s e
F i c h i e r ouvert , l e f i l e d e s c r i p t o r a pour v a l e u r 3
F i c h i e r ferme , l e f i l e d e s c r i p t o r a i v a i t p o u r v a l e u r 3
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Descriptif read

But : Permet de lire séquentiellement les données d'un chier Include


préalablement ouvert
unistd.h

Signature :
size_t read(int fd, void *buf, size_t count);
Paramètres :
int fd : Le le descriptor du chier obtenu après open our creat
void *buf : La chaine de caractères que l'on souhaite "remplir" des
caractères lus, passée par référence
size_t count : Le nombre d'octets que l'on souhaite lire
Valeur de retour int : Retourne le nombre d'octets eectivement lus, 0
en cas de n de chier, ou -1 en cas d'erreur
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Exemple read

Code Read.c
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <s y s / t y p e s . h>
#i n c l u d e <s y s / s t a t . h>
#i n c l u d e < f c n t l . h>
#i n c l u d e <u n i s t d . h>
#d e f i n e TAILLE_CHAINE 14
i n t main ( i n t a r g c , c h a r ** a r g v , c h a r ** envp )
{
int iFileDescripteur ;
s i z e _ t iNbLus ;
c h a r c p L i g n e [ TAILLE_CHAINE ] ;
i F i l e D e s c r i p t e u r=open ( " . / ReadSource . t x t " ,O_RDONLY) ;
i f ( i F i l e D e s c r i p t e u r == =1 ) {
perror (" Impossible d ' ouvrir le f i c h i e r " );
exit (1);
}
p r i n t f ( " F i c h i e r o u v e r t , l e f i l e d e s c r i p t o r a p o u r v a l e u r %d \n" , i F i l e D e s c r i p t e u r ) ;
iNbLus = r e a d ( i F i l e D e s c r i p t e u r , cpLigne , s i z e o f ( c p L i g n e ) ) ;
w h i l e ( iNbLus > 0){
p r i n t f ( " L i g n e l u e : %s de %d c a r a c t e r e s \n" , cpLigne , ( i n t ) iNbLus ) ;
iNbLus = r e a d ( i F i l e D e s c r i p t e u r , cpLigne , s i z e o f ( c p L i g n e ) ) ;
}
close ( iFileDescripteur );
exit (0);
}
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Exemple read

Execution ReadNew
$ >./ Read
F i c h i e r ouvert , l e f i l e d e s c r i p t o r a pour v a l e u r 3
L i g n e l u e : L i g n e un !
de 14 c a r a c t e r e s
L i g n e l u e : L i g n e deux !
de 14 c a r a c t e r e s
Ligne lue : Ligne t r o i s !
de 14 c a r a c t e r e s
Ligne lue : Ligne quatre !
de 14 c a r a c t e r e s
Ligne lue : Ligne cinq !
de 14 c a r a c t e r e s
Ligne lue : Ligne s i x !
de 14 c a r a c t e r e s
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Descriptif write

But : Permet d'écrire séquentiellement les données dans un Include


chier préalablement ouvert
unistd.h

Signature :
size_t write(int fd, void *buf, size_t count);
Paramètres :
int fd : Le le descriptor du chier obtenu après open our creat
void *buf : adresse d'une zone mémoire contenant les données à
écrire
size_t count : Le nombre d'octets que l'on souhaite écrire
Valeur de retour int : Retourne le nombre d'octets eectivement écrits,
ou -1 en cas d'erreur
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Exemple write
Code Write.c
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <s y s / t y p e s . h>
#i n c l u d e <s y s / s t a t . h>
#i n c l u d e < f c n t l . h>
#i n c l u d e <u n i s t d . h>
#i n c l u d e < s t r i n g . h>
#d e f i n e TAILLE_CHAINE 20
i n t main ( i n t a r g c , c h a r ** a r g v , c h a r ** envp ) {
int iFileDescripteur ;
size_t iNbEcrits ;
c h a r c p L i g n e [ TAILLE_CHAINE ] , cpNumero [ 3 ] ;
i F i l e D e s c r i p t e u r=open ( " . / W r i t e D e s t i n a t i o n . t x t " ,O_CREAT|O_WRONLY,S_IRWXU ) ;
i f ( i F i l e D e s c r i p t e u r == =1 ) {
perror (" Impossible d ' ouvrir le f i c h i e r " ); exit (1);
}
p r i n t f ( " F i c h i e r o u v e r t , l e f i l e d e s c r i p t o r a p o u r v a l e u r %d \n" , i F i l e D e s c r i p t e u r ) ;
f o r ( i n t i =1; i <11; i ++) {
b z e r o ( cpLigne , s i z e o f ( c p L i g n e ) ) ; // on met l e b u f f e r a z e r o
s t r c p y ( cpLigne , " C h a i n e " ) ;
s p r i n t f ( cpNumero , "%d" , i ) ;
s t r c a t ( cpLigne , cpNumero ) ;
s t r c a t ( cpLigne , "\n" ) ;
i N b E c r i t s = w r i t e ( i F i l e D e s c r i p t e u r , cpLigne , s t r l e n ( c p L i g n e ) ) ;
p r i n t f ( " L i g n e e c r i t e : %s de %d c a r a c t e r e s \n" , cpLigne , ( i n t ) i N b E c r i t s ) ;
}
close ( iFileDescripteur );
exit (0);
Unix/Linux Programmation Système C
Les appels systèmes sur les chiers
creat(), open(), read(), write(), close()

Exemple write

Execution WriteNew
$ >./ W ri te
F i c h i e r ouvert , l e f i l e d e s c r i p t o r a pour v a l e u r 3
Ligne e c r i t e : Chaine 1
de 9 c a r a c t e r e s
Ligne e c r i t e : Chaine 2
de 9 c a r a c t e r e s
Ligne e c r i t e : Chaine 3 $>c a t W r i t e D e s t i n a t i o n . t x t
de 9 c a r a c t e r e s Chaine 1
Ligne e c r i t e : Chaine 4 Chaine 2
de 9 c a r a c t e r e s Chaine 3
Ligne e c r i t e : Chaine 5 Chaine 4
de 9 c a r a c t e r e s Chaine 5
Ligne e c r i t e : Chaine 6 Chaine 6
de 9 c a r a c t e r e s Chaine 7
Ligne e c r i t e : Chaine 7 Chaine 8
de 9 c a r a c t e r e s Chaine 9
Ligne e c r i t e : Chaine 8 C h a i n e 10
de 9 c a r a c t e r e s C h a i n e 11
Ligne e c r i t e : Chaine 9
de 9 c a r a c t e r e s
L i g n e e c r i t e : C h a i n e 10
de 10 c a r a c t e r e s
L i g n e e c r i t e : C h a i n e 11
de 10 c a r a c t e r e s
Unix/Linux Programmation Système C
Programmation
Gérer les erreurs

Gestion des erreurs

ˆ Obligatoire au retour de tous les appels système

ˆ Valeur non négative : succès


ˆ Valeur négative : erreur

ˆ Achage en clair : perror (prototype dans stdio.h)

ˆ void perror(const char*msg); // le message msg est aché avant le


texte d'erreur système
ˆ perror("ouverture") achera ouverture : No such le or directory

Attention

CONSULTER LE MANUEL EN LIGNE !!


Unix/Linux Programmation Système C
Programmation
Gérer les erreurs

Comment programmer

ˆ Programmation C classique

ˆ Programmation modulaire
ˆ Indentation / Commentaires / norme de nommage /etc.
ˆ Utilisation de gcc avec le options usuelles :

gcc −Wall −o chier_exec chierA.c chierB.c


(exemple de makele fourni)
Unix/Linux Programmation Système C
Programmation
Gérer les erreurs

Règles d'or
ˆ Indentation

ˆ Norme de nommage

ˆ Commentaires

ˆ Déclaration de variables au début du main, évite leis doublons et les erreurs

ˆ Prendre le reexe de délimiter vos corps de conditions ou d'itérations dans


un bloc d'accolade => évite les erreurs de condition non prise en compte

ˆ Tester toutes les valeurs retour

ˆ Controler toutes vos entrées

ˆ GDB VS printf

ˆ Faire un Makele avec options !!! Attention à la syntaxe

ˆ Utilisez le man , niveau 2 pour le descriptif et les signatures de fonctions

ˆ Pour un printf, ne pas oublier le \n en n, pour vider le buer

ˆ Makele

ˆ Pas de Warning en compilation -Wall et tous les warnings corrigés

ˆ Gestion version
Unix/Linux Programmation Système C
Programmation
Gérer les erreurs

Comment programmer (suite)

ˆ Fichiers d'inclusion

ˆ <unistd.h> types, constantes et appels systèmes Unix standards


ˆ <sys/types.h> constantes et types de données standards
ˆ <sys/stat.h> caractéristiques des chiers
ˆ <fcntl.h> opérations de contrôle sur les dichiers
ˆ <errno.h> codes d'erreur
ˆ <stdio.h>,<stdlib.h> <string.h> etc.
Unix/Linux Programmation Système C
Programmation
Portabilité

Ecrire des programmes portables

ˆ Nombreuses variantes Unix : Linux, FreeBSD,NetBSD, OpenBSD, Solaris


etc.

ˆ Standards et normes

ˆ POSIX (Portable Operating System Interface) ; dénitino de services


système
ˆ POSIX.1 : Standard IEEE et ISO (ISO/IEC 9945−1:1990)
ˆ Nombreuses variantes : POSIX.1[a−g], POSIX.2, FIPS 151, Open
Group etc.
Unix/Linux Programmation Système C
Programmation
Portabilité

Ecrire des programmes portables (suite)

ˆ Taille et types des données variables :utilisez les types standards


(sys/types.h)

ˆ exemple : size_t : taille en octets

ˆ Voire le manuel des fonctions (man) pour connaître

ˆ Les chiers d'inclusion standards à ajouter à vos chiers C


ˆ Les types standards utilisés (et à utiliser)
ˆ Les erreurs retournées par les appels système (à gérer)

You might also like