[MPlayer-dev-eng] [patch 3/5] Fix stream_write_buffer to make sure all requested bytes are written

Reimar Döffinger Reimar.Doeffinger at gmx.de
Thu Jan 6 17:24:08 CET 2011


On Thu, Jan 06, 2011 at 05:06:33PM +0100, Tobias Diedrich wrote:
> Reimar Döffinger wrote:
> > On Tue, Jan 04, 2011 at 09:35:04PM +0100, Tobias Diedrich wrote:
> > > Index: mplayer-patchset1/stream/stream.c
> > > ===================================================================
> > > --- mplayer-patchset1.orig/stream/stream.c	2010-12-21 20:45:31.157756000 +0100
> > > +++ mplayer-patchset1/stream/stream.c	2010-12-21 20:48:16.229732000 +0100
> > > @@ -324,13 +324,16 @@
> > >  }
> > >  
> > >  int stream_write_buffer(stream_t *s, unsigned char *buf, int len) {
> > > -  int rd;
> > > -  if(!s->write_buffer)
> > > +  int rd = 0;
> > > +  if(!s->write_buffer || len < 0)
> > >      return -1;
> > > -  rd = s->write_buffer(s, buf, len);
> > > -  if(rd < 0)
> > > -    return -1;
> > > -  s->pos += rd;
> > > +  while (rd < len) {
> > > +    int ret = s->write_buffer(s, buf+rd, len-rd);
> > > +    if (ret < 0)
> > > +      return -1;
> > > +    rd += ret;
> > > +    s->pos += ret;
> > > +  }
> > 
> > I think this is a risky place to do it, I'd be more in favour of only
> > adding an assert here and fix all write_buffer implementations to make
> > sure this issue never happens.
> > There is also the issue that if write_buffer ever ends up returning 0
> > this would become an endless loop.
> 
> Something more like this?
> 
> Index: mplayer-patchset1/stream/stream.c
> ===================================================================
> --- mplayer-patchset1.orig/stream/stream.c	2011-01-06 16:16:21.982600000 +0100
> +++ mplayer-patchset1/stream/stream.c	2011-01-06 16:47:28.561260000 +0100
> @@ -28,6 +28,7 @@
>  #endif
>  #include <fcntl.h>
>  #include <strings.h>
> +#include <assert.h>
>  
>  #include "config.h"
>  
> @@ -331,6 +332,7 @@
>    if(rd < 0)
>      return -1;
>    s->pos += rd;
> +  assert(rd == len && "stream_write_buffer(): unexpected short write");
>    return rd;
>  }
>  
> Index: mplayer-patchset1/stream/stream_file.c
> ===================================================================
> --- mplayer-patchset1.orig/stream/stream_file.c	2011-01-06 16:18:13.945756000 +0100
> +++ mplayer-patchset1/stream/stream_file.c	2011-01-06 16:45:35.911193000 +0100
> @@ -52,13 +52,32 @@
>  };
>  
>  static int fill_buffer(stream_t *s, char* buffer, int max_len){
> -  int r = read(s->fd,buffer,max_len);
> -  return (r <= 0) ? -1 : r;
> +  int nr = 0;
> +  int r;
> +  while (nr < max_len) {
> +    r = read(s->fd,buffer,max_len);
> +    if (r < 0)
> +      return -1;
> +    max_len -= r;
> +    buffer += r;
> +    nr += r;
> +    if (r == 0)
> +      break;
> +  }
> +  return nr;
>  }

Have you seen cases where this is necessary for read? The reason I
dislike it is because I think it might interfere with the code that
tries to do a clean exit on CTRL+C.
Also it looks to me like your code allows a 0 return value (which
previously was not possible), IIRC that can cause hangs.


More information about the MPlayer-dev-eng mailing list