Les fonctions suivantes sont-elles des appels système ou des fonctions de la bibliothèque C standard ?
printf()
fopen()
fclose()
fread()
open()
close()
lseek()
rewind()
write()
exit()
_exit()
Aidez-vous des prototypes de ces fonctions pour répondre à cette question.
Le but de cet exercice est de mettre en évidence l’effet des buffers (tampons) sur les entrées-sorties.
Le schéma du programme buffer.c
que vous allez écrire est le suivant:
"Hello"
sleep(3)
" World!"
Afin de n’avoir qu’un seul programme source, vous allez utiliser le préprocesseur C pour conditionner le fonctionnement de votre programme.
CHAINE1
CHAINE2
.fprintf
ou write
fprintf(3)
si UTILISER_FPRINTF1
est positionnée, et avec write(2)
sinonUTILISER_FPRINTF2
UTILISER_SORTIE_ERREUR1
est positionnée, sur la sortie standard autrementUTILISER_SORTIE_ERREUR2
_exit(2)
si UTILISER__EXIT
est positionnée, et par exit(3)
sinon.Afin de voir les différents modes de fonctionnement des tampons, le programme est exécuté de deux manières différentes :
./buffer
afin que les sorties soient sur le terminal./buffer 2>&1 | cat -u
afin que les sorties du programme passent par un tube avant d'être affichéesMettez en évidence les trois modes de fonctionnement des buffers de la bibliothèque C standard, ainsi que le fait que les appels système n’utilisent pas de buffers visibles au niveau utilisateur.
Testez notamment les modes de compilations suivants:
rm -f buffer && make buffer CFLAGS+="-DUTILISER_FPRINTF1"
rm -f buffer && make buffer CFLAGS+="-DUTILISER_FPRINTF2 -DUTILISER_SORTIE_ERREUR2"
rm -f buffer && make buffer CFLAGS+="-DUTILISER_FPRINTF1 -DUTILISER_FPRINTF2 -DUTILISER_SORTIE_ERREUR2"
\n
dans la première chaîne, qu’est-ce que ça change ?Écrivez un programme qui:
printf
pour qu’il soit lisible,fork(2)
,et dont l’enfant affiche son propre pid (avec printf
) et celui de son parent.
Attention, le processus parent ne doit plus rien afficher après l’appel à fork(2)
.
Proposez trois solutions à ce problème, et implémentez-en une qui vous paraît la plus pratique et/ou la plus élégante.
Le but de cet exercice est d'écrire un programme lance
qui s’exécutera comme suit :
./lance sortie commande arg1 arg2 ...
Ce programme devra avoir le même comportement que l’exécution dans le shell de la commande suivante:
./commande arg1 arg2 ... > sortie
write
)execvp
.dup2
pour cette opération.wait(2)
).lance
.Pour générer le segfault, on pourra utiliser la fonction suivante après l’avoir comprise:
void gen_segfault()
{
*((int*)0) = 42;
}