[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