From a049a3240e7e09ac0640a00c8845cd5b97cd5aff Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 14 Oct 2016 17:10:17 -0600 Subject: 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. --- stream/stream_file.c | 8 +++++--- 1 file 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); -- cgit v1.2.3