Je travaille sur un projet C qui est censé être similaire à la commande “more” d’Unix. Comme “more”, ce programme est supposé pouvoir être saisi depuis un fichier (si spécifié) ou stdin si aucun fichier n’est fourni (pour que la sortie des autres programmes puisse y être transférée) et l’afficher sur stdout. Aussi comme “plus”, l’écho et le mode canonique sont supposés être désactivés, ce que j’ai fait avec le code suivant:
//change terminal atsortingbutes tcgetattr(0, &info); //Get info tcgetattr(0, &orig_inf); //Save original info info.c_lflag &= ~ECHO; //Disable echo info.c_lflag &= ~ICANON; //Disable canonical mode info.c_cc[VMIN] = 1; //Get 1 char at a time tcsetattr(0, TCSANOW, &info); //Set atsortingbutes
Pour lire les commandes de l’utilisateur depuis le clavier, j’ouvre explicitement “dev / tty” plutôt que de simplement lire stdin:
//Open cmd stream if((cmd = fopen("/dev/tty", "r")) == NULL){ perror("Failure opening command stream"); tcsetattr(0, TCSANOW, &orig_inf); exit(EXIT_FAILURE); }
et les lire avec getc (cmd). Cela fonctionne bien lorsque l’utilisateur fournit un fichier à lire, mais si le programme reçoit des entrées de stdin, il semble que les atsortingbuts du terminal soient en cours de réinitialisation. Je peux voir toutes les commandes que j’essaie de taper (ce qui signifie que l’écho est à nouveau activé) et les commandes ne sont pas envoyées au programme à moins que j’appuie sur enter (ce qui signifie que le mode canonique a été réactivé). J’ai cherché sur le Web et toutes les pages de manuel pour presque tous les appels système que j’utilise, et je n’arrive pas à trouver une raison à cela.
Si quelqu’un sait pourquoi cela se produit et comment y remédier, l’aide serait très appréciée.
Merci!
Ce qui semble manquer (du moins pas indiqué dans la question), c’est que vous ouvrez /dev/tty
pour lire les commandes et réinitialisez l’entrée standard d’origine via un descripteur de fichier. Mais il n’y a aucune mention d’utiliser fdreopen
ou dup2
:
0
(FILENO_STDIN), il ne s’agit pas du même descripteur de fichier que fileno(cmd)
– sauf si vous utilisez dup2
pour le remplacer. open
que fopen
, simplement parce que open
offre plus de contrôle sur le processus. On utilisera alors fdreopen
pour obtenir un stream en mémoire tampon à partir du descripteur de fichier. En utilisant fopen
sur /dev/tty
, par exemple, vous avez peut-être ignoré les parameters réels de ce stream, qui ne sont pas nécessairement les mêmes que ceux que vous avez reconfigurés sur le descripteur de fichier 0
. Une question connexe pourrait être: Quelle est la différence entre stdin et STDIN_FILENO? .