DELPHI LINUX CODES


Dans cette partie vous allez découvrir quelques bouts de codes utiles pour les programmes console sous linux.
  1. Effacer la console
    - Code source
  2. Executer une commande
    - Code source
  3. readkey
    - Code source

Effacer l'ecran clearscreen

en Turbo pascal il y avait la commande CLRSCR mais en delpi rien pour effacer la console que ce soit en windows ou linux.
Pour linux nous allons utiliser les caractères de séquences d'échappements
ESC[H ESC[2J ESC[3J cela revient à faire pour :
  1. ESC[H : Placer le curseur en position 1,1
  2. ESC[2J : Effacer tout
  3. ESC[3J : Effacer les lignes sauvegardées
Cela ce traduit en Delphi par:

  write (#27'[H'#27'[2J'#27'[3J');
  

Executer une commande

Pour exécuter une commande sous linux et récupérer son résultat il va falloir passer par les API suivantes :
popen : http://man7.org/linux/man-pages/man3/popen.3p.html
fgets : http://man7.org/linux/man-pages/man3/fgets.3p.html
pclose : http://man7.org/linux/man-pages/man3/pclose.3p.html

Déclaration des API


uses 
  Posix.Base;
        
type 
  TStreamHandle = pointer;

function popen  ( const aStcommand: MarshaledAString; const aStrType: MarshaledAString ): TStreamHandle; cdecl; external libc name _PU + 'popen';
//  ___________________________________________________________________________
// | Function popen                                                            |
// | _________________________________________________________________________ |
// || Permet de créer un processus en créant un tube (pipe)                   ||
// ||_________________________________________________________________________||
// || Entrées | const aStcommand: MarshaledAString                            ||
// ||         |   commande a executer                                         ||
// ||         | const aStrType: MarshaledAString                              ||
// ||         |   « r » pour la lecture ou « w » pour l'écriture              ||
// ||_________|_______________________________________________________________||
// || Sorties | result : TStreamHandle                                        ||
// ||         |   nul ou -1 si nok                                            ||
// ||_________|_______________________________________________________________||
// |___________________________________________________________________________|

function pclose ( filehandle: TStreamHandle ): int32; cdecl; external libc name _PU + 'pclose';
//  ___________________________________________________________________________
// | Function pclose                                                           |
// | _________________________________________________________________________ |
// || Permet d'attendre la fermeture du processus                             ||
// ||_________________________________________________________________________||
// || Entrées | filehandle: TStreamHandle                                     ||
// ||         |   Handle du processus ouvert                                  ||
// ||_________|_______________________________________________________________||
// || Sorties | result : integer                                              ||
// ||         |   resultat de l'execution 0 ok -1 nok                         ||
// ||_________|_______________________________________________________________||
// |___________________________________________________________________________|

function fgets  ( buffer : pointer ; size : int32 ; Stream : TStreamHAndle ) : pointer; cdecl; external libc name _PU + 'fgets';
//  ___________________________________________________________________________
// | Function fgets                                                            |
// | _________________________________________________________________________ |
// || Permet de recuperrer un string depuis un flux                           ||
// ||_________________________________________________________________________||
// || Entrées | buffer : pointer                                              ||
// ||         |   string lut                                                  ||
// ||         | size : int32                                                  ||
// ||         |   taille a lire                                               ||
// ||         | Stream : TStreamHAndle                                        ||
// ||         |   flux d'ou recuperrer le string                              ||
// ||_________|_______________________________________________________________||
// || Sorties | result : pointer                                              ||
// ||         |   nul si nok                                                  ||
// ||_________|_______________________________________________________________||
// |___________________________________________________________________________|
  

Création des fonctions

nous allons definir la fonction BufferToString

function BufferToString( Buffer: pointer; MaxSize: uint32 ): string;

//  ___________________________________________________________________________
// | function BufferToString                                                   |
// | _________________________________________________________________________ |
// || Permet de convertir un buffer en chaine de caractéres                   ||
// ||_________________________________________________________________________||
// || Entrées | Buffer: pointer                                               ||
// ||         |   buffer à convertir                                          ||
// ||         | MaxSize: uint32                                               ||
// ||         |   taille a convertir                                          ||
// ||_________|_______________________________________________________________||
// || Sorties | result : string                                               ||
// ||         |   chaine convertie                                            ||
// ||_________|_______________________________________________________________||
// |___________________________________________________________________________|

var
  cursor: ^uint8;
  EndOfBuffer: nativeuint;
begin
  Result := '';
  if not assigned(Buffer) then
  begin
    exit;
  end;
  cursor := Buffer;
  EndOfBuffer := NativeUint ( cursor ) + MaxSize;
  while ( NativeUint ( cursor ) < EndOfBuffer ) and ( cursor^ <> 0 ) do
  begin
    Result := Result + chr(cursor^);
    cursor := pointer( succ(NativeUInt(cursor)) );
  end;
end;
  
puis nous allons définir la fonction strExecuteCommande

function strExecuteCommande ( aStrCommande : string ; aStrMode :string ) : string;
//  ___________________________________________________________________________
// | function strExecuteCommande                                               |
// | _________________________________________________________________________ |
// || Permet d'executer une commande est renvoie le resultat                  ||
// ||_________________________________________________________________________||
// || Entrées | aStrCommande : MarshaledAString                               ||
// ||         |   ligne de commande à executer                                ||
// ||         | aStrMode :MarshaledAString                                    ||
// ||         |   « r » pour la lecture ou « w » pour l'écriture              ||
// ||_________|_______________________________________________________________||
// || Sorties | result  : string                                              ||
// ||         |   resultat de la commande                                     ||
// ||_________|_______________________________________________________________||
// |___________________________________________________________________________|

var
  Handle: TStreamHandle;
  Data: array[0..511] of uint8;
begin
  result := '';
  Handle := popen(PAnsiChar(AnsiString( aStrCommande )) , PAnsiChar(AnsiString( aStrMode)) );
  try
    while fgets(@data[0],Sizeof(Data),Handle) <> nil do 
	begin
      result := result + BufferToString(@Data[0],sizeof(Data));
    end;
  finally
    pclose(Handle);
  end;
end;
  

Utilisation

Par exemple pour avoir le nom de la machine

  write ('Le nom de la machine est : ' + strExecuteCommande ('/bin/hostname','r' ));
  

readkey

Pour retrouver la function readkey il va falloir passer par les API suivantes :
getchar : http://man7.org/linux/man-pages/man3/getchar.3p.html
tcgetattr : http://man7.org/linux/man-pages/man3/tcgetattr.3p.html
tcsetattr : http://man7.org/linux/man-pages/man3/tcsetattr.3p.html
Et la structure suivante :
termios : http://man7.org/linux/man-pages/man0/termios.h.0p.html

Déclaration de la structure


uses
  Posix.Unistd,
  Posix.Base;

type
  cc_t = Byte;
  speed_t = Cardinal;
  tcflag_t = Cardinal;

const
  NCCS = 32;
  _POSIX_VDISABLE: cc_t = cc_t(#0);
  ICANON    = $0000002;
  ECHO      = $0000008;
  VMIN      = 6;
  TCSANOW   = 0;

type

  termios = record
    c_iflag  : tcflag_t;                        { modes d'entrée }
    c_oflag  : tcflag_t;                        { modes de sortie }
    c_cflag  : tcflag_t;                        { modes de contrôle }
    c_lflag  : tcflag_t;                        { modes locaux }
    c_line   : cc_t;                            { discipline de ligne }
    c_cc     : packed array[0..NCCS-1] of cc_t; { caractères de contrôle }
    c_ispeed : speed_t;                         { vitesse d'entrée }
    c_ospeed : speed_t;                         { vitesse de sortie }
  end;
  

Déclaration des API


function getchar () : integer; cdecl; external libc name _PU + 'getchar';
//  ___________________________________________________________________________
// | function getchar                                                          |
// | _________________________________________________________________________ |
// || Permet de lire un octet depuis le stdin                                 ||
// ||_________________________________________________________________________||
// || Entrées |                                                               ||
// ||         |                                                               ||
// ||_________|_______________________________________________________________||
// || Sorties | result : integer                                              ||
// ||         |   code caractére                                              ||
// ||_________|_______________________________________________________________||
// |___________________________________________________________________________|

function tcsetattr( aIntFd : Integer; aIntOptionalActions : Integer; const aP_Termios : pointer): Integer; cdecl; external libc name _PU + 'tcsetattr';
//  ___________________________________________________________________________
// | function tcsetattr                                                        |
// | _________________________________________________________________________ |
// || Permet de definir les attributs TTY pour le descripteur de fichier      ||
// ||_________________________________________________________________________||
// || Entrées | aIntFd : Integer                                              ||
// ||         |   descripteur de fichier                                      ||
// ||         | aIntOptionalActions : Integer                                 ||
// ||         |   options d'actions voir Constantes pour tcsetattr            ||
// ||         | const aP_Termios : pointer                                    ||
// ||         |   pointeur sur la structure termios contenant les attributs   ||
// ||_________|_______________________________________________________________||
// || Sorties | result : integer                                              ||
// ||         |   resultat de l'execution 0 ok -1 nok                         ||
// ||_________|_______________________________________________________________||
// |___________________________________________________________________________|

function tcgetattr( aIntFd : Integer; aP_Termios: pointer): Integer; cdecl;external libc name _PU + 'tcgetattr';
//  ___________________________________________________________________________
// | Function tcgetattr                                                        |
// | _________________________________________________________________________ |
// || Permet de retourner les attributs TTY pour le descripteur de fichier    ||
// ||_________________________________________________________________________||
// || Entrées | aIntFd : Integer                                              ||
// ||         |   descripteur de fichier                                      ||
// ||_________|_______________________________________________________________||
// || Sorties | aP_Termios: pointer                                           ||
// ||         |   pointeur sur la structure termios recevant les attributs    ||
// || Sorties | result : integer                                              ||
// ||         |   resultat de l'execution 0 ok -1 nok                         ||
// ||_________|_______________________________________________________________||
// |___________________________________________________________________________|
  

Création des fonctions

nous allons definir la fonction readKey

function readKey ( aBooMasqueCaractere : boolean = true ) : char;

//  ___________________________________________________________________________
// | function readKey                                                          |
// | _________________________________________________________________________ |
// || Permet de lire une touche venant du clavier                             ||
// ||_________________________________________________________________________||
// || Entrées | aBooMasqueCaractere : boolean = true                          ||
// ||         |   mettre à true pour masquer le caractére                     ||
// ||_________|_______________________________________________________________||
// || Sorties | result : char                                                 ||
// ||         |   code du caractére appuyé                                    ||
// ||_________|_______________________________________________________________||
// |___________________________________________________________________________|

var
  savedState : termios;
  newState   : termios;
  intMasque  : integer;
begin

// ****************************************************************************
// * Sauvegarde les attributs TTY                                             *
// ****************************************************************************

  tcgetattr( STDIN_FILENO, @savedState);
  newState := savedState;

// ****************************************************************************
// * Calcule le nouveau masque d'attribut, non canonical et mascage caractere *
// * si defini                                                                *
// ****************************************************************************

  intMasque := ICANON;
  if aBooMasqueCaractere then
    intMasque := intMasque or ECHO;

// ****************************************************************************
// * Defini le nouveau local mode                                             *
// ****************************************************************************

  newState.c_lflag := not( intMasque ) and newState.c_lflag;

// ****************************************************************************
// * Defini l'attente à un caractere                                          *
// ****************************************************************************

  newState.c_cc[VMIN] := 1;

// ****************************************************************************
// * Defini les nouveau attribut TTY                                          *
// ****************************************************************************

  tcsetattr(STDIN_FILENO, TCSANOW, @newState);

// ****************************************************************************
// * Attend l'appuie sur une touche                                           *
// ****************************************************************************

  result := char ( getchar());

// ****************************************************************************
// * restaurre les attributs TTY                                              *
// ****************************************************************************

  tcsetattr(STDIN_FILENO, TCSANOW, @savedState);

end;