GNU/Linux >> Znalost Linux >  >> Linux

Neblokující získat charakter

Provádíte IO nesprávně, manuál POSIX a veškerá další související dokumentace výslovně říká nikdy nesměšovat IO provedené na FILE * s a deskriptory souborů. Toto pravidlo jste velmi očividně porušil. Toto pravidlo platí, protože FILE * s pomocí vyrovnávací paměti a to znamená, že po volání na fgets pro read nezbude nic získat, protože fgets již načetl všechna čekající data do vyrovnávací paměti, která je uložena v FILE * struktura.

Takže protože neexistuje způsob, jak zkontrolovat, zda bude metoda ISO C IO blokována, musíme používat pouze deskriptory souborů.

Protože víme, že STDIN_FILENO je pouze číslo 0, můžeme použít

fcntl (0, F_SETFL, O_NONBLOCK);

toto změní všech read s na deskriptoru souboru 0 do neblokovacího režimu, pokud chcete použít jiný deskriptor souboru, abyste mohli ponechat 0, stačí použít dup jej duplikovat.

Tímto způsobem se můžete držet dál od poll kompletně a implementovat ngetc jako

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

nebo ještě lépe makro

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

Získáte tak jednoduchou implementaci toho, co hledáte.

Upravit: Pokud se stále obáváte, že terminál ukládá vstup do vyrovnávací paměti, můžete kdykoli změnit nastavení terminálu, viz Jak z programu zakázat ukládání do vyrovnávací paměti řádku vstupu v xterm? pro více informací o tom, jak to provést.

Upravit: Důvod, proč nelze použít fgetc místo read je ze stejného důvodu jako použití fgets nebude fungovat. Když jeden z FILE * IO funkce jsou spuštěny, čte všechna data z přidruženého deskriptoru souboru. Ale jakmile se to stane, poll se nikdy nevrátí, protože čeká na deskriptor souboru, který je vždy prázdný, a totéž se stane s read . Navrhuji proto, abyste se řídili radami v dokumentaci a nikdy mix streamů (IO pomocí fgets , fgetc , atd.) a deskriptory souborů (IO pomocí read , write atd.)


Linux
  1. Ekvivalentní soubor „.bashrc“ čtený všemi shelly?

  2. `^m` A jak se toho zbavit?

  3. Čte Tail celý soubor?

  1. Rozbalením souboru .gz získáte textový soubor, ale získáte binární soubor?

  2. Číst soubor do pole?

  3. Oprávnění souborů v Linuxu – čtení/zápis/spouštění

  1. Get Age Of Given File?

  2. Získejte nejnovější soubor v adresáři v systému Linux

  3. Získejte délku MP3 v Linuxu / FreeBSD