*/smbclient: use the new API with SMBCCTX parameter

As a side effect, the input plugin closes the SMB/CIFS connection
after closing the file.

This solves one part of
https://github.com/MusicPlayerDaemon/MPD/issues/916
This commit is contained in:
Max Kellermann
2020-07-20 21:10:58 +02:00
parent 697531a948
commit f6dc9bcad6
5 changed files with 93 additions and 42 deletions

View File

@@ -34,14 +34,17 @@
#include <libsmbclient.h>
class SmbclientDirectoryReader final : public StorageDirectoryReader {
SmbclientContext &ctx;
const std::string base;
const unsigned handle;
SMBCFILE *const handle;
const char *name;
public:
SmbclientDirectoryReader(std::string &&_base, unsigned _handle)
:base(std::move(_base)), handle(_handle) {}
SmbclientDirectoryReader(SmbclientContext &_ctx,
std::string &&_base,
SMBCFILE *_handle) noexcept
:ctx(_ctx), base(std::move(_base)), handle(_handle) {}
~SmbclientDirectoryReader() override;
@@ -85,13 +88,13 @@ SmbclientStorage::MapToRelativeUTF8(std::string_view uri_utf8) const noexcept
}
static StorageFileInfo
GetInfo(const char *path)
GetInfo(SmbclientContext &ctx, const char *path)
{
struct stat st;
{
const std::lock_guard<Mutex> protect(smbclient_mutex);
if (smbc_stat(path, &st) != 0)
if (ctx.Stat(path, st) != 0)
throw MakeErrno("Failed to access file");
}
@@ -114,7 +117,7 @@ StorageFileInfo
SmbclientStorage::GetInfo(std::string_view uri_utf8, [[maybe_unused]] bool follow)
{
const std::string mapped = MapUTF8(uri_utf8);
return ::GetInfo(mapped.c_str());
return ::GetInfo(ctx, mapped.c_str());
}
std::unique_ptr<StorageDirectoryReader>
@@ -122,16 +125,17 @@ SmbclientStorage::OpenDirectory(std::string_view uri_utf8)
{
std::string mapped = MapUTF8(uri_utf8);
int handle;
SMBCFILE *handle;
{
const std::lock_guard<Mutex> protect(smbclient_mutex);
handle = smbc_opendir(mapped.c_str());
if (handle < 0)
handle = ctx.OpenDirectory(mapped.c_str());
if (handle == nullptr)
throw MakeErrno("Failed to open directory");
}
return std::make_unique<SmbclientDirectoryReader>(std::move(mapped),
return std::make_unique<SmbclientDirectoryReader>(ctx,
std::move(mapped),
handle);
}
@@ -147,7 +151,7 @@ SkipNameFS(const char *name) noexcept
SmbclientDirectoryReader::~SmbclientDirectoryReader()
{
const std::lock_guard<Mutex> lock(smbclient_mutex);
smbc_close(handle);
ctx.CloseDirectory(handle);
}
const char *
@@ -155,8 +159,7 @@ SmbclientDirectoryReader::Read() noexcept
{
const std::lock_guard<Mutex> protect(smbclient_mutex);
struct smbc_dirent *e;
while ((e = smbc_readdir(handle)) != nullptr) {
while (auto e = ctx.ReadDirectory(handle)) {
name = e->name;
if (!SkipNameFS(name))
return name;
@@ -169,7 +172,7 @@ StorageFileInfo
SmbclientDirectoryReader::GetInfo([[maybe_unused]] bool follow)
{
const std::string path = PathTraitsUTF8::Build(base, name);
return ::GetInfo(path.c_str());
return ::GetInfo(ctx, path.c_str());
}
static std::unique_ptr<Storage>