Differences

This shows you the differences between two versions of the page.

Link to this comparison view

sde:laboratoare:03 [2019/03/11 20:23]
alexandru.radovici
— (current)
Line 1: Line 1:
-====== TP 3 - Fonctions d'​entrée et sortie ====== 
-===== Documents d'aide ===== 
- 
-  * [[https://​www.slideshare.net/​alexandruradovici/​sde-tp-3-fonctions-dentre-et-sortie | Diapositifs]] 
-  * [[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab02-refcard.pdf | lab02-refcard.pdf]] 
- 
-==== Agréable à lire ==== 
-    * TLPI - Chapter 4, ''​File I/O: The Universal I/O model''​ 
- 
-===== Fichiers. Systèmes de fichiers ===== 
- 
-** Le fichier ** est l’une des abstractions fondamentales dans le domaine des systèmes d’exploitation;​ L'​autre abstraction est le processus. Si le processus résume l'​exécution d'une tâche spécifique sur le processeur, le fichier résume les informations persistantes d'un système d'​exploitation. Un fichier est utilisé pour stocker les informations nécessaires au fonctionnement du système d'​exploitation et aux interactions de l'​utilisateur. 
- 
-Un ** système de fichiers ** est un moyen d'​organiser les fichiers et de les présenter à l'​utilisateur. Du point de vue de l'​utilisateur,​ un système de fichiers a une structure hiérarchique de fichiers et de répertoires,​ commençant par un répertoire racine. L'​emplacement d'une entrée (fichier ou répertoire) est défini par un chemin qui répertorie toutes les entrées jusque-là. Ainsi, pour le chemin ''/​usr/​local/​file.txt '',​ le répertoire racine ''/''​ contient un sous-répertoire ''​usr''​ qui comprend le sous-répertoire ''​local''​ contenant un fichier file.txt. 
- 
-Chaque fichier est donc associé à un nom identifiant,​ à un ensemble de droits d'​accès et à des zones contenant des informations utiles. 
- 
-Les systèmes de fichiers pris en charge par les systèmes d'​exploitation Unix et Windows sont hiérarchiques. Les systèmes Linux / Unix sont sensibles à la casse ("​Données"​ est différent de "​données"​) et les systèmes Windows ne font pas la distinction entre les casse. 
- 
-La hiérarchie du système de fichiers Unix comporte un seul répertoire appelé "​racine"​ et ""​ / ""​ dans lequel n’importe quel fichier est localisé (à ne pas confondre avec le répertoire "/ racine",​ qui est: patrie de privilegiat,​ root). La liste des chemins de fichiers Unix est une chaîne de noms de répertoires séparés par ''​ '/'​ '',​ suivis du nom du fichier. Il existe également des chemins relatifs au répertoire en cours ''​ '​.'​ ''​ Ou au répertoire parent '''​..'''​. 
- 
-{{ :​sde:​laboratoare:​fs-tree.png?​nolink&​550 |}} 
-Sous Unix, il n'y a pas de différence entre les fichiers du disque local, du CD ou du lecteur réseau. Tous ces fichiers feront partie de la hiérarchie unique du répertoire racine. Cela se fait par '​mount':​ les systèmes de fichiers seront montés dans l'un des répertoires du système de fichiers racine. 
- 
-Il existe plusieurs hiérarchies dans Windows, une pour chaque partition et une pour chaque emplacement réseau. Contrairement à Unix, le délimiteur entre les noms de répertoire dans un chemin et pour les chemins absolus, la hiérarchie doit être spécifiée sous la forme ''​ C: \ '',​ ''​ E: \ ''​ ou ''<​nowiki>​\\FILESERVER\myFile</​nowiki>'' ​ (pour le réseau). Comme Unix, Windows utilise ''​.''​ Pour le répertoire actuel et ''​ '​..'​ ''​ pour le répertoire parent. 
-===== Opérations sur les fichiers ===== 
- 
-Sous Unix, un ** descripteur de fichier ** est un ensemble qui indexe une table avec des pointeurs sur des structures décrivant les fichiers ouverts par un processus. Si un programme est exécuté dans un shell Unix, le processus parent (shell) ouvre pour le processus enfant (le programme) 3 fichiers standard avec des descripteurs de fichier de valeur spéciaux: 
- 
-{{ so:​laboratoare:​standard_filedes.png?​300|Descripteurs de fichiers standard}} 
-* ** standard input** (0) - lecture à partir d'une entrée standard (clavier) 
-    * ** standard output** (1) - affichage sur la sortie standard (console) 
-    * ** standard error** (2) - affichage sur la sortie d'​erreur standard (console) 
- 
-Un fichier associe le pointeur de fichier qui indique la position actuelle dans le fichier. Le curseur de fichier est un entier représentant le déplacement (décalage) du début du fichier. 
- 
-Opérations spécifiques pour travailler avec des fichiers: 
-    * ** ouverture / création d'un fichier ** - signifie associer un descripteur de fichier identifié par son nom (''​fopen''​ (ANSI C), ''​open'',​ ''​creat''​ (POSIX), ''​CreateFile''​ (Win32 API))). ([[#​Création,​ ouverture et fermeture de fichiers | Linux]]) 
-    * ** fermer un fichier ** - signifie libérer les structures de fichier associées au processus et au descripteur de ce fichier - uniquement s’il n’ya pas d’entrée dans la table des descripteurs fichier qui pointe vers cette structure (''​fclose''​ (ANSI C), ''​close''​ (POSIX), ''​CloseHandle''​ (Win32 API)). ([[#​Création,​ ouverture et fermeture de fichiers | Linux]]) 
-    * ** lecture dans un fichier ** - signifie copier un bloc de données dans une mémoire tampon; après la lecture est mis à jour le curseur de fichier (''​fread''​ (ANSI C), ''​read''​ (POSIX), ''​ReadFile''​ (Win32 API)). ([[#Écrire et lire | Linux]]) 
-    * ** écriture dans un fichier ** - signifie copier un bloc de données d'un tampon dans un fichier; Ecrire signifie aussi mettre à jour le curseur de fichier (''​fwrite''​ (ISO C), ''​write''​ (POSIX), ''​WriteFile''​ (Win32 API)). ([[#Écrire et lire | Linux]]) 
-    * ** positionnement dans un fichier ** - signifie changer la valeur du curseur de fichier; les lectures ou écritures suivantes commenceront à l'​emplacement indiqué par ce curseur de fichier (''​fseek''​ (ANSI C), ''​lseek''​ (POSIX), ''​SetFilePointer''​ (Win32 API)). ([[#​Positionnement dans un fichier (lseek) | Linux]]) 
-    * ** changer les attributs d'un fichier ** - signifie définir les paramètres du fichier (''​ fcntl ''​ (POSIX), SetFileAttributes (Win32 API)). ([[#​Opérations spéciales | Linux]]) 
- 
-===== Opérations sur les fichiers sous Linux ===== 
-==== Création, ouverture et fermeture de fichiers ==== 
- 
-=== ouvert === 
- 
-Pour ouvrir / créer un fichier, utilisez [[http://​linux.die.net/​man/​2/​open|open]]. 
- 
-<code c> 
-int open(const char *pathname, int flag); ​              /* deschidere */ 
-int open(const char *pathname, int flags, mode_t mode); ​ /* creare */ 
-</​code>​ 
-Les valeurs possibles pour //flags// sont: 
-  * O_RDONLY ouvert en lecture seulement 
-  * O_WRONLY ouvert à l'​écriture uniquement 
-  * O_RDWR ouvert en lecture et en écriture 
-  * O_NONBLOCK ne bloque pas l'​ouverture ni la disponibilité des données 
-  * O_APPEND ajouter à chaque écriture 
-  * O_CREAT crée un fichier s'il n'​existe pas 
-  * Taille tronquée O_TRUNC à 0 
-  * Erreur O_EXCL et * O_CREAT si le fichier existe 
-  * O_SHLOCK obtenir atomiquement un verrou partagé 
-  * O_EXLOCK obtient atomiquement un verrou exclusif 
-  * O_NOFOLLOW ne suit pas les liens symboliques 
-  * O_SYMLINK autorise l'​ouverture de liens symboliques 
-  * Le descripteur O_EVTONLY est demandé pour les notifications d'​événement uniquement 
-  * O_CLOEXEC marque comme proche-sur-exec 
- 
-Les valeurs des indicateurs sont représentées par des bits, car elles peuvent être combinées par l'​opérateur | (ou sur des bits). 
-<code c> 
-// open a file in write only and delete all its contents (truncate to 0) 
-open(pathname,​ O_WRONLY | O_TRUNC, mode); 
-</​code>​ 
-La valeur de //mode// est représentée par les droits du nouveau fichier créé (en bits). Généralement,​ un nombre de base de 8 est utilisé. 
-Il a trois chiffres, chacun avec trois bits. 
-^  r w x  ^  r - x  ^  r - -  ^ 
-|  1 1 1  |  1 0 1  |  1 0 0  | 
-|    7    |    5    |    4    | 
- 
-  * r - read 
-  * w - write 
-  * x - execute 
-Chaque chiffre se réfère à: 
-   * premier chiffre - permissions de l'​utilisateur qui détient le fichier 
-   * deuxième chiffre - permissions du groupe contenant le fichier 
-   * troisième chiffre - les autorisations des utilisateurs qui ne possèdent pas le fichier et ne font pas partie du groupe qui détient le fichier 
-=== creat === 
-Vous pouvez également utiliser [[http://​linux.die.net/​man/​2/​creat|creat]] pour créer des fichiers: 
-<code c> 
-int creat(const char *pathname, mode_t mode); 
-</​code>​ 
-La fonction est équivalente à l'​appel '​open'​ où l'​indicateur O_CREAT est défini et le fichier n'​existe pas déjà: 
-<code c> 
-open(pathname,​ O_WRONLY | O_CREAT | O_TRUNC, mode); 
-</​code>​ 
- 
-=== close === 
-La fermeture des fichiers se fait avec [[http://​linux.die.net/​man/​2/​close|close]]:​ 
-<code c> 
-int close(int fd) 
-</​code>​ 
-Une erreur de programmation fréquente n’est pas la vérification du code d’erreur renvoyé à [[http://​linux.die.net/​man/​2/​close|close]],​ car il pourrait s’agir d’une erreur d’écriture (''​ EIO ''​ ) ne sera retourné à l'​utilisateur qu'à ''​close''​. 
-=== unlink === 
-La suppression effective d'un fichier d'un disque se fait avec [[http://​linux.die.net/​man/​2/​unlink|unlink]]:​ 
-<code c> 
-int unlink(const char *pathname); 
-</​code>​ 
-=== Exemple === 
- 
-Si, par exemple, nous voulons ouvrir le fichier ''​ in.txt ''​ pour la lecture et l'​écriture,​ éventuellement le créer, et le fichier ''​ out.txt ''​ pour l'​écriture,​ avec des troncatures,​ nous pouvons utiliser la séquence de code suivante: 
-<code c io-01.c> 
-#include <​sys/​types.h>​ /​* open */ 
-#include <​sys/​stat.h>​ /​* open */ 
-#include <​fcntl.h>​ /​* O_RDWR, O_CREAT, O_TRUNC, O_WRONLY */ 
-#include <​unistd.h>​ /​* close */ 
- 
-#include "​utils.h"​ 
- 
-int main(void) 
-{ 
- int rc; 
- int fd1, fd2; 
- 
- fd1 = open("​in.txt",​ O_RDWR | O_CREAT, 0644); 
- DIE(fd1 < 0, "open in.txt"​);​ 
- 
- /* will fail if out.txt does not exist */ 
- fd2 = open("​out.txt",​ O_WRONLY | O_TRUNC); 
- DIE(fd2 < 0, "open out.txt"​);​ 
- 
- rc = close(fd1); 
-        DIE(rc < 0, "close fd1"); 
-        ​ 
-        rc = close(fd2); 
-        DIE(rc < 0, "close fd2"); 
- 
- return 0; 
-} 
-</​code>​ 
-** Attention ** Une erreur courante est l'​omission des droits de création de fichier (0644 dans l'​exemple ci-dessus) lorsque l'​indicateur O_CREAT ouvert est appelé. 
- 
-==== Écrire et lire ==== 
-=== read === 
-La fonction [[http://​linux.die.net/​man/​2/​read|read]] est utilisée pour lire le nombre maximal de décomptes du fichier: 
-<code c> 
-ssize_t read(int fd, void *buf, size_t count); 
-</​code>​ 
-La fonction [[http://​linux.die.net/​man/​2/​read|read]] renvoie le nombre d'​octets réellement lus, tout au plus "​count"​. La valeur minimale est "​1"​ octet, et quand il atteint la fin du fichier, il renvoie "​0"​. 
-=== write === 
-La fonction [[http://​linux.die.net/​man/​2/​write|write]] est utilisée pour écrire le nombre maximal d'​octets ''​count'':​ 
-<code c> 
-ssize_t write(int fd, const void *buf, size_t count); 
-</​code>​ 
-La valeur de retour est le nombre d'​octets réellement écrits, au plus "​nombre"​. Par défaut, il n'est pas garanti que le retour à [[http://​linux.die.net/​man/​2/​write|write]] soit terminé. Pour forcer la mise à jour, vous pouvez utiliser [[http://​linux.die.net/​man/​2/​fsync|fsync]] ou le fichier peut être ouvert à l'aide de l'​indicateur ''​ O_FSYNC '',​ auquel cas il est garanti qu'​après chaque écriture le fichier a été mis à jour. 
- 
-** Note **: 
-Pour [[http://​linux.die.net/​man/​2/​read|read]],​ [[http://​linux.die.net/​man/​2/​write|write]],​ il y a [[http://​linux.die.net/​man/​2/​pread|pread]],​ [[http://​linux.die.net/​man/​2/​pwrite|pwrite]],​ qui vous permettent de spécifier un décalage de fichier à partir duquel effectuer l'​opération de lecture / écriture. (Il existe également des versions ''​pread64''​ et ''​ pwrite64 ''​ qui utilisent des décalages 64 bits - pour spécifier des tailles de décalage supérieures à 4 Go). 
- 
-==== Positionnement dans un fichier (lseek) ==== 
- 
-=== lseek === 
- 
-La fonction [[http://​linux.die.net/​man/​2/​lseek|lseek]] permet au curseur de déplacer un fichier vers une position absolue ou relative. 
-<code c> 
- off_t lseek(int fd, off_t offset, int whence) 
-</​code>​ 
-Le paramètre "​wherece"​ représente la position relative à partir de laquelle le déplacement est effectué: 
-   * ''​ SEEK_SET ''​ - contre la position de départ 
-   * ''​ SEEK_CUR ''​ - à la position actuelle 
-   * ''​ SEEK_END ''​ - vers la position finale 
- 
-** Remarque ** [[http://​linux.die.net/​man/​2/​lseek|lseek]] permet également le positionnement à la fin du fichier. L'​écriture dans de telles zones n'est pas perdue, ce qui est obtenu en étant un fichier // void //, une zone // ignorée // - n'est pas allouée au disque. 
- 
-Pour cette fonction, il existe une version de [[http://​linux.die.net/​man/​3/​lseek64|lseek64]] dans laquelle le décalage est de 64 bits. 
-==== Recadrer des fichiers ==== 
-En plus de tronquer à 0, ce qui peut être fait en appelant ''​ open ''​ avec l'​indicateur ''​ O_TRUNC '',​ vous pouvez spécifier de tronquer un fichier à une taille spécifiée par des appels système [[http://​linux.die.net/​man/​2/​ ftruncate | ftruncate]] et [[http://​linux.die.net/​man/​2/​ftruncate | truncate]]: 
-\\ 
-<code c> 
-int ftruncate(int fd, off_t length); ​         
-int truncate(const char *path, off_t length); 
-</​code>​ 
-Dans le cas de [[http://​linux.die.net/​man/​2/​ftruncate|ftrunched]],​ le paramètre ''​ fd ''​ est le fichier descripteur obtenu avec un appel ouvert fournissant l'​autorisation d'​écriture. Dans le cas de [[http://​linux.die.net/​man/​2/​ftruncate|truncate]],​ le fichier représenté par ''​ chemin ''​ doit avoir le droit d'​écriture. 
- 
-==== Exemple d'​utilisation des opérations d'E / S === 
-<code c io-2.c> 
-#include <​stdio.h>​ 
-#include <​string.h>​ 
-#include <​stdlib.h>​ 
- 
-#include <​sys/​types.h>​ /​* open */ 
-#include <​sys/​stat.h>​ /​* open */ 
-#include <​fcntl.h>​ /​* O_CREAT, O_RDONLY */ 
-#include <​unistd.h>​ /​* close, lseek, read, write */ 
- 
-#include "​utils.h"​ 
- 
-/* Print the last 100 bytes from a file */ 
- 
-int main (void) 
-{ 
- int fd, rc; 
- char *buf; 
- ssize_t bytes_read; 
- 
- /* alocate space for the read buffer */ 
- buf = malloc(101);​ 
- DIE(buf == NULL, "​malloc"​);​ 
- 
- /* open file */ 
- fd = open("​file.txt",​ O_RDONLY); 
- DIE(fd < 0, "​open"​);​ 
- 
- /* set file pointer at 100 characters 
- _before_ the end of the file */ 
- rc = lseek(fd, -100, SEEK_END); 
- DIE(rc < 0, "​lseek"​);​ 
- 
- /* read the last 100 characthers */ 
- bytes_read = read(fd, buf, 100); 
- DIE(bytes_read < 0, "​read"​);​ 
- 
- /* set '​\0'​ at end of buffer for printing purposes*/ 
- buf[bytes_read] = '​\0';​ 
- 
- printf("​the last %ld bytes: \n%s\n",​ bytes_read, buf); 
- 
- /* close file */ 
- rc = close(fd); 
- DIE(rc < 0, "​close"​);​ 
- 
- /* cleanup */ 
- free(buf); 
- 
- return 0; 
-} 
-</​code>​ 
-==== Redirections ==== 
- 
-Sous Linux, les redirections sont effectuées à l'aide des fonctions de duplication de descripteur de fichier [[http://​linux.die.net/​man/​2/​dup|dup]] et [[http://​linux.die.net/​man/​ 2 / dup2 | dup2]] (notez la différence entre 2 dans les liens précédents):​ 
-<code c> 
-int dup(int oldfd); 
-int dup2(int oldfd, int newfd); 
-</​code>​ 
-Par exemple, pour rediriger la sortie vers le fichier ''​ output.txt '',​ deux lignes de code sont requises: 
-<code c> 
-fd = open("​output.txt",​ O_RDWR|O_CREAT|O_TRUNC,​ 0600); 
-dup2(fd, STDOUT_FILENO);​ 
-</​code>​ 
-==== Opérations spéciales ==== 
- 
-La fonctionnalité [[http://​linux.die.net/​man/​2/​fcntl|fcntl]] vous permet d'​effectuer des opérations spéciales sur les descripteurs de fichiers. 
-<spoiler > 
- 
-<code C> 
-int fcntl(int fd, int cmd); 
-int fcntl(int fd, int cmd, long arg); 
-int fcntl(int fd, int cmd, struct flock *lock); 
-</​code>​ 
- 
-^ cmd ^ effet^ 
-| ''​ F_DUPFD ''​ | dupliquer un fichier descripteur 
-| ''​ F_GETFD ''​ lisez les drapeaux pour ''​ fd ''​ | 
-| ''​ F_SETFD ''​ | définit les drapeaux pour ''​ fd ''​ sur la valeur spécifiée par ''​ arg ''​ 
-| ''​ F_GETFL ''​ lire les indicateurs d'​état pour ''​ fd ''​ | 
-| ''​ F_SETFL ''​ définit les indicateurs d'​état pour ''​ fd ''​ sur la valeur spécifiée par ''​ arg ''​ 
-| ''​ F_GETLK ''​ | obtenir des informations sur un verrou de fichier 
-| ''​ F_SETLK ''​ | obtenir / libérer un verrou sur le fichier 
-| ''​ F_SETLKW ''​ | semblable à ''​ F_SETLK ''​ mais en attente de terminer l'​opération 
-| ''​ F_GETOWN ''​ obtention du ''​ PID ''​ du processus recevant le signal ''​ SIGIO ''​ 
-| ''​ F_SETOWN ''​ établissant le processus qui recevra le signal ''​ SIGIO ''​ 
-</​spoiler>​ 
-\\ 
- 
-===== Exercices ===== 
- 
-Pour résoudre le laboratoire,​ utilisez des clones [[https://​www.github.com/​upb-fils/​sde|repository]]. 
- 
-** Observations **: Pour vous aider à mettre en œuvre les exercices de laboratoire,​ il existe un fichier ''​ utils.h ''​ avec des fonctions utiles dans le répertoire ''​ utils ''​ de l'​archive. 
- 
-<note important>​ Utilisez ''​man''​ pour les informations sur l'​appel système (man 2 nom_fonction) </​note>​ 
-<note warning> ** Vérifier les retours de rappel système ** \\ 
-Vous pouvez utiliser le [[https://​ocw.cs.pub.ro/​courses/​so/​laboratoare/​resurse/​die | DIE]] (valeur renvoyée == erreur, "​message d'​erreur"​);​ 
-</​note>​ 
- 
-==== Exercice 1 - redirection (1p) ==== 
- 
-Allez dans le répertoire ''​ 1-redirect ''​ et regardez le contenu du fichier ''​ redirect.c ''​. 
- 
-Compilez le fichier (utilisez '​make'​). Exécutez le programme à l'aide de la commande '​./​redirect'​. 
- 
-Ouvrez un autre terminal et lancez la commande: 
-<code bash> watch -d lsof -p $(pidof redirect) </​code>​ 
-[[http://​linux.die.net/​man/​8/​lsof | lsof]] est un utilitaire qui affiche des informations sur les fichiers ouverts (fichiers ouverts dans le système, fichiers ouverts par un utilisateur particulier,​ etc.). Regardez dans le manuel (''​ man 8 lsof ''​) pour identifier la signification de la colonne FD et de la colonne TYPE. 
- 
-Utilisez la commande Entrée pour continuer le programme. En parallèle, observez l’évolution de la table des descripteurs. 
- 
-Dans le code, notez les paramètres de redirection avec [[http://​linux.die.net/​man/​2/​dup2|dup2]] (après 2 (fd2, STDERR_FILENO)). Remarquez ce qui se passe si les paramètres sont dans l'​ordre inverse. 
-   * Section de révision de [[#redirect | redirections]] 
- 
-==== Exercice 2 - read-write (3p) ==== 
- 
-Allez dans le répertoire ''​2-read-write''​ et regardez le contenu du fichier ''​read-write.c''​. 
- 
-=== 2a. Écrivez votre nom (1p) === 
-Mettez votre nom dans la variable //name//. Écrivez la variable à l'​écran en utilisant uniquement la fonction //write//. Suivez les lignes avec TODO 1. 
- 
-=== 2b. Lisez votre nom (1p) === 
-Lisez votre nom depuis le clavier dans la variable //name// en utilisant uniquement la fonction //read//. 
- 
-La fonction //read// lit les tampons, elle n’ajoutera pas le caractère \0 à la fin de la chaîne. Assurez-vous que le texte de la chaîne comporte le caractère \0 à la fin. 
- 
-Ecrivez le nouveau nom lu sur l'​écran en utilisant uniquement les fonctions //write//. 
- 
-Suivez les lignes avec TODO 2. 
- 
-=== 2c. Redirection de la sortie standard (1p) === 
- 
-Ecrivez votre nom dans le fichier //​output.txt//​ en utilisant la fonction //printf//. 
- 
-<​note>​ 
-Vous devrez rediriger la sortie standard. 
- 
-Lors de la création d'un nouveau fichier, vous devez définir le mode du fichier (le troisième paramètre de la fonction // open //). Le mode le plus commun est 0644. 
-</​note>​ 
- 
-Suivez les lignes avec TODO 3. 
- 
-==== Exercice 3 - lseek (1p) ==== 
- 
-Allez dans le répertoire ''​ 3-lseek ''​ et regardez le code source dans ''​ lseek.c ''​. 
-Quelle valeur le second appel de "​lseek"​ retournera-t-il?​ Décommentez la ligne d'​affichage,​ compilez et exécutez pour vérification. 
- 
-Source ne ferme que le fichier descripteur ''​ fd1 ''​. Avez-vous besoin de fermer et de classer le descripteur ''​ fd2 ''?​ Pourquoi 
- 
-==== Exercice 4 - mcat (4p) ==== 
- 
-Allez dans le répertoire ''​ 4-mcat ''​. 
- 
-=== 4a. Similarité de chat (1p) === 
-Remplissez le fichier pour que le programme ''​ mcat ''​ résultant ait une fonctionnalité similaire à celle de '​cat'​ (suivez les commentaires avec ''​ TODO 1 ''​) 
- 
-Le programme '​mcat'​ recevra comme argument de ligne de commande le nom d'un fichier dont il affichera le contenu à la sortie standard. 
-Vous ne pouvez pas lire le fichier entier en mémoire. Vous ne pouvez lire que des morceaux de taille maximale BUFSIZE. 
- 
-** Vérifiez le code d'​erreur ** renvoyé par les appels système. Vous pouvez utiliser le [[http://​elf.cs.pub.ro/​so/​wiki/​laboratoare/​resurse/​die | DIE]]. 
-Passez en revue les sections [[#​Création,​ ouverture et fermeture de fichiers | Création, ouverture et fermeture de fichiers]] et [[#Écrire et lire | Écriture et lecture de fichiers]]. 
- 
-Testez avec une commande comme: <code bash>​./​mcat Makefile </​code>​ 
- 
-=== 4b. Similarité cp (1p) === 
-Étendez la fonctionnalité de sorte que la sortie soit redirigée vers un fichier reçu en tant que deuxième argument - une fonctionnalité similaire à l'​utilitaire ''​ cp ''​. (suivez les commentaires avec ''​ TODO 2 ''​) 
- 
-Consultez la section [[#​Redirections | redirections]]. 
- 
-Tester la fonctionnalité:​ <code bash>​./​mcat Makefile out ; ./mcat out </​code>​ 
- 
-=== 4c. / dev / méchant (2p) === 
-Initialisez le fichier ''/​dev/​nasty'':​ <code bash> ./​set_nasty.sh </​code>​ 
- 
-Essayez de copier les fonctionnalités sur ''/​dev/​nasty '': ​ 
-<code bash> 
-./mcat /dev/nasty 
-./mcat /dev/nasty out ; ./mcat out  
-</​code>​ 
- 
-Si des différences se produisent, veillez à ce que les fonctions de lecture et d'​écriture (affichent éventuellement ces valeurs) et résolvez le problème. 
- 
-<​note>​ 
-La sortie standard étant redirigée vers un fichier, vous ne pouvez pas utiliser //printf//. Pour écrire à l'​écran,​ vous pouvez utiliser //fprintf// (stderr, ...) pour écrire à l'​erreur standard. 
-</​note>​ 
- 
-Testez ** l'​écriture ** avec: <code bash>​./​mcat Makefile /dev/nasty ; cat /​dev/​nasty</​code>​ 
-<note tip> 
-Si la dernière commande ne produit pas le résultat attendu, vous n'avez probablement pas correctement géré les cas où ''​read''/''​write''​ renvoie une valeur inférieure au troisième paramètre. 
-</​note>​ 
- 
-==== Exercice 5 - Dépannage (1p) ==== 
- 
-Allez dans le répertoire ''​ 5-trouble ''​. Compilez et exécutez le programme ''​ trouble ''​. 
- 
-Le programme devrait s'​afficher dans ''​ tmp1.txt ''​ le message ''​ msg ''​. Affichez le fichier ''​ tmp1.txt ''​. 
- 
-Que remarquez-vous?​ Identifiez et corrigez le problème. Passez en revue la section: [[#​Création,​ ouverture et fermeture de fichiers 
- | Création, ouverture et fermeture de fichiers]]. 
- 
-<​note>​ 
-Astuce: utilisez ls -l 
-</​note>​ 
- 
- 
-==== BONUS ==== 
- 
- 
-=== Exercice 6 - Verrouillage de fichier === 
- 
-Nous voulons nous assurer que seule ** une instance ** d'un programme s'​exécute à la fois. Pour cela, un fichier temporaire est en cours de création et tente d'​obtenir un verrou à l'aide de la commande [[http://​linux.die.net/​man/​2/​flock | Flock]]. 
- 
-Entrez le répertoire "​6-singular"​ et remplissez la source "​singular.c"​ (suivez les commentaires avec TODO). 
-<note important>​ Hint: ''​man 2 flock'',​ ''//​nonblocking//''​ </​note>​ 
-Testez en exécutant l'​exécutable à partir de deux terminaux différents ou à l'aide de la commande: <code bash>​./​singular & sleep 3 ; ./​singular</​code>​ 
- 
-Trouvez une méthode permettant de vous assurer que notre programme n'a qu'une seule instance, en utilisant moins d'​appels système ** **. 
- 
-==== EXTRA ==== 
-    * Opérations sur les fichiers en Python 
-    * Étudiez les exemples dans {{ so:​laboratoare:​pyfileoperations.zip | archive}}, lisez la documentation et notez les différences entre les API. 
- 
- 
-===== Solutions ===== 
- 
-[[https://​github.com/​UPB-FILS/​sde/​tree/​master/​tp03/​solutions | Solutions]] 
- 
- 
-===== Ressources utiles ===== 
- 
-  - [[http://​www.gnu.org/​software/​libc/​manual/​html_node/​Low_002dLevel-I_002fO.html|Low level I/O]] (info libc "​Low-Level I/O") 
-  - [[http://​www.gnu.org/​software/​libc/​manual/​html_node/​Duplicating-Descriptors.html|Duplicating descriptors]] (info libc "​Duplicating Descriptors"​) 
-  - [[http://​www.advancedlinuxprogramming.com/​alp-folder/​alp-apB-low-level-io.pdf|Low level I/O]] (Advanced Linux Programming) 
- 
  
sde/laboratoare/03.1552328621.txt.gz · Last modified: 2019/03/11 20:23 by alexandru.radovici
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0