diff options
author | wm4 <wm4@nowhere> | 2016-10-14 17:10:17 -0600 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-10-14 17:19:47 -0600 |
commit | a049a3240e7e09ac0640a00c8845cd5b97cd5aff (patch) | |
tree | 1e8b416469c136c63bd1f25e358aad242ff2609a | |
parent | 0af8811b15f25304ef04013b630ac324011144c0 (diff) | |
download | mpv-a049a3240e7e09ac0640a00c8845cd5b97cd5aff.tar.bz2 mpv-a049a3240e7e09ac0640a00c8845cd5b97cd5aff.tar.xz |
stream_file: don't use poll() on directories
POSIX leaves poll() behavior on directories unspecified. While on
Linux, it seems to behave the same way as regular files (always
return immediately), this is not guaranteed. At least with OSX
10.12, it seems to wait, which essentially means that opening
directories will "hang".
Fixes #3530 and #3649.
-rw-r--r-- | stream/stream_file.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/stream/stream_file.c b/stream/stream_file.c index ce9f9d9739..5d5925ac7c 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -60,14 +60,14 @@ struct priv { int fd; bool close; - bool regular; + bool use_poll; }; static int fill_buffer(stream_t *s, char *buffer, int max_len) { struct priv *p = s->priv; #ifndef __MINGW32__ - if (!p->regular) { + if (p->use_poll) { int c = s->cancel ? mp_cancel_get_fd(s->cancel) : -1; struct pollfd fds[2] = { {.fd = p->fd, .events = POLLIN}, @@ -269,6 +269,7 @@ static int open_f(stream_t *stream) openmode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; if (!write) m |= O_NONBLOCK; + p->use_poll = true; #endif p->fd = open(filename, m | O_BINARY, openmode); if (p->fd < 0) { @@ -279,13 +280,14 @@ static int open_f(stream_t *stream) struct stat st; if (fstat(p->fd, &st) == 0) { if (S_ISDIR(st.st_mode)) { + p->use_poll = false; stream->type = STREAMTYPE_DIR; stream->allow_caching = false; MP_INFO(stream, "This is a directory - adding to playlist.\n"); } #ifndef __MINGW32__ if (S_ISREG(st.st_mode)) { - p->regular = true; + p->use_poll = false; // O_NONBLOCK has weird semantics on file locks; remove it. int val = fcntl(p->fd, F_GETFL) & ~(unsigned)O_NONBLOCK; fcntl(p->fd, F_SETFL, val); |