|
Écriture d'une
fonction d'encapsulation (banalisée) |
1 - But de la fonction :
Un professeur
de mathématiques m'a demandé s'il était possible d'améliorer le dialogue avec
certains programmes qui n'utilisent que le clavier et l'écran, programmes de
type console donc. Ces programmes relativement éphémères dont la durée
de vie est l'année scolaire en général, n'incitent pas au développement
d'une interface élaborée, surtout graphique. Il faudrait donc quelque chose
de facile à mettre en oeuvre.
J'ai donc répondu que j'allais essayer de regarder comment faire et
j'ai pensé à la technique d'encapsulation de programme comme le réalisent les
commandes "ddd", "cgdb", "xcbx" en particulier qui encapsulent la commande
de debugguing "gdb". On a l'habitude d'utiliser aujourd'hui le vocable de "Front
end" pour nommer ce genre de programme.
J'ai alors essayé de m'appuyer sur les sources des commandes "ddd", "cgdb" et "xdbx" !.... Pas aisé je dois dire car les commentaires sont trés limités, surtout dans "cgdb", et je n'ai pas trouvé de documentation explicative qui s'y rapporte.
Pour faire ce qui est demandé, il faut limiter la programmation au strict nécessaire. J'ai donc essayé d'écrire une fonction qui ferait le travail d'encapsulation et que j'ai appelée "encaps.c". L'utilisateur aurait alors à programmer le traitement des sorties et des entrées du programme encapsulé.
Durant mon activité dans l'aéronautique, au tout début des années 80, j'ai déjà été confronté à ce besoin sur des stations Apollo, tournant sous système AEGIS, SYS V et BSD 4.2, pour tenter de connecter en mode online une table de dessin Kongsberg, une machine à commandes numériques, fonctionnant normalement en off-line. Je n'ai pas le souvenir d'avoir galéré comme aujourd'hui. Peut-être l'âge !... Il me semble que j'utilisais les IPC's (Inter Process Communications et "mmap") avec un pilote-caractère qu'Apollo m'avait aidé à installer. Je n'ai pas le souvenir des speudo-terminaux. Je vais tenter néanmoins de chercher dans mes vieilles archives une éventuelle note qui traînerait par là.
2 - Le programme "mon_programme" à encapsuler :
Ce programme simple simule le fonctionnement-type d'un programme-console comme "gdb". En entrée, le programme affiche un prompt "mpgm=>" pour la saisie du nombre de lignes à afficher et en sortie le programme affiche le nombre de lignes demandées en les numérotant :
Prototype de programme-console...
mpgm=>2
ligne 0
ligne 1
mpgm=>5
ligne 0
ligne 1
ligne 2
ligne 3
ligne 4
mpgm=>quit
Il s'agit donc d'obtenir le même résultat mais affiché par le programme encapsuleur ce qui permet d'envisager de traiter les flux d'entrée et de sortie du programme encapsulé.
2 - Le programme encapsuleur "ma_commande" :
C'est le programme qui doit être lancé. Il se compose des données et des points d'entrée suivants pour remplir sa fonction :
A) - Les données :
| "*prompt_maitre" | : | affiché par le programme encapsuleur pour demander à l'utilisateur d'entrer une commande au clavier. |
| "*quit_maitre" | : | commande entrée au clavier par l'utilisateur pour demander au programme encapsuleur de sortir. |
| "*prompt_esclave" | : | prompt habituel du programme encapsulé qui permet au programme encapsuleur de savoir s'il faut saisir une commande. Par exemple avec gdb lc prompt est "(gcb)". |
| "*pgm_encaps" | nom du programme à encapsuler. |
B) - Les points d'entrée à écrire par l'utilisateur :
| "encaps_init" | : | routine d'initialisation avant le fork() |
| "encaps_recu" | : | routine de traitement des lignes reçues |
| "encaps_emis" | : | routine de traitement des lignes à envoyer |
| "encaps_ctlC" | : | routine de traitement du signal CTRL/C éventuellement entrée par l'utilisateur sur son clavier |
| "main" | : | point d'entrée principal du programme encapsuleur. |
3 - Console de la compilation :
$ make
4 - Console de l'exécution :
$ ma_commande
5 - Ce que je constate :
Le programme affiche :
Si on essaie de relancer "ma_commande", le fonctionnement du programme s'arrête parfois au niveau de la ligne 10.
Un test de dernière minute (si cela peut éclairer) :
- Jusqu'ici, je travaillais sur un disque NTFS d'une partition autre que celle du système pour le partager avec Windows/Vista.
- Quand je lance le programme dans ma "home directory", donc sur le disque EXT3 du système Ubuntu, le programme refuse tout dialogue et s'arrête systématiquement au niveau de la ligne 10 comme citée plus haut.
- Soupçonnant des problèmes de timing dûs aux différences de performances lors du chargement, j'ai ajouté à tout hasard (!!!) l'instruction sleep(1) à la ligne 196 de "encaps.c" juste avant le début du dialogue avec le processus-esclave et là le fonctionnement s'effectue jusqu'au niveau de la ligne 16 comme je l'ai présenté.
Voilà où j'en suis. J'ai l'impression qu'il ne manque pas grand chose mais quoi ?
Merci si vous pouvez m'aider à trouver l'erreur de logique à moins qu'il faille s'y prendre autrement mais peut-être pas comme dans les sources de "cgdb" e "xdbx"que j'analyse et que je trouve un peu brouillon.
J'ai, pour ma part, quelques utilisations personnelles d'un tel outil.
Dans l'espoir de trouver parmi vous au moins une personne intéressée par ce genre de service ou par la technique pour l'assurer, encore merci d'avance.
Jean-Pierre Rousset