Quoting Frank Schmirler <vdr@xxxxxxxxxxxx>: > Hi, > > I would like to raise an issue with SVDRP. When the client doesn't send QUIT > but simply closes the connection, VDR happily ignores the EOF returned by > read. The socket will remain in state CLOSE_WAIT until it's finally closed due > to the SVDRP timeout. In the meantime the SVDRP port remains blocked for other > clients. > > I think the way it was implemented until vdr-1.2.1 was correct. Then a broken > pipe problem was reported > (http://linvdr.org/mailinglists/vdr/2003/07/msg00254.html) and the > implementation of cSVDRP::Process was modified to the way which is still used > in 1.4.1. > > The way it is implemented now is IMHO broken. So I would suggest to return to > the way it was initially implemented or - if someone has an idea where broken > pipes might come from - find a better way to fix it. Maybe the broken pipes at > that time even had a totally different cause? > > Code <= 1.2.1: > while (file.Ready(false)) { > unsigned char c; > int r = safe_read(file, &c, 1); > if (r > 0) { > ... > } > else if (r <= 0) { > isyslog("lost connection to SVDRP client"); > Close(); > } > } read() returning 0 means eof. So above code should be the correct one (tm) . But safe_read() has to be modified, as socket is non-blocking (oldflags |= O_NONBLOCK;), EAGAIN should be handled too: ssize_t safe_read(int filedes, void *buffer, size_t size) { for (;;) { ssize_t p = read(filedes, buffer, size); if (p < 0) { if (errno == EINTR) { dsyslog("EINTR while reading from file handle %d - retrying", filedes); continue; } if (errno == EAGAIN) { dsyslog("EAGAIN while reading from file handle %d - retrying", filedes); usleep (10000); continue; } } return p; } } > > Code >= 1.2.4 > while (file.Ready(false)) { > unsigned char c; > int r = safe_read(file, &c, 1); > if (r > 0) { > ... > } > else if (r < 0) { > isyslog("lost connection to SVDRP client"); > Close(); > } > else > break; > } > Stefan Lucke