sdbus++: add errno property to errors

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I9de8211cd503503dd11a404cf3ffe0fd1c8399c6
diff --git a/docs/error.md b/docs/error.md
index 62aa138..5f9b62d 100644
--- a/docs/error.md
+++ b/docs/error.md
@@ -11,12 +11,14 @@
 a catch clause that returns a D-Bus error like
 "org.freedesktop.Example.Error.SomeError" to the method caller.
 
-The error YAML is simply a list of `name` and optional `description` properties.
+The error YAML is simply a list of `name` along with optional `description`
+and `errno` properties.
 Example:
 ```
 - name: SomeError
 - name: AnotherError
   description: >
     This is another error.
+  errno: E2BIG
 ```
 
diff --git a/tools/sdbusplus/error.py b/tools/sdbusplus/error.py
index 3f8e476..398ebe7 100644
--- a/tools/sdbusplus/error.py
+++ b/tools/sdbusplus/error.py
@@ -4,22 +4,27 @@
 from .renderer import Renderer
 
 
+class ErrorElement(NamedElement):
+    def __init__(self, **kwargs):
+        super(ErrorElement, self).__init__(**kwargs)
+        self.errno = kwargs.pop("errno", False)
+
+
 class Error(NamedElement, Renderer):
     @staticmethod
-    def load(name, rootdir='.'):
-        filename = os.path.join(rootdir,
-                                name.replace('.', '/') + ".errors.yaml")
+    def load(name, rootdir="."):
+        filename = os.path.join(
+            rootdir, name.replace(".", "/") + ".errors.yaml"
+        )
 
         with open(filename) as f:
             data = f.read()
             y = yaml.safe_load(data)
-            y = {'name': name,
-                 'errors': y}
+            y = {"name": name, "errors": y}
             return Error(**y)
 
     def __init__(self, **kwargs):
-        self.errors = \
-            [NamedElement(**n) for n in kwargs.pop('errors', [])]
+        self.errors = [ErrorElement(**n) for n in kwargs.pop("errors", [])]
 
         super(Error, self).__init__(**kwargs)
 
diff --git a/tools/sdbusplus/templates/error.cpp.mako b/tools/sdbusplus/templates/error.cpp.mako
index 74cefdc..5859970 100644
--- a/tools/sdbusplus/templates/error.cpp.mako
+++ b/tools/sdbusplus/templates/error.cpp.mako
@@ -21,6 +21,12 @@
 {
     return errWhat;
 }
+    % if e.errno:
+int ${e.name}::get_errno() const noexcept
+{
+    return errErrno;
+}
+    % endif
     % endfor
 
 } // namespace Error
diff --git a/tools/sdbusplus/templates/error.hpp.mako b/tools/sdbusplus/templates/error.hpp.mako
index 8ef5da3..200dbeb 100644
--- a/tools/sdbusplus/templates/error.hpp.mako
+++ b/tools/sdbusplus/templates/error.hpp.mako
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <cerrno>
 #include <sdbusplus/exception.hpp>
 <% namespaces = error.name.split('.') %>
 namespace sdbusplus
@@ -20,10 +21,16 @@
             "${e.description.strip()}";
     static constexpr auto errWhat =
             "${error.name}.Error.${e.name}: ${e.description.strip()}";
+    % if e.errno:
+    static constexpr auto errErrno = ${e.errno};
+    % endif
 
     const char* name() const noexcept override;
     const char* description() const noexcept override;
     const char* what() const noexcept override;
+    % if e.errno:
+    int get_errno() const noexcept override;
+    % endif
 };
 
     % endfor