diff options
author | ranma <ranma@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2011-02-10 21:25:38 +0000 |
---|---|---|
committer | Uoti Urpala <uau@mplayer2.org> | 2011-04-12 18:23:43 +0300 |
commit | f8c32fc953320b93c5975c03d3d2f8a5febce498 (patch) | |
tree | 1e028da034c191693e0e90d98d6e501dcbbf0000 | |
parent | 7fe2856fd99fb9211634a3fbf611fb8c04232396 (diff) | |
download | mpv-f8c32fc953320b93c5975c03d3d2f8a5febce498.tar.bz2 mpv-f8c32fc953320b93c5975c03d3d2f8a5febce498.tar.xz |
stream: Make stream_write_buffer() check for short writes
None of the calling sites to stream_write_buffer were checking the
return value to see if all bytes got written (nothing in current code
actually calls it any more after MEncoder was removed).
This was causing (very occasionally) problems with mencoder when using
output pipes AND running under a sandbox or when being straced (ptrace
is the culprit). Theoretically this problem can happen without pipes
or ptrace.
Only stream_file, stream_smb and stream_ffmpeg implement
write_buffer and ffmpeg already handles this internally.
Original patch by Sang-Uok Kum.
Signed-off-by: Tobias Diedrich <ranma@google.com>
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32881 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r-- | stream/stream.c | 2 | ||||
-rw-r--r-- | stream/stream_ffmpeg.c | 1 | ||||
-rw-r--r-- | stream/stream_file.c | 12 | ||||
-rw-r--r-- | stream/stream_smb.c | 12 |
4 files changed, 23 insertions, 4 deletions
diff --git a/stream/stream.c b/stream/stream.c index 6f35252e3d..34b6bc81f9 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -28,6 +28,7 @@ #endif #include <fcntl.h> #include <strings.h> +#include <assert.h> #include "config.h" @@ -326,6 +327,7 @@ int stream_write_buffer(stream_t *s, unsigned char *buf, int len) { if(rd < 0) return -1; s->pos += rd; + assert(rd == len && "stream_write_buffer(): unexpected short write"); return rd; } diff --git a/stream/stream_ffmpeg.c b/stream/stream_ffmpeg.c index e6705883fc..343381afb0 100644 --- a/stream/stream_ffmpeg.c +++ b/stream/stream_ffmpeg.c @@ -34,6 +34,7 @@ static int fill_buffer(stream_t *s, char *buffer, int max_len) static int write_buffer(stream_t *s, char *buffer, int len) { + /* url_write retries internally on short writes and EAGAIN */ int r = url_write(s->priv, buffer, len); return (r <= 0) ? -1 : r; } diff --git a/stream/stream_file.c b/stream/stream_file.c index 22be803fba..6d436cf6f5 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -56,8 +56,16 @@ static int fill_buffer(stream_t *s, char* buffer, int max_len){ } static int write_buffer(stream_t *s, char* buffer, int len) { - int r = write(s->fd,buffer,len); - return (r <= 0) ? -1 : r; + int r; + int wr = 0; + while (wr < len) { + r = write(s->fd,buffer,len); + if (r <= 0) + return -1; + wr += r; + buffer += r; + } + return len; } static int seek(stream_t *s,off_t newpos) { diff --git a/stream/stream_smb.c b/stream/stream_smb.c index 684940749f..714e80fe79 100644 --- a/stream/stream_smb.c +++ b/stream/stream_smb.c @@ -100,8 +100,16 @@ static int fill_buffer(stream_t *s, char* buffer, int max_len){ } static int write_buffer(stream_t *s, char* buffer, int len) { - int r = smbc_write(s->fd,buffer,len); - return (r <= 0) ? -1 : r; + int r; + int wr = 0; + while (wr < len) { + r = smbc_write(s->fd,buffer,len); + if (r <= 0) + return -1; + wr += r; + buffer += r; + } + return len; } static void close_f(stream_t *s){ |