GNU/Linux >> Linux Esercitazione >  >> Linux

Non bloccante Ottieni carattere

Stai eseguendo l'IO in modo errato, il manuale POSIX e tutta l'altra documentazione correlata dicono esplicitamente di non mescolare mai l'IO fatto su FILE * se descrittori di file. Hai infranto palesemente questa regola. Questa regola è in vigore perché FILE * s usa il buffering an this significa che dopo una chiamata a fgets non rimarrà nulla per read per ottenere perché fgets ha già letto tutti i dati in attesa in un buffer conservato nel FILE * struttura.

Quindi, poiché non c'è modo di verificare se un metodo ISO C IO si bloccherà, dobbiamo usare solo i descrittori di file.

Poiché sappiamo che STDIN_FILENO è solo il numero 0, possiamo usare

fcntl (0, F_SETFL, O_NONBLOCK);

questo trasformerà tutti i read s sul descrittore di file 0 in modalità non bloccante, se vuoi utilizzare un descrittore di file diverso in modo da poter lasciare solo 0, usa semplicemente dup per duplicarlo.

In questo modo, puoi stare lontano da poll completamente e implementare ngetc come

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

o meglio ancora, una macro

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

In questo modo ottieni una semplice implementazione per ciò che stai cercando.

Modifica: Se sei ancora preoccupato per il terminale che bufferizza l'input, puoi sempre modificare le impostazioni del terminale, vedi Come disabilitare il buffering di riga dell'input in xterm dal programma? per ulteriori informazioni su come eseguire questa operazione.

Modifica: Il motivo per cui non si poteva usare fgetc invece di read è per lo stesso motivo per cui si utilizza fgets non funzionerà. Quando uno dei FILE * funzioni IO viene eseguito, legge tutti i dati dal descrittore di file associato. Ma una volta che ciò accade, poll non tornerà mai perché è in attesa di un descrittore di file che è sempre vuoto, e la stessa cosa accadrà con read . Pertanto, ti suggerisco di seguire i consigli della documentazione e mai mescolare stream (IO usando fgets , fgetc , ecc.) e descrittori di file (IO usando read , write , ecc.)


Linux
  1. Ottieni l'età del file specificato?

  2. Tail legge l'intero file?

  3. Decomprimere un file .gz per ottenere un file di testo ma ottenere un file binario??

  4. Leggi il file nell'array?

  5. Permessi dei file in Linux – Lettura/Scrittura/Esegui

Come leggere i file riga per riga in Bash

Come leggere un file riga per riga in Bash

Casella occupata Leggi file riga per riga?

Ottieni il tempo di creazione/creazione del file??

Come leggere una variabile da un file?

Perché select è usato in Linux