Guillaume Chanel
Remerciements à Jean-Luc Falcone
Merci à Jacques Menu
0 | Entrée standard |
---|---|
1 | Sortie standard |
2 | Erreur standard |
A l'ouverture d'un canal d'entrée/sortie:
Un élément de la tables des canaux ouverts contient (entre autre):
O_RDONLY, O_WRONLY, O_RDWR
)O_APPEND, O_NONBLOCK, O_ASYNC
)Les mêmes fonctions sont utilisés quelque soit le type de fichier (fichier de données, socket, pipe, périphériques, etc.):
Opération | Appel système |
---|---|
Ouverture | open |
Lecture de données | read |
Ecriture de données | write |
Contrôle du fonctionement | fcntl dup dup2 |
Fermeture | close |
open
)L'appel système suivant ouvre un canal:
int open(const char *pathname, int flags, mode_t mode);
pathname
est le nom du fichierflags
est un champ de bit indiquant le mode d'accès au fichiermode
indique les permissions si le fichier est créé par open
(cf. O_CREAT
).Les flags suivants peuvent être passés à la fonction open
:
O_RDONLY | Lecture seule |
O_WRONLY | Ecriture seule |
O_RDWR | Lecture et écriture |
O_APPEND | Ecrit à la fin |
O_CREAT | Crée le fichier s'il n'existe pas |
O_TRUNC | Efface le fichier s'il existe |
O_EXCL | Erreur si O_CREATE est spécifié et que le fichier existe |
Lorsque que le flag O_CREAT
est passé, il faut spécifier les permissions:
int fd = open("/tmp/foo.txt", O_RDWR | O_CREAT | O_OEXCL, 0640);
Si O_CREAT
est absent, le mode est ignoré.
Si un fichier est ouvert plusieurs fois par un ou plusieurs processus:
close
)fd
:int close(int fd);
unlink
, le fichier est effectivement effacé.exit
ou abort
, le noyau ferme tous les descripteurs (équivalent à close
).execv()
si le bit close-on-exec est égal à 1.fcntl
)On peut manipuler finement un descripteur avec:
int fcntl(int fd, int cmd, ... /* arg */ );
fd
est un descripteur et cmd
la commande.fcntl
(voir
man).
dup
et dup2
permettent de dupliquer des descripteurs de fichiers qui pointerons sur la même entrée de la table des canaux.
#include <unistd.h>
int dup(int fildes);
int dup2(int fildes, int fildes2);
fildes
: un descripteur à dupliquerdup2
seulement: ferme le descripteur existant fildes2
et y stocke un nouveau descripteur qui est un duplicata de fildes
dup
est équivalent à:
fcntl(fildes, F_DUPFD, 0);
read
)Pour lire les données d'un descripteur, on peut utiliser:
ssize_t read(int fd, void *buf, size_t count);
count
bytes depuis le descripteur fd
buf
errno
)write
)Pour écrire des données sur un descripteur, on peut utiliser:
ssize_t write(int fd, void *buf, size_t count);
count
bytes sur le descripteur fd
buf
contient les bytes à écrireerrno
)read
et write
Sur des fichiers standards read et write retournent moins que demandé quand:
read
arrive en fin de fichier;write
n'a plus d'espace sur le système de fichier.Mais il faut penser que:
Include example there (see script)
lseek
)off_t lseek(int fd, off_t offset, int whence);
fd
whence
(slide suivant)errno
)La nouvelle position, dépend de whence
et d'offset
whence | Nouvelle position |
---|---|
SEEK_SET | offset |
SEEK_CUR | position courant + offset |
SEEK_END | fin du fichier + offset |
Include example there (see script)
mkstemp
)La fonction mkstemp
permet de créer et d'ouvrir un fichier temporaire:
int mkstemp(char *template);
*template
), terminé par 6 "X".*template
est modifiée avec le vrai nom du fichier.0600
mkstemp
char name[15] = "";
int fd = -1;
strncpy( name, "/tmp/ed.XXXXXX", sizeof name );
fd = mkstemp( name );
if( fd < 0 ) {
//Gerer l'erreur
}
else {
printf( "The temporaray filename is %s\n", name );
}
unlink
n'efface pas un fichier, seulement son nomunlink
sur un fichier temporaire créé.mkstemp/unlink/link
(pseudocode)
int fd = mkstemp( name );
unlink( fd ); // Enleve le nom
DOWNLOAD_INTO( fd );
PLAY_WITH( fd );
close( downloadFD ); // Efface les donnees
mkdtemp
)On peut aussi créer des répertoires temporaires:
char *mkdtemp(char *template);
mkstemp
.0700
.NULL
.Rappel:
$ ls -lh /dev | more
ls
et more
On peut créer un canal de communication anonyme en utilisant:
int pipe(int fildes[2]);
filedes[0]
est un descripteur de fichier représentant la sortie du tube/pipe (i.e. on peu lire sur ce descripteur);filedes[1]
est un descripteur de fichier représentant l'entrée du tube/pipe (i.e. on peu écrire sur ce descripteur);errno
);Les tubes et FIFO:
mkfifo(1)
On peut créer un FIFO avec la commande:
mkfifo [OPTION]... NOM...
NOM
est le nom du FIFO à créer-m MODE
.mkfifo(2)
On peut créer un FIFO avec l'appel système:
int mkfifo(const char *pathname, mode_t mode);
pathname
est le nom du fichier à créermode
représente les permissions (modifiées mode & ~umask
)open/read
) mais il faut veiller à respecter la directionalité du fifoInclude example there (see script)
Include example there (see script)