From 43e230f543c16c1b46ed3a892c8732b7a801e941 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 16:31:10 +0200 Subject: [PATCH 01/17] decoder/ffmpeg: remove "rtsp://" from the list of supported protocols FFmpeg implements RTSP as a demuxer, not as a protocol handler. Thus, avio_open() cannot be used, and our input plugin cannot handle RTSP. Closes https://github.com/MusicPlayerDaemon/MPD/issues/930 --- NEWS | 1 + src/input/plugins/FfmpegInputPlugin.cxx | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 207c28226..165bdb942 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ ver 0.21.26 (not yet released) - iso9660: support seeking - zzip: fix crash on corrupt ZIP file * decoder + - ffmpeg: remove "rtsp://" from the list of supported protocols - sndfile: fix lost samples at end of file ver 0.21.25 (2020/07/06) diff --git a/src/input/plugins/FfmpegInputPlugin.cxx b/src/input/plugins/FfmpegInputPlugin.cxx index 09597e774..3cb8bd151 100644 --- a/src/input/plugins/FfmpegInputPlugin.cxx +++ b/src/input/plugins/FfmpegInputPlugin.cxx @@ -140,7 +140,6 @@ FfmpegInputStream::Seek(offset_type new_offset) static constexpr const char *ffmpeg_prefixes[] = { "gopher://", "rtp://", - "rtsp://", "rtmp://", "rtmpt://", "rtmps://", From e10b867fe6ffbac1ac37a333dbd69597e4fc9f03 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 16:33:01 +0200 Subject: [PATCH 02/17] decoder/ffmpeg: add "hls+http://" to the list of supported protocols --- NEWS | 1 + src/input/plugins/FfmpegInputPlugin.cxx | 2 ++ 2 files changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 165bdb942..f00ba7a79 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ ver 0.21.26 (not yet released) - zzip: fix crash on corrupt ZIP file * decoder - ffmpeg: remove "rtsp://" from the list of supported protocols + - ffmpeg: add "hls+http://" to the list of supported protocols - sndfile: fix lost samples at end of file ver 0.21.25 (2020/07/06) diff --git a/src/input/plugins/FfmpegInputPlugin.cxx b/src/input/plugins/FfmpegInputPlugin.cxx index 3cb8bd151..9bdaa9373 100644 --- a/src/input/plugins/FfmpegInputPlugin.cxx +++ b/src/input/plugins/FfmpegInputPlugin.cxx @@ -139,6 +139,8 @@ FfmpegInputStream::Seek(offset_type new_offset) static constexpr const char *ffmpeg_prefixes[] = { "gopher://", + "hls+http://", + "hls+https://", "rtp://", "rtmp://", "rtmpt://", From c61a3b8d13e9b7fd2b0ef5f64a2dd9745fdc0306 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 17:16:23 +0200 Subject: [PATCH 03/17] LogBackend: change the initial log_threshold to DEFAULT The log levels have always been very confusing (and badly named), but this was most confusing: if there's a log level called "default", why is it not the default? Closes https://github.com/MusicPlayerDaemon/MPD/issues/926 --- NEWS | 1 + src/LogBackend.cxx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f00ba7a79..82e0d55e5 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,7 @@ ver 0.21.26 (not yet released) - ffmpeg: remove "rtsp://" from the list of supported protocols - ffmpeg: add "hls+http://" to the list of supported protocols - sndfile: fix lost samples at end of file +* the default log_level is "default", not "info" ver 0.21.25 (2020/07/06) * protocol: diff --git a/src/LogBackend.cxx b/src/LogBackend.cxx index f7760ee23..676ecf3cb 100644 --- a/src/LogBackend.cxx +++ b/src/LogBackend.cxx @@ -61,7 +61,7 @@ ToAndroidLogLevel(LogLevel log_level) noexcept #else -static LogLevel log_threshold = LogLevel::INFO; +static LogLevel log_threshold = LogLevel::DEFAULT; static bool enable_timestamp; From d9d511f33ef6ed358e844e834db1706f40588cb7 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:11:50 +0200 Subject: [PATCH 04/17] player/Thread: update function name in comment --- src/player/Thread.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx index 286855136..1766164e1 100644 --- a/src/player/Thread.cxx +++ b/src/player/Thread.cxx @@ -440,7 +440,7 @@ Player::ActivateDecoder() noexcept pc.audio_format.Clear(); { - /* call syncPlaylistWithQueue() in the main thread */ + /* call playlist::SyncWithPlayer() in the main thread */ const ScopeUnlock unlock(pc.mutex); pc.listener.OnPlayerSync(); } From e29c06b718301562eebf2fa165f4017eae9407dc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:12:51 +0200 Subject: [PATCH 05/17] player/Thread: add another code comment explaining OnPlayerSync() --- src/player/Thread.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx index 1766164e1..9f3fe23a1 100644 --- a/src/player/Thread.cxx +++ b/src/player/Thread.cxx @@ -1169,6 +1169,11 @@ try { { const ScopeUnlock unlock(mutex); do_play(*this, dc, buffer); + + /* give the main thread a chance to + queue another song, just in case + we've stopped playback + spuriously */ listener.OnPlayerSync(); } From 32f4f15831573c94e19fbd14f3c77d80a4408f2c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:09:03 +0200 Subject: [PATCH 06/17] player/Thread: call OnPlayerSync() in SeekDecoder() This fixes a spurious "single" mode bug which occurs when using "play" or "seek" to start playback on the song that is currently paused: in that case, the main thread never queues the next song, and at the end of the song, the player thread exits Run(), stopping playback, and after that, the main thread starts the next song without considering "single" mode. By calling OnPlayerSync(), we ensure that the main thread gets a chance to queue the next song before the player thread exits the Run() loop. Closes https://github.com/MusicPlayerDaemon/MPD/issues/850 --- NEWS | 1 + src/player/Thread.cxx | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 82e0d55e5..340a35741 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,7 @@ ver 0.21.26 (not yet released) - ffmpeg: remove "rtsp://" from the list of supported protocols - ffmpeg: add "hls+http://" to the list of supported protocols - sndfile: fix lost samples at end of file +* fix "single" mode bug after resuming playback * the default log_level is "default", not "info" ver 0.21.25 (2020/07/06) diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx index 9f3fe23a1..6c7bab00d 100644 --- a/src/player/Thread.cxx +++ b/src/player/Thread.cxx @@ -681,6 +681,12 @@ Player::SeekDecoder() noexcept /* re-fill the buffer after seeking */ buffering = true; + { + /* call syncPlaylistWithQueue() in the main thread */ + const ScopeUnlock unlock(pc.mutex); + pc.listener.OnPlayerSync(); + } + return true; } From e81bb5d8f18c3d4de9a591cd85cd33a2a47692a6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:38:29 +0200 Subject: [PATCH 07/17] db/update/Inotify*: include cleanup --- src/db/update/InotifySource.cxx | 8 ++++---- src/db/update/InotifySource.hxx | 3 --- src/db/update/InotifyUpdate.cxx | 10 +++++----- src/db/update/InotifyUpdate.hxx | 2 -- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/db/update/InotifySource.cxx b/src/db/update/InotifySource.cxx index e0509715c..ac3c931ff 100644 --- a/src/db/update/InotifySource.cxx +++ b/src/db/update/InotifySource.cxx @@ -24,11 +24,11 @@ #include "system/Error.hxx" #include "Log.hxx" +#include +#include +#include + #include -#include -#include -#include -#include bool InotifySource::OnSocketReady(gcc_unused unsigned flags) noexcept diff --git a/src/db/update/InotifySource.hxx b/src/db/update/InotifySource.hxx index dadefec90..43225df56 100644 --- a/src/db/update/InotifySource.hxx +++ b/src/db/update/InotifySource.hxx @@ -21,9 +21,6 @@ #define MPD_INOTIFY_SOURCE_HXX #include "event/SocketMonitor.hxx" -#include "util/Compiler.h" - -class FileDescriptor; typedef void (*mpd_inotify_callback_t)(int wd, unsigned mask, const char *name, void *ctx); diff --git a/src/db/update/InotifyUpdate.cxx b/src/db/update/InotifyUpdate.cxx index 0885aa435..b19961ade 100644 --- a/src/db/update/InotifyUpdate.cxx +++ b/src/db/update/InotifyUpdate.cxx @@ -27,13 +27,13 @@ #include "fs/Traits.hxx" #include "Log.hxx" -#include -#include +#include +#include #include +#include +#include -#include #include -#include #include static constexpr unsigned IN_MASK = @@ -148,7 +148,7 @@ WatchDirectory::GetUriFS() const noexcept static bool skip_path(const char *path) { return PathTraitsFS::IsSpecialFilename(path) || - strchr(path, '\n') != nullptr; + std::strchr(path, '\n') != nullptr; } static void diff --git a/src/db/update/InotifyUpdate.hxx b/src/db/update/InotifyUpdate.hxx index 8f9f7d99b..47fda5e66 100644 --- a/src/db/update/InotifyUpdate.hxx +++ b/src/db/update/InotifyUpdate.hxx @@ -20,8 +20,6 @@ #ifndef MPD_INOTIFY_UPDATE_HXX #define MPD_INOTIFY_UPDATE_HXX -#include "util/Compiler.h" - class EventLoop; class Storage; class UpdateService; From fc3861b4217e0ee76ecaa64ddaaed22c936c78cc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 1 Sep 2019 13:58:22 +0200 Subject: [PATCH 08/17] db/update/InotifyQueue: add `noexcept` --- src/db/update/InotifyQueue.cxx | 2 +- src/db/update/InotifyQueue.hxx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/db/update/InotifyQueue.cxx b/src/db/update/InotifyQueue.cxx index 84b576b2e..35269cedd 100644 --- a/src/db/update/InotifyQueue.cxx +++ b/src/db/update/InotifyQueue.cxx @@ -79,7 +79,7 @@ path_in(const char *path, const char *possible_parent) noexcept } void -InotifyQueue::Enqueue(const char *uri_utf8) +InotifyQueue::Enqueue(const char *uri_utf8) noexcept { delay_event.Schedule(INOTIFY_UPDATE_DELAY); diff --git a/src/db/update/InotifyQueue.hxx b/src/db/update/InotifyQueue.hxx index bb6159019..9190cbc18 100644 --- a/src/db/update/InotifyQueue.hxx +++ b/src/db/update/InotifyQueue.hxx @@ -35,11 +35,11 @@ class InotifyQueue final { TimerEvent delay_event; public: - InotifyQueue(EventLoop &_loop, UpdateService &_update) + InotifyQueue(EventLoop &_loop, UpdateService &_update) noexcept :update(_update), delay_event(_loop, BIND_THIS_METHOD(OnDelay)) {} - void Enqueue(const char *uri_utf8); + void Enqueue(const char *uri_utf8) noexcept; private: void OnDelay() noexcept; From a8e23c414047064048a0cabfe0c94f772fdaea57 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 1 Sep 2019 13:58:45 +0200 Subject: [PATCH 09/17] db/update/InotifySource: add `noexcept` --- src/db/update/InotifySource.cxx | 2 +- src/db/update/InotifySource.hxx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/db/update/InotifySource.cxx b/src/db/update/InotifySource.cxx index ac3c931ff..e8b61e874 100644 --- a/src/db/update/InotifySource.cxx +++ b/src/db/update/InotifySource.cxx @@ -98,7 +98,7 @@ InotifySource::Add(const char *path_fs, unsigned mask) } void -InotifySource::Remove(unsigned wd) +InotifySource::Remove(unsigned wd) noexcept { auto ifd = GetSocket().ToFileDescriptor(); int ret = inotify_rm_watch(ifd.Get(), wd); diff --git a/src/db/update/InotifySource.hxx b/src/db/update/InotifySource.hxx index 43225df56..846d44682 100644 --- a/src/db/update/InotifySource.hxx +++ b/src/db/update/InotifySource.hxx @@ -42,7 +42,7 @@ public: InotifySource(EventLoop &_loop, mpd_inotify_callback_t callback, void *ctx); - ~InotifySource() { + ~InotifySource() noexcept { Close(); } @@ -60,7 +60,7 @@ public: * * @param wd the watch descriptor returned by mpd_inotify_source_add() */ - void Remove(unsigned wd); + void Remove(unsigned wd) noexcept; private: bool OnSocketReady(unsigned flags) noexcept override; From b18fc3a8d0ae115d6f37d765925aaf441646c76c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:40:26 +0200 Subject: [PATCH 10/17] db/update/InotifySource: use `auto` --- src/db/update/InotifySource.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/update/InotifySource.cxx b/src/db/update/InotifySource.cxx index e8b61e874..670f76e32 100644 --- a/src/db/update/InotifySource.cxx +++ b/src/db/update/InotifySource.cxx @@ -48,7 +48,7 @@ InotifySource::OnSocketReady(gcc_unused unsigned flags) noexcept while (true) { const size_t remaining = end - p; - const struct inotify_event *event = + const auto *event = (const struct inotify_event *)p; if (remaining < sizeof(*event) || remaining < sizeof(*event) + event->len) From e907ff43aec3690858d0a9174ff79e884edd7b89 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:57:37 +0200 Subject: [PATCH 11/17] command/file, storage/{nfs,smbclient}: use PathTraitsFS::IsSpecialFilename() Eliminate some duplicate code. --- src/command/FileCommands.cxx | 4 +--- src/storage/plugins/NfsStorage.cxx | 4 +--- src/storage/plugins/SmbclientStorage.cxx | 6 ++---- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/command/FileCommands.cxx b/src/command/FileCommands.cxx index 448da2caf..29685713d 100644 --- a/src/command/FileCommands.cxx +++ b/src/command/FileCommands.cxx @@ -50,9 +50,7 @@ gcc_pure static bool SkipNameFS(PathTraitsFS::const_pointer_type name_fs) noexcept { - return name_fs[0] == '.' && - (name_fs[1] == 0 || - (name_fs[1] == '.' && name_fs[2] == 0)); + return PathTraitsFS::IsSpecialFilename(name_fs); } gcc_pure diff --git a/src/storage/plugins/NfsStorage.cxx b/src/storage/plugins/NfsStorage.cxx index e485fd8e4..e7d125a81 100644 --- a/src/storage/plugins/NfsStorage.cxx +++ b/src/storage/plugins/NfsStorage.cxx @@ -307,9 +307,7 @@ gcc_pure static bool SkipNameFS(PathTraitsFS::const_pointer_type name) noexcept { - return name[0] == '.' && - (name[1] == 0 || - (name[1] == '.' && name[2] == 0)); + return PathTraitsFS::IsSpecialFilename(name); } static void diff --git a/src/storage/plugins/SmbclientStorage.cxx b/src/storage/plugins/SmbclientStorage.cxx index 0324bf219..ff6262f58 100644 --- a/src/storage/plugins/SmbclientStorage.cxx +++ b/src/storage/plugins/SmbclientStorage.cxx @@ -144,11 +144,9 @@ SmbclientStorage::OpenDirectory(const char *uri_utf8) gcc_pure static bool -SkipNameFS(const char *name) noexcept +SkipNameFS(PathTraitsFS::const_pointer_type name) noexcept { - return name[0] == '.' && - (name[1] == 0 || - (name[1] == '.' && name[2] == 0)); + return PathTraitsFS::IsSpecialFilename(name); } SmbclientDirectoryReader::~SmbclientDirectoryReader() From 5b22d27cbb00d9be5ff9393b26d55577194a8079 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:48:01 +0200 Subject: [PATCH 12/17] db/update/InotifyUpdate: remove commented log call --- src/db/update/InotifyUpdate.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/db/update/InotifyUpdate.cxx b/src/db/update/InotifyUpdate.cxx index b19961ade..cf917b7cb 100644 --- a/src/db/update/InotifyUpdate.cxx +++ b/src/db/update/InotifyUpdate.cxx @@ -240,8 +240,6 @@ mpd_inotify_callback(int wd, unsigned mask, { WatchDirectory *directory; - /*FormatDebug(inotify_domain, "wd=%d mask=0x%x name='%s'", wd, mask, name);*/ - directory = tree_find_watch_directory(wd); if (directory == nullptr) return; From bf97ebf89ff442de455b1d17d9e473f6abcc7be3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:48:27 +0200 Subject: [PATCH 13/17] db/update/InotifyUpdate: convert pointer to reference --- src/db/update/InotifyUpdate.cxx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/db/update/InotifyUpdate.cxx b/src/db/update/InotifyUpdate.cxx index cf917b7cb..de0e4355e 100644 --- a/src/db/update/InotifyUpdate.cxx +++ b/src/db/update/InotifyUpdate.cxx @@ -152,13 +152,12 @@ static bool skip_path(const char *path) } static void -recursive_watch_subdirectories(WatchDirectory *directory, +recursive_watch_subdirectories(WatchDirectory &parent, const AllocatedPath &path_fs, unsigned depth) { DIR *dir; struct dirent *ent; - assert(directory != nullptr); assert(depth <= inotify_max_depth); assert(!path_fs.IsNull()); @@ -209,14 +208,14 @@ recursive_watch_subdirectories(WatchDirectory *directory, /* already being watched */ continue; - directory->children.emplace_front(directory, - name_fs, - ret); - child = &directory->children.front(); + parent.children.emplace_front(&parent, + name_fs, + ret); + child = &parent.children.front(); tree_add_watch_directory(child); - recursive_watch_subdirectories(child, child_path_fs, depth); + recursive_watch_subdirectories(*child, child_path_fs, depth); } closedir(dir); @@ -261,7 +260,7 @@ mpd_inotify_callback(int wd, unsigned mask, ? root : (root / uri_fs); - recursive_watch_subdirectories(directory, path_fs, + recursive_watch_subdirectories(*directory, path_fs, directory->GetDepth()); } @@ -320,7 +319,7 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update, tree_add_watch_directory(inotify_root); - recursive_watch_subdirectories(inotify_root, path, 0); + recursive_watch_subdirectories(*inotify_root, path, 0); inotify_queue = new InotifyQueue(loop, update); From 83f9d2a9630b8122b94c9535acd7c0ad3bc7085e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:51:18 +0200 Subject: [PATCH 14/17] db/update/InotifyUpdate: use class DirectoryReader --- src/db/update/InotifyUpdate.cxx | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/db/update/InotifyUpdate.cxx b/src/db/update/InotifyUpdate.cxx index de0e4355e..c513d8fab 100644 --- a/src/db/update/InotifyUpdate.cxx +++ b/src/db/update/InotifyUpdate.cxx @@ -23,8 +23,10 @@ #include "InotifyDomain.hxx" #include "storage/StorageInterface.hxx" #include "fs/AllocatedPath.hxx" +#include "fs/DirectoryReader.hxx" #include "fs/FileInfo.hxx" #include "fs/Traits.hxx" +#include "util/Compiler.h" #include "Log.hxx" #include @@ -145,19 +147,18 @@ WatchDirectory::GetUriFS() const noexcept } /* we don't look at "." / ".." nor files with newlines in their name */ -static bool skip_path(const char *path) +gcc_pure +static bool +SkipFilename(Path name) noexcept { - return PathTraitsFS::IsSpecialFilename(path) || - std::strchr(path, '\n') != nullptr; + return PathTraitsFS::IsSpecialFilename(name.c_str()) || + name.HasNewline(); } static void recursive_watch_subdirectories(WatchDirectory &parent, const AllocatedPath &path_fs, unsigned depth) -{ - DIR *dir; - struct dirent *ent; - +try { assert(depth <= inotify_max_depth); assert(!path_fs.IsNull()); @@ -166,20 +167,14 @@ recursive_watch_subdirectories(WatchDirectory &parent, if (depth > inotify_max_depth) return; - dir = opendir(path_fs.c_str()); - if (dir == nullptr) { - FormatErrno(inotify_domain, - "Failed to open directory %s", path_fs.c_str()); - return; - } - - while ((ent = readdir(dir))) { + DirectoryReader dir(path_fs); + while (dir.ReadEntry()) { int ret; - if (skip_path(ent->d_name)) + const Path name_fs = dir.GetEntry(); + if (SkipFilename(name_fs)) continue; - const auto name_fs = Path::FromFS(ent->d_name); const auto child_path_fs = path_fs / name_fs; FileInfo fi; @@ -217,8 +212,8 @@ recursive_watch_subdirectories(WatchDirectory &parent, recursive_watch_subdirectories(*child, child_path_fs, depth); } - - closedir(dir); +} catch (...) { + LogError(std::current_exception()); } gcc_pure From e8213220e2a2bc8b691135053d360c47447c392e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 21:07:52 +0200 Subject: [PATCH 15/17] db/update/InotifyUpdate: split the WatchDirectory constructor --- src/db/update/InotifyUpdate.cxx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/db/update/InotifyUpdate.cxx b/src/db/update/InotifyUpdate.cxx index c513d8fab..eb0c2d305 100644 --- a/src/db/update/InotifyUpdate.cxx +++ b/src/db/update/InotifyUpdate.cxx @@ -55,9 +55,15 @@ struct WatchDirectory { std::forward_list children; template - WatchDirectory(WatchDirectory *_parent, N &&_name, + WatchDirectory(N &&_name, int _descriptor) - :parent(_parent), name(std::forward(_name)), + :parent(nullptr), name(std::forward(_name)), + descriptor(_descriptor) {} + + template + WatchDirectory(WatchDirectory &_parent, N &&_name, + int _descriptor) + :parent(&_parent), name(std::forward(_name)), descriptor(_descriptor) {} WatchDirectory(const WatchDirectory &) = delete; @@ -203,7 +209,7 @@ try { /* already being watched */ continue; - parent.children.emplace_front(&parent, + parent.children.emplace_front(parent, name_fs, ret); child = &parent.children.front(); @@ -310,7 +316,7 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update, return; } - inotify_root = new WatchDirectory(nullptr, path, descriptor); + inotify_root = new WatchDirectory(path, descriptor); tree_add_watch_directory(inotify_root); From e113ce96214971c322c87255fa22a9e8e0ed7ab3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 16 Sep 2020 20:47:47 +0200 Subject: [PATCH 16/17] db/update/InotifyUpdate: obey `.mpdignore` files Closes https://github.com/MusicPlayerDaemon/MPD/issues/846 --- NEWS | 2 ++ src/db/update/InotifyUpdate.cxx | 31 +++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 340a35741..aeb7eb5bf 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.21.26 (not yet released) +* database + - inotify: obey ".mpdignore" files * output - osx: fix crash bug - sles: support floating point samples diff --git a/src/db/update/InotifyUpdate.cxx b/src/db/update/InotifyUpdate.cxx index eb0c2d305..0b5cd1893 100644 --- a/src/db/update/InotifyUpdate.cxx +++ b/src/db/update/InotifyUpdate.cxx @@ -21,11 +21,15 @@ #include "InotifySource.hxx" #include "InotifyQueue.hxx" #include "InotifyDomain.hxx" +#include "ExcludeList.hxx" #include "storage/StorageInterface.hxx" +#include "input/InputStream.hxx" +#include "input/Error.hxx" #include "fs/AllocatedPath.hxx" #include "fs/DirectoryReader.hxx" #include "fs/FileInfo.hxx" #include "fs/Traits.hxx" +#include "thread/Mutex.hxx" #include "util/Compiler.h" #include "Log.hxx" @@ -52,6 +56,8 @@ struct WatchDirectory { int descriptor; + ExcludeList exclude_list; + std::forward_list children; template @@ -64,11 +70,14 @@ struct WatchDirectory { WatchDirectory(WatchDirectory &_parent, N &&_name, int _descriptor) :parent(&_parent), name(std::forward(_name)), - descriptor(_descriptor) {} + descriptor(_descriptor), + exclude_list(_parent.exclude_list) {} WatchDirectory(const WatchDirectory &) = delete; WatchDirectory &operator=(const WatchDirectory &) = delete; + void LoadExcludeList(Path directory_path) noexcept; + gcc_pure unsigned GetDepth() const noexcept; @@ -76,6 +85,18 @@ struct WatchDirectory { AllocatedPath GetUriFS() const noexcept; }; +void +WatchDirectory::LoadExcludeList(Path directory_path) noexcept +try { + Mutex mutex; + auto is = InputStream::OpenReady((directory_path / Path::FromFS(".mpdignore")).c_str(), + mutex); + exclude_list.Load(std::move(is)); +} catch (...) { + if (!IsFileNotFound(std::current_exception())) + LogError(std::current_exception()); +} + static InotifySource *inotify_source; static InotifyQueue *inotify_queue; @@ -163,7 +184,8 @@ SkipFilename(Path name) noexcept static void recursive_watch_subdirectories(WatchDirectory &parent, - const AllocatedPath &path_fs, unsigned depth) + const AllocatedPath &path_fs, + unsigned depth) try { assert(depth <= inotify_max_depth); assert(!path_fs.IsNull()); @@ -181,6 +203,9 @@ try { if (SkipFilename(name_fs)) continue; + if (parent.exclude_list.Check(name_fs)) + continue; + const auto child_path_fs = path_fs / name_fs; FileInfo fi; @@ -213,6 +238,7 @@ try { name_fs, ret); child = &parent.children.front(); + child->LoadExcludeList(child_path_fs); tree_add_watch_directory(child); @@ -317,6 +343,7 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update, } inotify_root = new WatchDirectory(path, descriptor); + inotify_root->LoadExcludeList(path); tree_add_watch_directory(inotify_root); From 4c1cfca95b8a6dd2c0d9a7b6df065912eb8b4231 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 17 Sep 2020 14:18:28 +0200 Subject: [PATCH 17/17] db/update/InotifyUpdate: pass path by value to recursive_watch_subdirectories() --- src/db/update/InotifyUpdate.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/update/InotifyUpdate.cxx b/src/db/update/InotifyUpdate.cxx index 0b5cd1893..fd3e43694 100644 --- a/src/db/update/InotifyUpdate.cxx +++ b/src/db/update/InotifyUpdate.cxx @@ -184,7 +184,7 @@ SkipFilename(Path name) noexcept static void recursive_watch_subdirectories(WatchDirectory &parent, - const AllocatedPath &path_fs, + const Path path_fs, unsigned depth) try { assert(depth <= inotify_max_depth);