select() a pojmenovane fifo

Martin Kezlinek kez na fel.cvut.cz
Pondělí Červenec 3 00:32:09 CEST 2006


> Zdravim
> 
> mam problem s chovanim select() pro sledovani pojmenovane fifo.
> 
> program velmi zjednodusene vypada takto:
> 
> // --------------------------------------------
> int fifo_fd, rc;
> FILE *fifo_file;
> struct timeval timeout;
> fd_set fdset;
> 
> int main(int argc, char **argv)
> {
> fifo_fd = open("fifo", O_RDONLY | O_NONBLOCK);
> fifo_file = fdopen(fifo_fd, "r");
> while (1) {
> FD_ZERO(&fdset);
> FD_SET(fifo_fd, &set);
> timeout.tv_sec = 1;
> timeout.tv_usec = 0;
> rc = select(fifo_fd + 1, &fdset, NULL, NULL, &timeout);
> if (rc > 0) {
> // zpracuj data z fifo_file
> } else if (rc < 0) {
> // neco je spatne - chcipni 
> }
> // proved neco
> }
> }
> // ---------------------------------------------
> 
> 
> Moje potiz spociva v tom, ze 
> - dokud do fifo nic nepise, tak select() spravne ceka timeout a pak 
>  vrati 0 ...
> 
> - pokud ji neco otevre pro zapis, tak take ceka a pracuje podle
>  ocekavani (jsou data - navrat s 1, nesou data po timeout vraci 0)
> 
> - pokud ji to neco zavre, tak 
>  - nedostanu SIGPIPE
>  - select vraci okamzite 1 pri kazdem pruchodu smyckou - to me stve
>    nejvic
>  - pripadne cteni z fifo_file precte 0 byte a skonci s EOF
> 
> distribuce debian unstable, jadro vlastni vanilla 2.6.16.20 + swsusp2,
> libc 2.3.6-15
> 
> Predpokladam, ze se me tyka odstavec na konci manualu select()
> 
> Under Linux, select() may report a socket file descriptor as "ready for
> reading",  while  nevertheless a subsequent read blocks. This could for
> example happen when data has arrived but  upon examination  has  wrong
> checksum  and is discarded. There may be other circumstances in which a
> file descriptor is spuriously reported as ready.  Thus it may be  safer
> to use O_NONBLOCK on sockets that should not block.
> 
> Resil to nekdo? Tusim, jak to obejit, ale nejake korektni reseni by se
> hodilo.
> Nebo jsem uplne vedle a chova se to jak ma?
> 
> 
> S pozdravem 
> 
> Petr Janda

A nepomuze pomoci FD_ISSET  se dotazat  na  stav co se vlastne stalo?
btw:  FD_SET(fifo_fd, &set); ..nema tam byt  &fdset ?

Martin Kezlinek


Další informace o konferenci Linux