GNU/Linux >> Tutoriales Linux >  >> Linux

Obtener carácter sin bloqueo

Estás haciendo IO incorrectamente, el manual POSIX y toda la documentación relacionada dice explícitamente que nunca mezcles IO hecho en FILE * s y descriptores de archivos. Has roto esta regla descaradamente. Esta regla existe porque FILE * s usar búfer y esto significa que después de una llamada a fgets no quedará nada para read obtener porque fgets ya leyó todos los datos pendientes en un búfer que se guarda en el FILE * estructura.

Entonces, dado que no hay forma de verificar si un método ISO C IO se bloqueará, solo debemos usar descriptores de archivos.

Como sabemos que STDIN_FILENO es solo el número 0, podemos usar

fcntl (0, F_SETFL, O_NONBLOCK);

esto convertirá todos los read s en el descriptor de archivo 0 al modo sin bloqueo, si desea usar un descriptor de archivo diferente para poder dejar 0 solo, simplemente use dup para duplicarlo.

De esta manera, puedes mantenerte alejado de poll completamente e implementar ngetc como

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

o mejor aún, una macro

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

Por lo tanto, obtiene una implementación simple para lo que está buscando.

Editar: Si aún le preocupa que el terminal almacene en búfer la entrada, siempre puede cambiar la configuración del terminal, consulte ¿Cómo deshabilitar el almacenamiento en búfer de línea de entrada en xterm desde el programa? para obtener más información sobre cómo hacerlo.

Editar: La razón por la que uno no puede usar fgetc en lugar de read es por la misma razón que usar fgets no funcionará Cuando uno de los FILE * Las funciones IO se ejecutan, lee todos los datos del descriptor de archivo asociado. Pero una vez que eso sucede, poll nunca regresará porque está esperando un descriptor de archivo que siempre está vacío, y lo mismo sucederá con read . Por lo tanto, le sugiero que siga los consejos de la documentación y nunca mezclar flujos (IO usando fgets , fgetc , etc.) y descriptores de archivo (IO usando read , write , etc)


Linux
  1. ¿Archivo equivalente ".bashrc" leído por todos los shells?

  2. `^m` ¿Y cómo deshacerse de él?

  3. ¿Tail lee todo el archivo?

  4. ¿Descomprimir un archivo .gz para obtener un archivo de texto pero obtener un archivo binario?

  5. ¿Cómo leer una variable de un archivo?

Cómo leer archivos línea por línea en Bash

Cómo leer un archivo línea por línea en Bash

Buzón ocupado ¿Leer archivo línea por línea?

¿Obtener archivo creado/hora de creación?

Leer archivo en matriz?

Obtenga la longitud de MP3 en Linux / FreeBSD