From bb7a485c0932375b888a61966970696c06851a15 Mon Sep 17 00:00:00 2001 From: Mohammad AlSaleh Date: Thu, 4 Apr 2024 10:23:00 +0300 Subject: [PATCH] stream: don't try to read from all-sparse/no-data files ``` dd if=/dev/zero of=/tmp/10g.empty bs=1 seek=10G count=0 dd if=/dev/zero of=/tmp/10m.empty bs=1 seek=10M count=0 time mpv /tmp/10{g,m}.empty ``` I keep files with the name format `${name}-${hash}.${ext}.empty` around, where the original is removed, and a sparse file with the size of the original is created instead. A lot of time is wasted on such files when going through playlists/directories that include some of them. This admittedly may not be that common of a use-case. Signed-off-by: Mohammad AlSaleh --- meson.build | 3 +++ stream/stream_file.c | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/meson.build b/meson.build index b0283c87b3..20b5af2d81 100644 --- a/meson.build +++ b/meson.build @@ -438,6 +438,9 @@ endif features += {'ppoll': cc.has_function('ppoll', args: '-D_GNU_SOURCE', prefix: '#include ')} +features += {'seek-data': cc.has_header_symbol('errno.h', 'ENXIO') and + cc.has_header_symbol('unistd.h', 'SEEK_DATA', args: '-D_GNU_SOURCE')} + cd_devices = { 'windows': 'D:', 'cygwin': 'D:', diff --git a/stream/stream_file.c b/stream/stream_file.c index 1744fc13a4..0a6a697ff6 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -358,6 +358,17 @@ static int open_f(stream_t *stream, const struct stream_open_args *args) setmode(p->fd, O_BINARY); #endif +#if HAVE_SEEK_DATA + if (stream->mode == STREAM_READ) { + off_t first_data = lseek(p->fd, 0, SEEK_DATA); + if (first_data == (off_t)-1 && errno == ENXIO) { + MP_ERR(stream, "File is empty or all sparse (has no data).\n"); + s_close(stream); + return STREAM_ERROR; + } + } +#endif + off_t len = lseek(p->fd, 0, SEEK_END); lseek(p->fd, 0, SEEK_SET); if (len != (off_t)-1) {