d = open("f",ouverture,0); c = 'a'; write(d,&c,1); lseek(d,(off_t)100000,SEEK_END); write(d,&c,1); lseek(d,(off_t)50000,SEEK_SET); read(d,&c,1); printf("J'ai lu le caractère ASCII %d\n",c); close(d);On supposera qu'avant la première exécution il n'existe pas dans le répertoire courant de lien de nom
f
.
open()
pour que le programme puisse fonctionner comme attendu ?
open()
réalisera t-il la création du fichier ?
printf()
?
#define L 10 total = 0; d = open("g",O_RDONLY); while ((lu=read(d,buf,L))>0) total += lu; printf("%d\n",total); if (lu==-1) { close(d); exit(EXIT_FAILURE); } sleep(10); // 10 secondes d'attente... lu = read(d,buf,L); printf("%d\n",lu); close(d);On suppose qu'avant l'exécution le fichier
g
contient 103 caractères:
printf()
?
printf()
? et pourquoi ?
g
, que produit le second appel à printf()
? et pourquoi ?
g
(rm g
) que se passe t-il pour chacun des deux cas précédents ?
$ ls -ail h 3427142 prw-r--r-- 1 yunes staff 0 16 Jan 13:05 h $
// programme a.c #define L 1000 int d; char buf[L]; int lu; int total; d = open(argv[1],O_RDONLY); printf("%s: %s ouvert\n",argv[0],argv[1]); while ((lu=read(d,buf,L))>0) { buf[lu] = 0; printf("J'ai lu %s\n",buf); } return EXIT_SUCCESS;
// programme b.c #define L 10 int d; char buf[L]; int lu; int total; d = open(argv[1],O_WRONLY); printf("%s: %s ouvert\n",argv[0],argv[1]); while ((lu=read(STDIN_FILENO,buf,L))>0) write(d,buf,lu); close(d); return EXIT_SUCCESS;
a h
depuis un terminal ?
b h
depuis un autre terminal mais sur la même machine ?
abcdef
suivi d'un retour à la ligne sur le terminal depuis lequel on a lancé b
?
<CTRL>-D
sur le terminal depuis lequel on a lancé b
?
void truc() { while ((lu=read(STDIN_FILENO,buf,L))>0) { write(STDOUT_FILENO,buf,lu); write(STDERR_FILENO,buf,lu); } return; }
truc()
?
truc()
afin de recopier le contenu du fichier f1
à la fois sur la sortie standard et dans un fichier de nom f2
:
truc()
et permettant de réaliser ce que l'on désire.
STDIN_FILENO
, STDOUT_FILENO
et STDERR_FILENO
? si oui écrivez le code correspondant, si non expliquez pourquoi.
Le serveur ftpd
reçoit sur un tube d'entrée de nom ftp
des demandes de connexion. Chaque demande correspond à un message contenant deux références et de tubes qui seront utilisés pour réaliser le service de manipulation. Sur le tube le serveur doit s'attendre à recevoir trois types de messages:
DIR
. En réponse à un tel message le serveur doit renvoyer sur le tube , soit les informations relatives au fichier de référence déduite de , soit les informations relatives aux fichiers contenus dans un répertoire de référence déduite de . Les informations transmises en retour sont pour chaque référence trouvée: la référence et la longueur du fichier désigné par cette référence.
GET
. En réponse à un tel message le serveur doit renvoyer dans le tube , la longueur du fichier de référence déduite de puis son contenu.
QUIT
. En réponse le serveur renvoie une confirmation, ferme les tubes et reprend son attente sur le tube principal ftp
.
ftpd /a/b
, toute demande de la part d'un client concernant une référence /c
sera donc traitée par le serveur comme concernant en réalité l'objet de référence /a/b/c
(le client ignore donc la localisation exacte de la référence /c
puisqu'elle est «traduite» dynamiquement par le serveur).
Le client est une simple application interactive qui créé deux tubes uniques ( et ), se connecte sur le serveur en envoyant un message de type ,, réalise une lecture sur le terminal, l'interprète et envoie le message correspondant sur le tube puis lit la réponse et recommence une lecture sur le terminal jusqu'à la saisie d'une commande QUIT
laquelle doit terminer le client après la lecture de la réponse et suppression des objets devenus inutiles.
La création d'une référence unique pourra être réalisée par un appel à la fonction POSIX tmpnam(char *ref);
.