summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2020-07-20 17:32:40 +0200
committerMax Kellermann <max@musicpd.org>2020-07-20 22:01:10 +0200
commit697531a948bc8f21cd56c591bb5b5cd523cd30d1 (patch)
tree474a8db7b1034fdfc11f208136672eb36a24b9ed
parentb04c6fbd7287fb7155a8a24852aa274b99dd1ac6 (diff)
lib/smbclient/Context: new wrapper for SMBCCTX
-rw-r--r--src/input/plugins/SmbclientInputPlugin.cxx42
-rw-r--r--src/lib/smbclient/Context.cxx40
-rw-r--r--src/lib/smbclient/Context.hxx59
-rw-r--r--src/lib/smbclient/meson.build1
-rw-r--r--src/storage/plugins/SmbclientStorage.cxx25
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 = {