summaryrefslogtreecommitdiffstats
path: root/stream
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-02-20 19:58:24 +0100
committerDiogo Franco (Kovensky) <diogomfranco@gmail.com>2015-02-21 20:49:11 +0900
commitde4727371638afb7cfb5d08bf885a1d91029ceae (patch)
treecc6b47c6266814fae969e5230dc2d916c3a1a466 /stream
parent7ace4f2115db999105c31714ee7aa1b0099c6866 (diff)
downloadmpv-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.c37
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;