[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [gulliver] Python et la gestion des signaux


From plaunay1 <pierre dot launay at ac-rennes dot fr>
Subject Re: [gulliver] Python et la gestion des signaux
Date Sun, 13 Apr 2008 19:17:52 +0200

Jean-Philippe Gaulier a écrit :
Le Sat, 12 Apr 2008 23:39:29 +0200,
plaunay1 <pierre dot launay at ac-rennes dot fr> a écrit :

Allez, je me lance dans la pseudo traduction, Patrick aura l'amabilité de me
reprendre en douceur si je raconte des âneries :))

Le premier c'est un débordement de buf si read() lit 255
caractères, buf[255] n'a alors pas la place pour buf[res]=0.

OK, mais tu chipotes

Pas vraiment. Je te montrerai du chipotage (gestion des chaînes avec passage de big indian à little indian), mais dans ce cas précis, c'est ou ça peut être très courant qu'une chaîne de caractère dépasse la taille autorisée, il faut donc se border. C'est le b-a-ba de la programmation compilée (avantage du semi-compilé ou de l'interprété pour tout ce qui est débordement de tampon). Donc Pierre, prend les bonnes méthodes dès le départ :p

Je rappelle qu'au départ, c'est pour gérer une liaison série entre un PC et un microcontroleur et qu'il n'y a que les informaticiens pour envoyer depuis un microcontroleur 254 caractères ASCII suivi d'une fin de ligne.
Question pour informaticien : quelles différences entre microprocesseur et microcontroleur ?


Le second c'est que "by design" ça ne marche pas.

C'est quoi "by design" "par dessin ???"

Par design signifie que l'architecture est censé le prendre en compte. Tout comme le design d'une voiture emporte l'airbag, les barres latérales renforcées et autres nécessités du genre.



Le troisième c'est que printf() n'est pas autorisé dans un gestionnaire
de signal. La liste des fonctions "saines" est donnée dans man
sigaction

Pas en français

printf n'étant pas une fonction saine, c'est normal que tu ne la trouves pas dans le man en question. Plutôt que de le chercher tel un barbare en quête de nouveaux pâturages à conquérir, prend le temps de bien lire le man dans son intégralité.

C'est pas facile à lire, encore moins à comprendre même en français !!!

Un très bon bouquin (une bible ?) est "Programmation système en C sous Linux" de Christophe Blaess, publié chez Eyrolles. Je peux l'amener demain si tu viens à la séance "secure http/ssh/ftp, ou pas".

librement,
jp

Ci-joint ce que j'ai compris "en français" du fichier C #include <termios.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #include <sys/types.h>

      #define BAUDRATE B38400
      #define MODEMDEVICE "/dev/ttyS1"
      #define _POSIX_SOURCE 1 /* POSIX compliant source */
      #define FALSE 0
      #define TRUE 1

volatile int STOP=FALSE;

void signal_handler_IO (int status); /* definition of signal handler */
int wait_flag=TRUE; /* TRUE while no signal received */


      main()
      {
        int fd,c, res;
        struct termios oldtio,newtio;
        struct sigaction saio;           /* definition of signal action */
        char buf[255];

/* open the device to be non-blocking (read will return immediatly) */
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd <0) {perror(MODEMDEVICE); exit(-1); } /* erreur port non ouvert */
/* On associe fd et le port série avec lequel on travaille voir Termios*/


/* install the signal handler before making the device asynchronous */
saio.sa_handler = signal_handler_IO;
saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
/* si une lecture ou écriture sur port série alors le signal SIGIO est déclenché */
/* on déroute la gestion de l'interruption vers signal_handler_IO voir man sigaction */
/* allow the process to receive SIGIO */
fcntl(fd, F_SETOWN, getpid());
/* on associe fd et sigaction et on met le PID du propriétaire getpid() voir man fcntl partie F_SETOWN */
/* Make the file descriptor asynchronous (the manual page says only
O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
fcntl(fd, F_SETFL, FASYNC); /* on met en mode asynchrone, non bloquant */


tcgetattr(fd,&oldtio); /* save current port settings */
/* set new port settings for canonical input processing */
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR | ICRNL;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
/* termios mode canonique lecture man termios */
/* CRTSCTS
(Pas dans POSIX) Contrôle de flux RTS/CTS. [Nécessite _BSD_SOURCE ou _SVID_SOURCE]
C'est même pas POSIX bouh ... */
/* loop while waiting for input. normally we would do something
useful here c'est ici qu'il faudra mettre le callback */
while (STOP==FALSE) {
printf(".\n");usleep(100000);
/* after receiving SIGIO, wait_flag = FALSE, input is available
and can be read */
if (wait_flag==FALSE) {
res = read(fd,buf,255);
buf[res]=0;
printf(":%s:%d\n", buf, res);
if (res==1) STOP=TRUE; /* stop loop if only a CR was input */
wait_flag = TRUE; /* wait for new input */
}
}
/* restore old port settings */
tcsetattr(fd,TCSANOW,&oldtio);
}



/***************************************************************************
* signal handler. sets wait_flag to FALSE, to indicate above loop that *
* characters have been received. *


***************************************************************************/

void signal_handler_IO (int status)
{
printf("received SIGIO signal.\n");
wait_flag = FALSE;
}
/* si j'ai compris signal_handler_IO est appelé par SIGIO,
or on ne met pas de printf dans une procédure appelée par une interruption */
/* Quand on veut tester qu'on passe bien dans un programme d'IT,
on place un drapeau dans celui-ci et c'est dans le programme principal qu'on l'affiche
le printf dans le main ne me dérange pas */


Je croyais que Patrick parlait du printf dans le main

Pierre