storage: migrate from class Error to C++ exceptions

This commit is contained in:
Max Kellermann
2016-10-27 08:40:40 +02:00
parent cab87e9398
commit c598686bd9
19 changed files with 208 additions and 281 deletions
+26 -40
View File
@@ -25,7 +25,6 @@
#include "fs/FileInfo.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/DirectoryReader.hxx"
#include "util/Error.hxx"
#include "util/StringCompare.hxx"
#include <string>
@@ -43,8 +42,7 @@ public:
/* virtual methods from class StorageDirectoryReader */
const char *Read() override;
bool GetInfo(bool follow, StorageFileInfo &info,
Error &error) override;
StorageFileInfo GetInfo(bool follow) override;
};
class LocalStorage final : public Storage {
@@ -59,11 +57,9 @@ public:
}
/* virtual methods from class Storage */
bool GetInfo(const char *uri_utf8, bool follow, StorageFileInfo &info,
Error &error) override;
StorageFileInfo GetInfo(const char *uri_utf8, bool follow) override;
StorageDirectoryReader *OpenDirectory(const char *uri_utf8,
Error &error) override;
StorageDirectoryReader *OpenDirectory(const char *uri_utf8) override;
std::string MapUTF8(const char *uri_utf8) const override;
@@ -72,15 +68,15 @@ public:
const char *MapToRelativeUTF8(const char *uri_utf8) const override;
private:
AllocatedPath MapFS(const char *uri_utf8, Error &error) const;
AllocatedPath MapFSOrThrow(const char *uri_utf8) const;
};
static bool
Stat(Path path, bool follow, StorageFileInfo &info, Error &error)
gcc_pure
static StorageFileInfo
Stat(Path path, bool follow)
{
FileInfo src;
if (!GetFileInfo(path, src, follow, error))
return false;
const FileInfo src(path, follow);
StorageFileInfo info;
if (src.IsRegular())
info.type = StorageFileInfo::Type::REGULAR;
@@ -97,7 +93,7 @@ Stat(Path path, bool follow, StorageFileInfo &info, Error &error)
info.device = src.GetDevice();
info.inode = src.GetInode();
#endif
return true;
return info;
}
std::string
@@ -112,24 +108,25 @@ LocalStorage::MapUTF8(const char *uri_utf8) const
}
AllocatedPath
LocalStorage::MapFS(const char *uri_utf8, Error &error) const
LocalStorage::MapFSOrThrow(const char *uri_utf8) const
{
assert(uri_utf8 != nullptr);
if (StringIsEmpty(uri_utf8))
return base_fs;
AllocatedPath path_fs = AllocatedPath::FromUTF8(uri_utf8, error);
if (!path_fs.IsNull())
path_fs = AllocatedPath::Build(base_fs, path_fs);
return path_fs;
return AllocatedPath::Build(base_fs,
AllocatedPath::FromUTF8Throw(uri_utf8));
}
AllocatedPath
LocalStorage::MapFS(const char *uri_utf8) const
{
return MapFS(uri_utf8, IgnoreError());
try {
return MapFSOrThrow(uri_utf8);
} catch (const std::runtime_error &) {
return AllocatedPath::Null();
}
}
const char *
@@ -138,25 +135,16 @@ LocalStorage::MapToRelativeUTF8(const char *uri_utf8) const
return PathTraitsUTF8::Relative(base_utf8.c_str(), uri_utf8);
}
bool
LocalStorage::GetInfo(const char *uri_utf8, bool follow, StorageFileInfo &info,
Error &error)
StorageFileInfo
LocalStorage::GetInfo(const char *uri_utf8, bool follow)
{
AllocatedPath path_fs = MapFS(uri_utf8, error);
if (path_fs.IsNull())
return false;
return Stat(path_fs, follow, info, error);
return Stat(MapFSOrThrow(uri_utf8), follow);
}
StorageDirectoryReader *
LocalStorage::OpenDirectory(const char *uri_utf8, Error &error)
LocalStorage::OpenDirectory(const char *uri_utf8)
{
AllocatedPath path_fs = MapFS(uri_utf8, error);
if (path_fs.IsNull())
return nullptr;
return new LocalDirectoryReader(std::move(path_fs));
return new LocalDirectoryReader(MapFSOrThrow(uri_utf8));
}
gcc_pure
@@ -186,12 +174,10 @@ LocalDirectoryReader::Read()
return nullptr;
}
bool
LocalDirectoryReader::GetInfo(bool follow, StorageFileInfo &info, Error &error)
StorageFileInfo
LocalDirectoryReader::GetInfo(bool follow)
{
const AllocatedPath path_fs =
AllocatedPath::Build(base_fs, reader.GetEntry());
return Stat(path_fs, follow, info, error);
return Stat(AllocatedPath::Build(base_fs, reader.GetEntry()), follow);
}
Storage *
+19 -24
View File
@@ -35,7 +35,6 @@
#include "event/Call.hxx"
#include "event/DeferredMonitor.hxx"
#include "event/TimeoutMonitor.hxx"
#include "util/Error.hxx"
#include "util/StringCompare.hxx"
extern "C" {
@@ -84,11 +83,9 @@ public:
}
/* virtual methods from class Storage */
bool GetInfo(const char *uri_utf8, bool follow, StorageFileInfo &info,
Error &error) override;
StorageFileInfo GetInfo(const char *uri_utf8, bool follow) override;
StorageDirectoryReader *OpenDirectory(const char *uri_utf8,
Error &error) override;
StorageDirectoryReader *OpenDirectory(const char *uri_utf8) override;
std::string MapUTF8(const char *uri_utf8) const override;
@@ -214,7 +211,7 @@ private:
};
static std::string
UriToNfsPath(const char *_uri_utf8, Error &error)
UriToNfsPath(const char *_uri_utf8)
{
assert(_uri_utf8 != nullptr);
@@ -222,7 +219,7 @@ UriToNfsPath(const char *_uri_utf8, Error &error)
std::string uri_utf8("/");
uri_utf8.append(_uri_utf8);
return AllocatedPath::FromUTF8(uri_utf8.c_str(), error).Steal();
return AllocatedPath::FromUTF8Throw(uri_utf8.c_str()).Steal();
}
std::string
@@ -260,12 +257,15 @@ Copy(StorageFileInfo &info, const struct stat &st)
class NfsGetInfoOperation final : public BlockingNfsOperation {
const char *const path;
StorageFileInfo &info;
StorageFileInfo info;
public:
NfsGetInfoOperation(NfsConnection &_connection, const char *_path,
StorageFileInfo &_info)
:BlockingNfsOperation(_connection), path(_path), info(_info) {}
NfsGetInfoOperation(NfsConnection &_connection, const char *_path)
:BlockingNfsOperation(_connection), path(_path) {}
const StorageFileInfo &GetInfo() const {
return info;
}
protected:
void Start() override {
@@ -277,19 +277,16 @@ protected:
}
};
bool
NfsStorage::GetInfo(const char *uri_utf8, gcc_unused bool follow,
StorageFileInfo &info, Error &error)
StorageFileInfo
NfsStorage::GetInfo(const char *uri_utf8, gcc_unused bool follow)
{
const std::string path = UriToNfsPath(uri_utf8, error);
if (path.empty())
return false;
const std::string path = UriToNfsPath(uri_utf8);
WaitConnected();
NfsGetInfoOperation operation(*connection, path.c_str(), info);
NfsGetInfoOperation operation(*connection, path.c_str());
operation.Run();
return true;
return operation.GetInfo();
}
gcc_pure
@@ -377,11 +374,9 @@ NfsListDirectoryOperation::CollectEntries(struct nfsdir *dir)
}
StorageDirectoryReader *
NfsStorage::OpenDirectory(const char *uri_utf8, Error &error)
NfsStorage::OpenDirectory(const char *uri_utf8)
{
const std::string path = UriToNfsPath(uri_utf8, error);
if (path.empty())
return nullptr;
const std::string path = UriToNfsPath(uri_utf8);
WaitConnected();
@@ -392,7 +387,7 @@ NfsStorage::OpenDirectory(const char *uri_utf8, Error &error)
}
static Storage *
CreateNfsStorageURI(EventLoop &event_loop, const char *base, Error &)
CreateNfsStorageURI(EventLoop &event_loop, const char *base)
{
if (memcmp(base, "nfs://", 6) != 0)
return nullptr;
+34 -41
View File
@@ -26,8 +26,9 @@
#include "lib/smbclient/Mutex.hxx"
#include "fs/Traits.hxx"
#include "thread/Mutex.hxx"
#include "util/Error.hxx"
#include "system/Error.hxx"
#include "util/StringCompare.hxx"
#include "util/ScopeExit.hxx"
#include <libsmbclient.h>
@@ -45,8 +46,7 @@ public:
/* virtual methods from class StorageDirectoryReader */
const char *Read() override;
bool GetInfo(bool follow, StorageFileInfo &info,
Error &error) override;
StorageFileInfo GetInfo(bool follow) override;
};
class SmbclientStorage final : public Storage {
@@ -65,11 +65,9 @@ public:
}
/* virtual methods from class Storage */
bool GetInfo(const char *uri_utf8, bool follow, StorageFileInfo &info,
Error &error) override;
StorageFileInfo GetInfo(const char *uri_utf8, bool follow) override;
StorageDirectoryReader *OpenDirectory(const char *uri_utf8,
Error &error) override;
StorageDirectoryReader *OpenDirectory(const char *uri_utf8) override;
std::string MapUTF8(const char *uri_utf8) const override;
@@ -93,18 +91,18 @@ SmbclientStorage::MapToRelativeUTF8(const char *uri_utf8) const
return PathTraitsUTF8::Relative(base.c_str(), uri_utf8);
}
static bool
GetInfo(const char *path, StorageFileInfo &info, Error &error)
static StorageFileInfo
GetInfo(const char *path)
{
struct stat st;
smbclient_mutex.lock();
bool success = smbc_stat(path, &st) == 0;
smbclient_mutex.unlock();
if (!success) {
error.SetErrno();
return false;
{
const ScopeLock protect(smbclient_mutex);
if (smbc_stat(path, &st) != 0)
throw MakeErrno("Failed to access file");
}
StorageFileInfo info;
if (S_ISREG(st.st_mode))
info.type = StorageFileInfo::Type::REGULAR;
else if (S_ISDIR(st.st_mode))
@@ -116,27 +114,28 @@ GetInfo(const char *path, StorageFileInfo &info, Error &error)
info.mtime = st.st_mtime;
info.device = st.st_dev;
info.inode = st.st_ino;
return true;
return info;
}
bool
SmbclientStorage::GetInfo(const char *uri_utf8, gcc_unused bool follow,
StorageFileInfo &info, Error &error)
StorageFileInfo
SmbclientStorage::GetInfo(const char *uri_utf8, gcc_unused bool follow)
{
const std::string mapped = MapUTF8(uri_utf8);
return ::GetInfo(mapped.c_str(), info, error);
return ::GetInfo(mapped.c_str());
}
StorageDirectoryReader *
SmbclientStorage::OpenDirectory(const char *uri_utf8, Error &error)
SmbclientStorage::OpenDirectory(const char *uri_utf8)
{
std::string mapped = MapUTF8(uri_utf8);
smbclient_mutex.lock();
int handle = smbc_opendir(mapped.c_str());
smbclient_mutex.unlock();
if (handle < 0) {
error.SetErrno();
return nullptr;
int handle;
{
const ScopeLock protect(smbclient_mutex);
handle = smbc_opendir(mapped.c_str());
if (handle < 0)
throw MakeErrno("Failed to open directory");
}
return new SmbclientDirectoryReader(std::move(mapped.c_str()), handle);
@@ -173,18 +172,15 @@ SmbclientDirectoryReader::Read()
return nullptr;
}
bool
SmbclientDirectoryReader::GetInfo(gcc_unused bool follow,
StorageFileInfo &info,
Error &error)
StorageFileInfo
SmbclientDirectoryReader::GetInfo(gcc_unused bool follow)
{
const std::string path = PathTraitsUTF8::Build(base.c_str(), name);
return ::GetInfo(path.c_str(), info, error);
return ::GetInfo(path.c_str());
}
static Storage *
CreateSmbclientStorageURI(gcc_unused EventLoop &event_loop, const char *base,
Error &error)
CreateSmbclientStorageURI(gcc_unused EventLoop &event_loop, const char *base)
{
if (memcmp(base, "smb://", 6) != 0)
return nullptr;
@@ -193,16 +189,13 @@ CreateSmbclientStorageURI(gcc_unused EventLoop &event_loop, const char *base,
const ScopeLock protect(smbclient_mutex);
SMBCCTX *ctx = smbc_new_context();
if (ctx == nullptr) {
error.SetErrno("smbc_new_context() failed");
return nullptr;
}
if (ctx == nullptr)
throw MakeErrno("smbc_new_context() failed");
SMBCCTX *ctx2 = smbc_init_context(ctx);
if (ctx2 == nullptr) {
error.SetErrno("smbc_init_context() failed");
smbc_free_context(ctx, 1);
return nullptr;
AtScopeExit(ctx) { smbc_free_context(ctx, 1); };
throw MakeErrno("smbc_new_context() failed");
}
return new SmbclientStorage(base, ctx2);