Suivez-nous sur X

|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Assembleur - les notifications
(Article écrit par Frédéric Delacroix et extrait d'Amiga News - octobre 1994)
|
|
On le sait déjà, les progrès faits par AmigaOS depuis sa version 2.0 sont immenses. Parmi
les nouveautés, la notification répond à un besoin lié à la nouvelle gestion des Préférences
à partir de cette version : elle permet de détecter les changements effectués sur un fichier.
Dans le cas des Préférences, c'est le programme IPrefs qui se charge de cette surveillance.
Le principe
Sur Amiga, les lecteurs de disquette, le disque dur, le RAM Disk, tout ce qu'on peut imaginer,
sont gérés par des processus séparés. Ainsi, DF0: gère le lecteur interne, RAM: le RAM Disk,
RAD: le disque récupérable, SER: le port série, etc. Le rôle de ces processus, appelés "handlers",
est de gérer les périphériques, soit directement, soit par l'intermédiaire des périphériques logiques d'exec.
La dos.library est ainsi, en gros, un protocole de communication entre les processus :
le programme et les handlers, d'où l'apparition des fameux paquets DOS (DosPackets), que nous n'étudierons
pas en détail ici.
Certains handlers, comme PRT (imprimante) ou SPEAK (le narrateur) n'acceptent que des données brutes,
ce n'est évidemment pas le cas de ceux qui gèrent des fichiers. Le code s'occupant alors de ces
handlers s'appelle alors un "filesystem" (système de fichiers). Sur Amiga, deux systèmes de fichiers
se trouvent déjà en ROM : le premier gère soit l'OFS (Old File System, utilisé surtout avant le
Kickstart 2.0) ou le FFS (Fast File System, version aux performances améliorées).
Le FFS est apparu avec le Kickstart 1.3, et résidait sur disquette (répertoire L:),
on ne pouvait pas amorcer une disquette FFS. De nos jours (Kickstart 2.0 et plus),
l'OFS et le FFS ont été réunis dans un seul module, situé en ROM, d'où son nom de
"ROM FileSystem" (système de fichiers en ROM). Le second système de fichiers se trouve au sein même du RAM-handler,
le gestionnaire du RAM Disk.
Le Workbench 2.1 a également apporté le système de fichiers CrossDOS, qui permet d'accéder aux
disquettes au format MS-DOS comme s'il s'agissait de disquettes Amiga. D'autres système de fichiers
peuvent prendre en compte un lecteur de CD, ou d'autres formats étrangers, on peut trouver le
ProFileSystem dans le domaine public (on peu bogué me semble-il) ; on a ici un aperçu de la
puissance du système de l'Amiga.
En fait, les systèmes de fichiers et les handlers ont le même rôle : recevoir et interpréter les
messages des autres processus qui leur parviennent sous forme de paquets DOS : lecture, écriture,
ouverture de fichier, etc. Les processus nommés DF0:, DF1:, DH0: sont ainsi de multiples
incarnations du système de fichiers en ROM, chargés chacun du périphérique logique DOS correspondant. Ce qui nous concerne
ici est le fonctionnement de l'un de des paquets DOS, apparu avec le Kickstart 2.0, et
plus précisément son interface avec la dos.library : la notification.
La notification consiste à demander à un handler (chargé d'un périphérique logique DOS) de vous prévenir
lorsqu'un objet à sa charge est modifié (par vous-même ou une autre tâche, peu importe).
Pour l'instant, il n'est pas possible de surveiller les lectures. Précisons tout de suite
que les systèmes de fichiers ne sont absolument pas obligés d'autoriser la notification.
Le système de fichiers en ROM et le RAM-handler l'utilisent (pas sans bogues mineurs, d'ailleurs),
pas CrossDOS.
Les opérations suivantes peuvent déclencher une notification : écriture dans un fichier (dans
ce cas, la notification intervient à la fermeture du fichier), création d'un fichier, création
d'un répertoire, effacement d'un fichier, création de liens matériels (hard links),
changement de nom, de commentaire, de date ou d'attributs de protection. De plus, la
notification est associée au volume et non au périphérique logique. C'est-à-dire que si vous enlevez la
disquette avec le fichier surveillé et en insérez une autre, les fichiers de celle-ci ne
sont pas surveillés. C'est comme si, par exemple, DF0: désignait la disquette en DF0:
et non le lecteur lui-même.
Concrètement
Toute demande de notification passe obligatoirement par une structure, définie dans dos/notify.i,
fort judicieusement nommée "NotifyRequest".
Voyons les champs importants de cette structure :
"nr_Name" contient un pointeur sur le
nom de l'objet (fichier ou directory) à surveiller. Ce nom sera étendu (en résolvant les
assignations et liens) par la fonction "StartNotify()", un pointeur sur ce nom complet
sera alors disponible dans le champ "nr_FullName".
"nr_Flags" contient quelques drapeaux (flags) qui indiquent au handler comment procéder.
Les drapeaux définis indiquent si la notification doit être faite par l'envoi d'un message
(drapeau NRF_SEND_MESSAGE) ou d'un signal (drapeau NRF_SEND_SIGNAL), si le handler doit attendre
la réponse avant d'envoyer une nouvelle notification (drapeau NRF_WAIT_REPLY,
valable uniquement avec NRF_SEND_MESSAGE) et s'il doit envoyer une notification tout de suite (drapeau
NRF_NOTIFY_INITIAL). Vient ensuite une union. Rappelons que dans ce cas, seule la taille du plus
grand des champs est réservée au sein de la structure. Dans le cas du drapeau NRF_SEND_MESSAGE,
on trouve un pointeur sur le MsgPort où le message doit être envoyé (champ "nr_Port"),
ou, dans le cas de NRF_SEND_SIGNAL, l'adresse de la tâche à signaler et le numéro
du signal (et pas le masque correspondant !) à utiliser.
Il va de soi que le signal doit avoir été alloué par AllocSignal() avant ! Les autres champs
sont privés et doivent être mis à 0. Une fois la structure NotifyRequest réservée et initialisée,
on peut le déclarer grâce à la fonction suivante de la dos.library :
succès.StartNotify(NR)
D0 D1
|
A partir de ce moment, la structure NotifyRequest ne doit plus être modifiée : en effet, le
handler peut y accéder à tout moment pour envoyer des messages. À propos, voyons la structure des
messages reçus dans le cas du flag NRF_SEND_MESSAGE :
Outre le message Exec placé au début, le seul champ important pour nous est "nm_NReq" :
il pointe la structure NotifyRequest concernée, ce qui est bien pratique si on surveille
beaucoup d'objets à la fois. La raison d'être des champs "nm_Class" et "nm_Code" est l'imitation
d'une structure IntuiMessage, d'où la possibilité d'utiliser le port IDCMP d'une fenêtre pour
la notification. Ce n'est toutefois pas recommandé.
La valeur retournée par StartNotify() indique si le handler a ou non accepté votre demande de
notification. Contrairement à ce que racontent les autodocs, si StartNotify() a échoué, il ne
faut pas appeler la fonction suivante. Celle-ci permet de retirer une demande de notification :
la structure NotifyRequest (passée en argument) pourra alors être libérée ou réutilisée.
Bogues ?
Comme je l'ai dit plus haut, la notification est légèrement boguée dans les versions actuelles des
deux systèmes de fichiers en ROM, rien de très grave, rassurez-vous.
Premièrement, la version 36 (Kickstart 2.0) du système de fichiers en ROM n'envoie pas de
notifications du tout, mais tout le monde devrait posséder au moins la version 37 de nos
jours. De plus, le système de fichiers en ROM n'accepte de notification sur un répertoire
que si celui-ci existe déjà au moment de StartNotify(), la création d'un fichier en MODE_READWRITE
ne déclenche pas de notification, et EndNotify() ne marche pas correctement sur les fichiers situés
sur une disquette non insérée dans un lecteur. Le ram-handler, quant à lui, n'envoie pas de notification si un
fichier est modifié dans un répertoire surveillé (alors que cela constitue aussi une modification du
répertoire en question).
Enfin, le système de fichiers en ROM ignore (pour la notification) SetComment(), SetFileDate()
et SetProtection(). Le RAM handler ignore SetComment() et SetProtection().
Programme d'exemple
Nous en savons assez pour écrire un programme de surveillance de fichiers et de répertoires.
Pour corser un peu, je l'ai prévu pour surveiller plusieurs objets en même temps,
ce qui montre un peu la gestion des listes.
Une dernière chose : sachant que tous les systèmes de fichiers n'implémentent pas la notification
(en particulier CrossDOS et tous les systèmes de fichiers de réseaux), il vaut mieux ne pas
trop se reposer dessus et prévoir, lorsqu'il s'agit de relire un répertoire ou de recharger
un fichier, une action manuelle. De plus, on peut aussi détecter les changements effectués sur
un répertoire en comparant les dates de modifications (ce que font certaines requêtes de fichiers).
Sur ce, je vous laisse avec le listing du programme, à bientôt.
|