SVDRP ignores EOF (clientside close)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Big List of Linux Books]     [Fedora Users]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux