Exercice

1.
La première commande recopie son entrée standard sur sa sortie standard, alors que la deuxième copie le fichier donné en argument sur sa sortie standard. Il suffit de noter que seule la deuxième commande a conscience de copier le fichier toto.
2.
Dans les deux cas cela signifie que les références toto et titi nomment le même objet du système de fichiers (même inoeud).
3.
Bien que dans les commandes 6 et 7 les références f1 et f2 jouent un rôle identique à celui des fichiers toto et titi dans les deux premières commandes et que le contenu des fichiers f1 et f2 soient les mêmes, il s'agit à l'évidence de deux fichiers distincts.
4.

Exercice

L'autorisation de supprimer une référence n'est pas liée à l'objet nommé par celle-ci. C'est le répertoire qui contient la référence qui contrôle le droit de suppression : si le répertoire est fermé en écriture (création ou suppression d'objets dans le répertoire lui-même) il est impossible de supprimer la référence en question.

Exercice

1.
Le programme p1 lit sizeof(int) octets sur son entrée standard, puis écrit sizeof(int) octets sur sa sortie standard. Si un entier est de taille 4 (valeur très répandue), alors ce programme lit les caractères 12<espace>3 puis les affichent sur la sorite standard. Il reste donc les caractères 4<return> dans le tampon d'entrée qui est alors lu par le shell après exécution de p1 et indique donc 4: command not found
2.
Le programme p2 lit une ligne (terminée par <return>) sur son entrée standard, convertit le plus grand suffixe composé de caractères formant un entier en sa représentation machine, puis affiche les sizeof(int) caractères situés à l'adresse de cette représentation machine. Donc on a l'ensemble de l'entrée dans le tampon de lecture, l'appel à scanf() convertit la chaîne 12 en la représentation machine de 12 (par exemple <nul><nul><nul><np><np> est le douziême caractère ASCII) puis ces caractères sont envoyés en sortie.
3.
Si l'on remplace les appels à write() par le printf() indiqué cela ne change rien aux lectures réalisées, seules les sorties seront modifiées. Pour p1 la sortie sera l'entier dont la représentation machine est la suite des caractères 12<espace>3 (soit par exemple ascii('1')*2563+ascii('2')*2562+ascii(' ')*256+ascii('3') égal à 825368627). Pour p2, l'affichage sera la suite de caractères 12.

Exercice

On peut remarquer que les deux programmes effectuent tout deux une recopie du fichier f dans g en copiant le contenu caractère par caractère. Seules les fonctions utilisées sont différentes. Pour cp1 on utilise des appels systèmes (1752064 appels à read() et à write()), or ces appels systèmes sont coûteux : basculements des modes noyau à utilisateur, validation des arguments, recopie des arguments d'un espace dans l'autre, etc. Pour cp2 on utilise des fonctions de la bibliothèque C (1752064 appels à fread() et à fwrite()), mais il faut garder en tête que la bibliothèque d'entrées/sorties du C utilise un tampon de lecture/écriture, lequel est vidé/remplit par des appels à read() et write() sur le tampon dans son entier. On économise donc de très nombreux appels systèmes (environ 1 appel à read() pour taille_du_tampon appels à fread()). Les appels à fread() qui n'utilisent pas read() sont très peu coûteux puisqu'il s'agit simplement de recopier un caractère (idem pour write() et fwrite()).
Les mesures indiquent bien que le temps passé dans le système par cp1 est environ 1000 fois plus important que celui de cp2. En ce qui concerne le temps utilisateur la différence est nettement moins flagrante : cp1 n'y passe environ que 8 fois plus de temps que cp2

Exercice

Le problème est que pour Unix tout caractère (paquet de huit bits) peut être lu. Or la fonction getchar() doit renvoyer une erreur indiquant la fin de fichier. Donc la fonction getchar() peut renvoyer au moins 257 valeurs (les 256 mots possibles de huit bits, plus l'erreur de lecture en fin de fichier). Le type char (huit bits) ne peut contenir 257 valeurs, il faut pour cela un mot d'au moins neuf bits : on a choisi le type int (dont la norme ANSI garantit qu'il est strictement plus grand que char).

Exercice

1.
À l'évidence le programme est destiné à construire un objet du système de fichiers contenant un nouvel entier à chaque consultation. Si l'objet frandom est un fichier régulier (ou normal) ce programme boucle sans arrêt en ouvrant le fichier, puis écrivant un entier tiré aléatoirement, puis refermant le fichier. Le problème est que ce programme consomme alors inutilement des ressources (processeur pour boucler avidemment à l'infini, tirage d'entiers même si personne n'en veut, appels systèmes à répétition).
2.
Si l'objet frandom est un tube nommé, alors nous aurons le comportement désiré car : une ouverture en écriture n'est effective que lorsqu'un nouveau lecteur se manifeste ou qu'un lecteur est déjà actif, autrement le processus est endormi (il ne consomme donc rien en temps de calcul).

Exercice