summaryrefslogtreecommitdiffstats
path: root/stream/stream_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'stream/stream_file.c')
-rw-r--r--stream/stream_file.c55
1 files changed, 45 insertions, 10 deletions
diff --git a/stream/stream_file.c b/stream/stream_file.c
index 4895a8301b..ff53d35546 100644
--- a/stream/stream_file.c
+++ b/stream/stream_file.c
@@ -23,10 +23,9 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <unistd.h>
#include <errno.h>
-#ifndef __MINGW32__
+#ifndef _WIN32
#include <poll.h>
#endif
@@ -50,9 +49,37 @@
#ifdef _WIN32
#include <windows.h>
+#include <winioctl.h>
#include <winternl.h>
#include <io.h>
+#ifdef _MSC_VER
+// Those are defined only in Windows DDK
+typedef struct _FILE_FS_DEVICE_INFORMATION {
+ DEVICE_TYPE DeviceType;
+ ULONG Characteristics;
+} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
+
+typedef enum _FSINFOCLASS {
+ FileFsVolumeInformation = 1,
+ FileFsLabelInformation, // 2
+ FileFsSizeInformation, // 3
+ FileFsDeviceInformation, // 4
+ FileFsAttributeInformation, // 5
+ FileFsControlInformation, // 6
+ FileFsFullSizeInformation, // 7
+ FileFsObjectIdInformation, // 8
+ FileFsDriverPathInformation, // 9
+ FileFsVolumeFlagsInformation, // 10
+ FileFsSectorSizeInformation, // 11
+ FileFsDataCopyInformation, // 12
+ FileFsMetadataSizeInformation, // 13
+ FileFsFullSizeInformationEx, // 14
+ FileFsGuidInformation, // 15
+ FileFsMaximumInformation
+} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
+#endif
+
#ifndef FILE_REMOTE_DEVICE
#define FILE_REMOTE_DEVICE (0x10)
#endif
@@ -89,7 +116,7 @@ static int fill_buffer(stream_t *s, void *buffer, int max_len)
{
struct priv *p = s->priv;
-#ifndef __MINGW32__
+#ifndef _WIN32
if (p->use_poll) {
int c = mp_cancel_get_fd(p->cancel);
struct pollfd fds[2] = {
@@ -272,10 +299,16 @@ static int open_f(stream_t *stream, const struct stream_open_args *args)
if (strncmp(url, "fd://", 5) == 0 || is_fdclose) {
char *begin = strstr(stream->url, "://") + 3, *end = NULL;
p->fd = strtol(begin, &end, 0);
- if (!end || end == begin || end[0]) {
- MP_ERR(stream, "Invalid FD: %s\n", stream->url);
+ if (!end || end == begin || end[0] || p->fd < 0) {
+ MP_ERR(stream, "Invalid FD number: %s\n", stream->url);
+ return STREAM_ERROR;
+ }
+#ifdef F_SETFD
+ if (fcntl(p->fd, F_GETFD) == -1) {
+ MP_ERR(stream, "Invalid FD: %d\n", p->fd);
return STREAM_ERROR;
}
+#endif
if (is_fdclose)
p->close = true;
} else if (!strict_fs && !strcmp(filename, "-")) {
@@ -306,24 +339,26 @@ static int open_f(stream_t *stream, const struct stream_open_args *args)
}
struct stat st;
+ bool is_sock_or_fifo = false;
if (fstat(p->fd, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
stream->is_directory = true;
- if (!(args->flags & STREAM_LESS_NOISE))
- MP_INFO(stream, "This is a directory - adding to playlist.\n");
} else if (S_ISREG(st.st_mode)) {
p->regular_file = true;
-#ifndef __MINGW32__
+#ifndef _WIN32
// 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);
#endif
} else {
+#ifndef __MINGW32__
+ is_sock_or_fifo = S_ISSOCK(st.st_mode) || S_ISFIFO(st.st_mode);
+#endif
p->use_poll = true;
}
}
-#ifdef __MINGW32__
+#ifdef _WIN32
setmode(p->fd, O_BINARY);
#endif
@@ -340,7 +375,7 @@ static int open_f(stream_t *stream, const struct stream_open_args *args)
stream->get_size = get_size;
stream->close = s_close;
- if (check_stream_network(p->fd)) {
+ if (is_sock_or_fifo || check_stream_network(p->fd)) {
stream->streaming = true;
#if HAVE_COCOA
if (fcntl(p->fd, F_RDAHEAD, 0) < 0) {