Portál AbcLinuxu, 12. května 2025 06:17

Dotaz: Neúplný výstup na stdout při O_NONBLOCK stdin

24.3.2008 01:04 martyone | skóre: 18
Neúplný výstup na stdout při O_NONBLOCK stdin
Přečteno: 490×
Odpovědět | Admin
Veselé velikonoce všem! :-)

Můj problém je v ukázce kódu níže – jakmile nastavím stdin flag O_NONBLOCK, následující výstup na stdout se po chvíli zastaví a nehodlá pokračovat. Jakmile flag na stdin zruším, vše opět funguje jak má. Je to standardní chování? Dá se ovlivnit?

Díky za každou reakci


#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>


int main(int argc, char** argv)
{
	int flags, i;
	char foo[]=
		"% 6d 012345678901234567890123456789012345678901234567890123456789\n";

	// vypise se vse
	for (i= 0; i < 10000; i++) printf(foo, i);

	// vypise se
	puts("\nklavesu...");
	fgetc(stdin);

	flags= fcntl(fileno(stdin), F_GETFL, 0);
	fcntl(fileno(stdin), F_SETFL, flags | O_NONBLOCK);

	// NEvypise se vse
	for (i= 0; i < 10000; i++) printf(foo, i);

	// NEvypise se ani tohle
	puts("\n*** KONEC ***");

	fcntl(fileno(stdin), F_SETFL, flags);

	// tohle se uz vypise
	puts("\nklavesu...");
	fgetc(stdin);

	// vypise se vse
	for (i= 0; i < 10000; i++) printf(foo, i);

	// vypise se
	puts("\n*** KONEC ***");

	return (0);
}
Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

Luboš Doležel (Doli) avatar 24.3.2008 01:05 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
Rozbalit Rozbalit vše Re: Neúplný výstup na stdout při O_NONBLOCK stdin
Odpovědět | | Sbalit | Link | Blokovat | Admin
Střílím: nepomohlo by udělat flush na ten stdout?
24.3.2008 19:34 martyone | skóre: 18
Rozbalit Rozbalit vše Re: Neúplný výstup na stdout při O_NONBLOCK stdin
Bohužel ne – to dělám v původním (C++) kódu, kde jsem se s tímto chováním setkal.
24.3.2008 01:37 Andrej Herceg | skóre: 43
Rozbalit Rozbalit vše Re: Neúplný výstup na stdout při O_NONBLOCK stdin
Odpovědět | | Sbalit | Link | Blokovat | Admin
Pravdepodobne je to tento problém Re: msh stdin, fcntl nonblock on stdin by child of child
24.3.2008 19:43 martyone | skóre: 18
Rozbalit Rozbalit vše Re: Neúplný výstup na stdout při O_NONBLOCK stdin
Musím se přiznat, že jsem nějak nenašel souvislost(?) …
24.3.2008 20:48 Andrej Herceg | skóre: 43
Rozbalit Rozbalit vše Re: Neúplný výstup na stdout při O_NONBLOCK stdin
Pôvodne som si myslel, že je problém v tom, že aj rodičovskému procesu sa nastaví stdin na neblokujúci.

Problém je pravdepodobne inde, ale vyzerá to tak, že je to s tým odkazom súvisí. Keď je zariadenie terminál, tak stdin, stdout a stderr je v podstate rovnaký súbor (pravdepodobne je file descriptor iba zduplikovaný) a zmena jedného na NONBLOCK zmení aj ostatné (aspoň ja som to tak pochopil).

Na jednej stránke som našiel citát R. Stevensa z UNIX Network Programming Vol1, p.399
using standard I/O with nonblocking descriptors, a recipe for disaster
(ale celé som to nečítal, takže neviem, v čom je ten problém)

Tento program dokazuje, že zmena stdin na neblokujúci, zmení aj stdout a stderr (aspoň u mňa).
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>


int main(int argc, char** argv)
{
	int flags;

	fprintf(stdout, "stdin: %s\n", (fcntl(fileno(stdin), F_GETFL, 0) & O_NONBLOCK) ? "NONBLOCK" : "BLOCK");
	fprintf(stdout, "stdout: %s\n", (fcntl(fileno(stdout), F_GETFL, 0) & O_NONBLOCK) ? "NONBLOCK" : "BLOCK");
	fprintf(stdout, "stderr: %s\n", (fcntl(fileno(stderr), F_GETFL, 0) & O_NONBLOCK) ? "NONBLOCK" : "BLOCK");

	flags= fcntl(fileno(stdin), F_GETFL, 0);
	fcntl(fileno(stdin), F_SETFL, flags | O_NONBLOCK);

	fprintf(stdout, "stdin: %s\n", (fcntl(fileno(stdin), F_GETFL, 0) & O_NONBLOCK) ? "NONBLOCK" : "BLOCK");
	fprintf(stdout, "stdout: %s\n", (fcntl(fileno(stdout), F_GETFL, 0) & O_NONBLOCK) ? "NONBLOCK" : "BLOCK");
	fprintf(stdout, "stderr: %s\n", (fcntl(fileno(stderr), F_GETFL, 0) & O_NONBLOCK) ? "NONBLOCK" : "BLOCK");

	fcntl(fileno(stdin), F_SETFL, flags);

	return (0);
}
24.3.2008 21:37 martyone | skóre: 18
Rozbalit Rozbalit vše Re: Neúplný výstup na stdout při O_NONBLOCK stdin
Aha, děkuju :-)

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.