diff options
author | wm4 <wm4@nowhere> | 2015-02-20 19:58:24 +0100 |
---|---|---|
committer | Diogo Franco (Kovensky) <diogomfranco@gmail.com> | 2015-02-21 20:49:11 +0900 |
commit | de4727371638afb7cfb5d08bf885a1d91029ceae (patch) | |
tree | cc6b47c6266814fae969e5230dc2d916c3a1a466 /stream | |
parent | 7ace4f2115db999105c31714ee7aa1b0099c6866 (diff) | |
download | mpv-de4727371638afb7cfb5d08bf885a1d91029ceae.tar.bz2 mpv-de4727371638afb7cfb5d08bf885a1d91029ceae.tar.xz |
stream_file: open pipes non-blocking
Now the player can actually be quit if a pipe was opened, but nobody is
writing to it.
(cherry picked from commit 3c9344a1a9de335925b81058b7699fccd187626b)
Diffstat (limited to 'stream')
-rw-r--r-- | stream/stream_file.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/stream/stream_file.c b/stream/stream_file.c index a78cda1f89..5ce346b706 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -27,6 +27,10 @@ #include <unistd.h> #include <errno.h> +#ifndef __MINGW32__ +#include <poll.h> +#endif + #include "osdep/io.h" #include "common/common.h" @@ -57,11 +61,24 @@ struct priv { int fd; bool close; + bool regular; }; static int fill_buffer(stream_t *s, char *buffer, int max_len) { struct priv *p = s->priv; +#ifndef __MINGW32__ + if (!p->regular) { + int c = s->cancel ? mp_cancel_get_fd(s->cancel) : -1; + struct pollfd fds[2] = { + {.fd = p->fd, .events = POLLIN}, + {.fd = c, .events = POLLIN}, + }; + poll(fds, c >= 0 ? 2 : 1, -1); + if (fds[1].revents & POLLIN) + return -1; + } +#endif int r = read(p->fd, buffer, max_len); return (r <= 0) ? -1 : r; } @@ -250,6 +267,8 @@ static int open_f(stream_t *stream) mode_t openmode = S_IRUSR | S_IWUSR; #ifndef __MINGW32__ openmode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + if (!write) + m |= O_NONBLOCK; #endif fd = open(filename, m | O_BINARY, openmode); if (fd < 0) { @@ -258,10 +277,20 @@ static int open_f(stream_t *stream) return STREAM_ERROR; } struct stat st; - if (fstat(fd, &st) == 0 && S_ISDIR(st.st_mode)) { - MP_ERR(stream, "File is a directory: '%s'\n", filename); - close(fd); - return STREAM_ERROR; + if (fstat(fd, &st) == 0) { + if (S_ISDIR(st.st_mode)) { + MP_ERR(stream, "File is a directory: '%s'\n", filename); + close(fd); + return STREAM_ERROR; + } +#ifndef __MINGW32__ + if (S_ISREG(st.st_mode)) { + priv->regular = true; + // O_NONBLOCK has weird semantics on file locks; remove it. + int val = fcntl(fd, F_GETFL) & ~(unsigned)O_NONBLOCK; + fcntl(fd, F_SETFL, val); + } +#endif } priv->fd = fd; priv->close = true; |