From 86e2075c636e2828871e38bf0f2aef4a243c42fd Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 6 Jul 2018 19:01:30 +0200 Subject: [PATCH] lib/nfs/Connection: use new class NfsClientError Allows callers to extract the NFS error code. --- Makefile.am | 1 + src/input/Error.cxx | 9 +++++ src/lib/nfs/Connection.cxx | 3 +- src/lib/nfs/Error.cxx | 76 ++++++++++++++++++++++++++++++++++++++ src/lib/nfs/Error.hxx | 58 +++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 src/lib/nfs/Error.cxx create mode 100644 src/lib/nfs/Error.hxx diff --git a/Makefile.am b/Makefile.am index f41f852f6..bbc666ce7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -713,6 +713,7 @@ NFS_SOURCES = \ src/lib/nfs/Cancellable.hxx \ src/lib/nfs/Lease.hxx \ src/lib/nfs/Connection.cxx src/lib/nfs/Connection.hxx \ + src/lib/nfs/Error.cxx src/lib/nfs/Error.hxx \ src/lib/nfs/Manager.cxx src/lib/nfs/Manager.hxx \ src/lib/nfs/Glue.cxx src/lib/nfs/Glue.hxx \ src/lib/nfs/Base.cxx src/lib/nfs/Base.hxx \ diff --git a/src/input/Error.cxx b/src/input/Error.cxx index 04638a16e..ae7b9d7de 100644 --- a/src/input/Error.cxx +++ b/src/input/Error.cxx @@ -21,6 +21,11 @@ #include "Error.hxx" #include "system/Error.hxx" +#ifdef ENABLE_NFS +#include "lib/nfs/Error.hxx" +#include +#endif + bool IsFileNotFound(std::exception_ptr ep) { @@ -28,6 +33,10 @@ IsFileNotFound(std::exception_ptr ep) std::rethrow_exception(ep); } catch (const std::system_error &e) { return IsFileNotFound(e); +#ifdef ENABLE_NFS + } catch (const NfsClientError &e) { + return e.GetCode() == NFS3ERR_NOENT; +#endif } catch (...) { } diff --git a/src/lib/nfs/Connection.cxx b/src/lib/nfs/Connection.cxx index f9792f41b..cad2da530 100644 --- a/src/lib/nfs/Connection.cxx +++ b/src/lib/nfs/Connection.cxx @@ -19,6 +19,7 @@ #include "config.h" #include "Connection.hxx" +#include "Error.hxx" #include "Lease.hxx" #include "Callback.hxx" #include "event/Loop.hxx" @@ -139,7 +140,7 @@ NfsConnection::CancellableCallback::Callback(int err, void *data) if (err >= 0) cb.OnNfsCallback((unsigned)err, data); else - cb.OnNfsError(std::make_exception_ptr(std::runtime_error((const char *)data))); + cb.OnNfsError(std::make_exception_ptr(NfsClientError(-err, (const char *)data))); } else { if (open) { /* a nfs_open_async() call was cancelled - to diff --git a/src/lib/nfs/Error.cxx b/src/lib/nfs/Error.cxx new file mode 100644 index 000000000..942e6cabf --- /dev/null +++ b/src/lib/nfs/Error.cxx @@ -0,0 +1,76 @@ +/* + * Copyright 2007-2017 Content Management AG + * All rights reserved. + * + * author: Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Error.hxx" +#include "util/StringFormat.hxx" + +extern "C" { +#include +} + +#include +#include + +static StringBuffer<256> +FormatNfsClientError(struct nfs_context *nfs, const char *msg) noexcept +{ + assert(msg != nullptr); + + const char *msg2 = nfs_get_error(nfs); + return StringFormat<256>("%s: %s", msg, msg2); +} + +NfsClientError::NfsClientError(struct nfs_context *nfs, const char *msg) noexcept + :std::runtime_error(FormatNfsClientError(nfs, msg).c_str()), + code(0) {} + +static StringBuffer<256> +FormatNfsClientError(int err, struct nfs_context *nfs, void *data, + const char *msg) noexcept +{ + assert(msg != nullptr); + assert(err < 0); + + const char *msg2 = (const char *)data; + if (data == nullptr || *(const char *)data == 0) { + msg2 = nfs_get_error(nfs); + if (msg2 == nullptr) + msg2 = strerror(-err); + } + + return StringFormat<256>("%s: %s", msg, msg2); +} + +NfsClientError::NfsClientError(int err, struct nfs_context *nfs, void *data, + const char *msg) noexcept + :std::runtime_error(FormatNfsClientError(err, nfs, data, msg).c_str()), + code(-err) {} diff --git a/src/lib/nfs/Error.hxx b/src/lib/nfs/Error.hxx new file mode 100644 index 000000000..73ab13e5d --- /dev/null +++ b/src/lib/nfs/Error.hxx @@ -0,0 +1,58 @@ +/* + * Copyright 2007-2017 Content Management AG + * All rights reserved. + * + * author: Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NFS_ERROR_HXX +#define NFS_ERROR_HXX + +#include + +class NfsClientError : public std::runtime_error { + int code; + +public: + explicit NfsClientError(const char *_msg) noexcept + :std::runtime_error(_msg), code(0) {} + + NfsClientError(int _code, const char *_msg) noexcept + :std::runtime_error(_msg), code(_code) {} + + NfsClientError(struct nfs_context *nfs, const char *msg) noexcept; + + NfsClientError(int err, struct nfs_context *nfs, void *data, + const char *msg) noexcept; + + int GetCode() const noexcept { + return code; + } +}; + +#endif