GNU/Linux >> Tutoriels Linux >  >> Linux

Obtenir un caractère non bloquant

Vous faites des IO de manière incorrecte, le manuel POSIX et toutes les autres documentations associées indiquent explicitement de ne jamais mélanger les IO effectuées sur FILE * s et descripteurs de fichiers. Vous avez très clairement enfreint cette règle. Cette règle est en place car FILE * s utiliser la mise en mémoire tampon an cela signifie qu'après un appel au fgets il ne restera plus rien pour read obtenir parce que fgets déjà lu toutes les données en attente dans un tampon qui est conservé dans le FILE * structure.

Donc, comme il n'y a aucun moyen de vérifier si une méthode ISO C IO bloquera, nous devons utiliser uniquement des descripteurs de fichiers.

Puisque nous savons que STDIN_FILENO est juste le nombre 0, nous pouvons utiliser

fcntl (0, F_SETFL, O_NONBLOCK);

cela transformera tous les read s sur le descripteur de fichier 0 en mode non bloquant, si vous souhaitez utiliser un descripteur de fichier différent afin de pouvoir laisser 0 seul, utilisez simplement dup pour le dupliquer.

De cette façon, vous pouvez rester à l'écart du poll complètement et implémentez ngetc comme

ssize_t 
ngetc (char *c)
{
  return read (0, c, 1);
}

ou mieux encore, une macro

#define ngetc(c) (read (0, (c), 1))

Ainsi, vous obtenez une implémentation simple pour ce que vous recherchez.

Modifier : Si vous craignez toujours que le terminal ne mette en mémoire tampon l'entrée, vous pouvez toujours modifier les paramètres du terminal, voir Comment désactiver la mise en mémoire tampon de ligne de l'entrée dans xterm à partir du programme ? pour plus d'informations sur la façon de procéder.

Modifier : La raison pour laquelle on ne pouvait pas utiliser fgetc au lieu de read est pour la même raison que l'utilisation de fgets ne fonctionnera pas. Lorsque l'un des FILE * Les fonctions d'E/S sont exécutées, elles lisent toutes les données du descripteur de fichier associé. Mais une fois que cela se produit, poll ne reviendra jamais car il attend un descripteur de fichier toujours vide, et la même chose se produira avec read . Ainsi, je vous suggère de suivre les conseils de la documentation et jamais mélanger les flux (IO utilisant fgets , fgetc , etc.) et descripteurs de fichiers (IO utilisant read , write , etc.)


Linux
  1. Fichier équivalent ".bashrc" lu par tous les shells ?

  2. Obtenir l'âge du fichier donné ?

  3. Tail lit-il tout le fichier ?

  4. Décompresser un fichier .gz pour obtenir un fichier texte mais obtenir un fichier binaire ? ?

  5. Comment lire une variable à partir d'un fichier ?

Comment lire des fichiers ligne par ligne dans Bash

Comment lire un fichier ligne par ligne dans Bash

Obtenir l'heure de création/création du fichier ? ?

Autorisations de fichiers sous Linux – Lecture/Écriture/Exécution

Obtenir la longueur MP3 sous Linux / FreeBSD

Obtenir l'emplacement de la ville à partir des adresses IP dans un fichier