Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3079 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  std::cin et SIGINT

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

std::cin et SIGINT

n°591781
SoWhatIn22
Posté le 16-12-2003 à 14:02:38  profilanswer
 

bonjour,
 
sous linux, j'ai le soucis suivant:
j'ai un process en attente sur std::cin. Je valide chaque entrée en testant std::cin.eof(). En dehors de cela, j'ai un handler pour les signaux SIGINT, SIGHUP et SIGPIPE. Lorsque l'utilisateur envoie un C^c à l'application, celle-ci reçoit bien un signal SIGINT, mais en plus std::cin.eof() renvoie true... J'ai bien essayé de std::cin.clear(std::ios::eofbit), mais rien n'y fait. C'est gênant car je voudrait pouvoir continuer mon process en lisant sur std::cin. Je ne vois pas bien où se trouve le problème et la relation entre SIGINT et l'entrée standard.
Avez vous une idée?

mood
Publicité
Posté le 16-12-2003 à 14:02:38  profilanswer
 

n°591970
Taz
bisounours-codeur
Posté le 16-12-2003 à 16:16:47  profilanswer
 

ton code.
 
attendre std::cin.eof(), tu peux courir ...

n°592008
SoWhatIn22
Posté le 16-12-2003 à 16:58:03  profilanswer
 

Taz a écrit :

ton code.


 
voici un exemple simpliste, qui a le comportement que je décris.
au prompt il ne faut bien sûr rentrer qu'une seule commande.
 
tu fais C^d => ça envoie eof, qui est détécté, et ya pas de souçis. le C^c est bien détécté, mais cin.eof renvoie true.
 

Code :
  1. /*
  2. * file   : main.cpp
  3. *
  4. */
  5. #include <iostream>
  6. #include <unistd.h>
  7. #include <sys/signal.h>
  8. static struct sigaction oldact;
  9. /*
  10. **
  11. **
  12. **
  13. */
  14. void on_signal( int signal )
  15. {
  16.         sigset_t set;
  17.         sigprocmask(SIG_BLOCK, NULL, &set );
  18.         // do the job
  19.         if( signal==SIGINT )
  20.         {
  21.                 std::cout << " ---> pid "<<getpid()<<" - interrupt set (SIGINT) <--- ";
  22.                 std::cout.flush();
  23.         }
  24. std::cout << "clearing std input status...";
  25. std::cin.clear(std::ios::eofbit);
  26. }
  27. /*
  28. **
  29. **
  30. **
  31. */
  32. void sethandler()
  33. {
  34.         struct sigaction act;
  35.         // initialisation des structures
  36.         act.sa_handler    = on_signal;
  37.         oldact.sa_handler = NULL;
  38. // liste des signaux à bloquer pendant l'execution du handler
  39. sigemptyset( &act.sa_mask );
  40.         sigaddset  ( &act.sa_mask, SIGINT );
  41.         sigaction( SIGINT, &act, &oldact);
  42. }
  43. /*
  44. **
  45. **
  46. **
  47. */
  48. int main(int argc, char *argv[])
  49. {
  50. std::string cmd;
  51. sethandler();
  52. while(!std::cin.eof())
  53. {
  54.  std::cout << "> ";
  55.  std::cin  >> cmd;
  56.  if(std::cin.eof()) continue;
  57.  std::cout << "< " << cmd << std::endl;
  58. }
  59. std::cout << std::endl << "> bye (eof="<< std::cin.eof() << " )" << std::endl;
  60. return 0;
  61. }


 
 

n°592032
Taz
bisounours-codeur
Posté le 16-12-2003 à 17:41:53  profilanswer
 

je comprends pas trop ton fonctionnement, cela dit
 
1) if(cin >> dawa)
au cas ou il se passe autre chose.
ensuite si c'est du eof, ilf aut clearer, et nettoyer un peu tout le bordel
std::cin.ignore(std::numeric_limits<int>::max(), '\n');

n°592034
SoWhatIn22
Posté le 16-12-2003 à 17:48:28  profilanswer
 

je suis bien d'accord pour le nettoyage d'après la saisie, qui n'apparait pas dans ce code.
 
Ceci dit, le nettoyage du eof est bien fait dans le handler du SIGINT:

Code :
  1. std::cin.clear(std::ios::eofbit);


et quand j'éxecute cet exemple, le C^c fait bien passer dans le handler, qui fait le clear. Mais une fois revenu dans le processus pricipal, cin.eof() renvoie toujours true. Et c'est bien cela qui m'ennuie...
 

n°592040
Taz
bisounours-codeur
Posté le 16-12-2003 à 17:59:10  profilanswer
 

et les autres champs il ressemblent à quoi ? avec un clear() ?

n°592063
SoWhatIn22
Posté le 16-12-2003 à 18:58:29  profilanswer
 

Taz a écrit :

et les autres champs il ressemblent à quoi ? avec un clear() ?


 

Code :
  1. void on_signal( int signal )
  2. {
  3.         // ...
  4. std::cin.clear();
  5. }
  6. int main(int argc, char *argv[])
  7. {
  8.         // ...
  9. std::cout << "> eof="<< (std::cin.rdstate() && std::ios::eofbit)
  10.  << " good="<< (std::cin.rdstate() && std::ios::goodbit)
  11.  << " bad ="<< (std::cin.rdstate() && std::ios::badbit)
  12.  << " fail="<< (std::cin.rdstate() && std::ios::failbit)
  13.  << std::endl;
  14. }


 
résulat:  
eof=1 good=0 bad =1 fail=1


Message édité par SoWhatIn22 le 16-12-2003 à 18:58:47
n°592075
Taz
bisounours-codeur
Posté le 16-12-2003 à 19:12:47  profilanswer
 

faut nettoyer le reste alors. le plus simple, c'est peut-être de ne changer le eof qui si c'est le seul problème.

n°592292
SoWhatIn22
Posté le 17-12-2003 à 08:16:25  profilanswer
 

nettoyer quel reste? A priori, quand je fais std::cin.clear(), je me dis que tout devrait être nettoyé. Je me trompe? pour dire vrai, je ne vois pas bien comment nettoyer plus. me faut une nouvelle lessive qui nettoie encoire plus que l'actuelle, mais je sais pas laquelle...
 
 
 

n°592314
Taz
bisounours-codeur
Posté le 17-12-2003 à 09:38:52  profilanswer
 

fais avec des & et des &&

mood
Publicité
Posté le 17-12-2003 à 09:38:52  profilanswer
 

n°592370
SoWhatIn22
Posté le 17-12-2003 à 11:36:04  profilanswer
 

Taz a écrit :

fais avec des & et des &&


désolé, je ne comprends pas ce que tu veux dire. Tu peux préciser?

n°592402
Taz
bisounours-codeur
Posté le 17-12-2003 à 12:27:16  profilanswer
 

pas des && logiques mais des & binaires


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  std::cin et SIGINT

 

Sujets relatifs
Plus de sujets relatifs à : std::cin et SIGINT


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)