diff options
author | Max Kellermann <max@musicpd.org> | 2020-07-20 17:32:40 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2020-07-20 22:01:10 +0200 |
commit | 697531a948bc8f21cd56c591bb5b5cd523cd30d1 (patch) | |
tree | 474a8db7b1034fdfc11f208136672eb36a24b9ed | |
parent | b04c6fbd7287fb7155a8a24852aa274b99dd1ac6 (diff) |
lib/smbclient/Context: new wrapper for SMBCCTX
-rw-r--r-- | src/input/plugins/SmbclientInputPlugin.cxx | 42 | ||||
-rw-r--r-- | src/lib/smbclient/Context.cxx | 40 | ||||
-rw-r--r-- | src/lib/smbclient/Context.hxx | 59 | ||||
-rw-r--r-- | src/lib/smbclient/meson.build | 1 | ||||
-rw-r--r-- | src/storage/plugins/SmbclientStorage.cxx | 25 |
5 files changed, 119 insertions, 48 deletions
diff --git a/src/input/plugins/SmbclientInputPlugin.cxx b/src/input/plugins/SmbclientInputPlugin.cxx index e8febc82f..9f4a148d2 100644 --- a/src/input/plugins/SmbclientInputPlugin.cxx +++ b/src/input/plugins/SmbclientInputPlugin.cxx @@ -19,6 +19,7 @@ #include "SmbclientInputPlugin.hxx" #include "lib/smbclient/Init.hxx" +#include "lib/smbclient/Context.hxx" #include "lib/smbclient/Mutex.hxx" #include "../InputStream.hxx" #include "../InputPlugin.hxx" @@ -29,15 +30,17 @@ #include <libsmbclient.h> class SmbclientInputStream final : public InputStream { - SMBCCTX *ctx; + SmbclientContext ctx; int fd; public: SmbclientInputStream(const char *_uri, Mutex &_mutex, - SMBCCTX *_ctx, int _fd, const struct stat &st) + SmbclientContext &&_ctx, + int _fd, const struct stat &st) :InputStream(_uri, _mutex), - ctx(_ctx), fd(_fd) { + ctx(std::move(_ctx)), fd(_fd) + { seekable = true; size = st.st_size; SetReady(); @@ -46,7 +49,6 @@ public: ~SmbclientInputStream() override { const std::lock_guard<Mutex> lock(smbclient_mutex); smbc_close(fd); - smbc_free_context(ctx, 1); } /* virtual methods from InputStream */ @@ -83,38 +85,22 @@ static InputStreamPtr input_smbclient_open(const char *uri, Mutex &mutex) { - const std::lock_guard<Mutex> protect(smbclient_mutex); - - SMBCCTX *ctx = smbc_new_context(); - if (ctx == nullptr) - throw MakeErrno("smbc_new_context() failed"); - - SMBCCTX *ctx2 = smbc_init_context(ctx); - if (ctx2 == nullptr) { - int e = errno; - smbc_free_context(ctx, 1); - throw MakeErrno(e, "smbc_init_context() failed"); - } + auto ctx = SmbclientContext::New(); - ctx = ctx2; + const std::lock_guard<Mutex> protect(smbclient_mutex); int fd = smbc_open(uri, O_RDONLY, 0); - if (fd < 0) { - int e = errno; - smbc_free_context(ctx, 1); - throw MakeErrno(e, "smbc_open() failed"); - } + if (fd < 0) + throw MakeErrno("smbc_open() failed"); struct stat st; - if (smbc_fstat(fd, &st) < 0) { - int e = errno; - smbc_free_context(ctx, 1); - throw MakeErrno(e, "smbc_fstat() failed"); - } + if (smbc_fstat(fd, &st) < 0) + throw MakeErrno("smbc_fstat() failed"); return std::make_unique<MaybeBufferedInputStream> (std::make_unique<SmbclientInputStream>(uri, mutex, - ctx, fd, st)); + std::move(ctx), + fd, st)); } size_t diff --git a/src/lib/smbclient/Context.cxx b/src/lib/smbclient/Context.cxx new file mode 100644 index 000000000..3e122bd37 --- /dev/null +++ b/src/lib/smbclient/Context.cxx @@ -0,0 +1,40 @@ +/* + * Copyright 2003-2020 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "Context.hxx" +#include "system/Error.hxx" + +#include <cerrno> + +SmbclientContext +SmbclientContext::New() +{ + SMBCCTX *ctx = smbc_new_context(); + if (ctx == nullptr) + throw MakeErrno("smbc_new_context() failed"); + + SMBCCTX *ctx2 = smbc_init_context(ctx); + if (ctx2 == nullptr) { + int e = errno; + smbc_free_context(ctx, 1); + throw MakeErrno(e, "smbc_init_context() failed"); + } + + return SmbclientContext(ctx2); +} diff --git a/src/lib/smbclient/Context.hxx b/src/lib/smbclient/Context.hxx new file mode 100644 index 000000000..7d4c59f88 --- /dev/null +++ b/src/lib/smbclient/Context.hxx @@ -0,0 +1,59 @@ +/* + * Copyright 2003-2020 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_SMBCLIENT_CONTEXT_HXX +#define MPD_SMBCLIENT_CONTEXT_HXX + +#include <libsmbclient.h> + +#include <utility> + +/** + * Wrapper for `SMBCCTX*`. + */ +class SmbclientContext { + SMBCCTX *ctx = nullptr; + + explicit SmbclientContext(SMBCCTX *_ctx) noexcept + :ctx(_ctx) {} + +public: + SmbclientContext() = default; + + ~SmbclientContext() noexcept { + if (ctx != nullptr) + smbc_free_context(ctx, 1); + } + + SmbclientContext(SmbclientContext &&src) noexcept + :ctx(std::exchange(src.ctx, nullptr)) {} + + SmbclientContext &operator=(SmbclientContext &&src) noexcept { + using std::swap; + swap(ctx, src.ctx); + return *this; + } + + /** + * Throws on error. + */ + static SmbclientContext New(); +}; + +#endif diff --git a/src/lib/smbclient/meson.build b/src/lib/smbclient/meson.build index 36f4020b7..24aee8c7c 100644 --- a/src/lib/smbclient/meson.build +++ b/src/lib/smbclient/meson.build @@ -9,6 +9,7 @@ smbclient = static_library( 'Domain.cxx', 'Mutex.cxx', 'Init.cxx', + 'Context.cxx', include_directories: inc, dependencies: [ smbclient_dep, diff --git a/src/storage/plugins/SmbclientStorage.cxx b/src/storage/plugins/SmbclientStorage.cxx index c227978c4..f65c1efc1 100644 --- a/src/storage/plugins/SmbclientStorage.cxx +++ b/src/storage/plugins/SmbclientStorage.cxx @@ -22,6 +22,7 @@ #include "storage/StorageInterface.hxx" #include "storage/FileInfo.hxx" #include "lib/smbclient/Init.hxx" +#include "lib/smbclient/Context.hxx" #include "lib/smbclient/Mutex.hxx" #include "fs/Traits.hxx" #include "thread/Mutex.hxx" @@ -52,16 +53,11 @@ public: class SmbclientStorage final : public Storage { const std::string base; - SMBCCTX *const ctx; + SmbclientContext ctx = SmbclientContext::New(); public: - SmbclientStorage(const char *_base, SMBCCTX *_ctx) - :base(_base), ctx(_ctx) {} - - ~SmbclientStorage() override { - const std::lock_guard<Mutex> lock(smbclient_mutex); - smbc_free_context(ctx, 1); - } + explicit SmbclientStorage(const char *_base) + :base(_base) {} /* virtual methods from class Storage */ StorageFileInfo GetInfo(std::string_view uri_utf8, bool follow) override; @@ -184,18 +180,7 @@ CreateSmbclientStorageURI([[maybe_unused]] EventLoop &event_loop, const char *ba SmbclientInit(); - const std::lock_guard<Mutex> protect(smbclient_mutex); - SMBCCTX *ctx = smbc_new_context(); - if (ctx == nullptr) - throw MakeErrno("smbc_new_context() failed"); - - SMBCCTX *ctx2 = smbc_init_context(ctx); - if (ctx2 == nullptr) { - AtScopeExit(ctx) { smbc_free_context(ctx, 1); }; - throw MakeErrno("smbc_new_context() failed"); - } - - return std::make_unique<SmbclientStorage>(base, ctx2); + return std::make_unique<SmbclientStorage>(base); } const StoragePlugin smbclient_storage_plugin = { |