bindings: cxx: check for error from gpiod_line_bulk_new()
authorBartosz Golaszewski <bgolaszewski@baylibre.com>
Thu, 3 Dec 2020 12:55:00 +0000 (13:55 +0100)
committerBartosz Golaszewski <bgolaszewski@baylibre.com>
Mon, 14 Dec 2020 14:56:30 +0000 (15:56 +0100)
We call gpiod_line_bulk_new() in C++ bindings but never check its return
value. This function can fail so add a private method to line_bulk that
calls it and throws an exception if it returns NULL.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
bindings/cxx/gpiod.hpp
bindings/cxx/line_bulk.cpp

index a4ef7c90e4ef1a1c058a08db186cd259217d8ba7..8c8e6c9256d5bbd3b31b17fd83d88dbd0a78f841 100644 (file)
@@ -869,6 +869,7 @@ private:
 
        using line_bulk_ptr = ::std::unique_ptr<::gpiod_line_bulk, line_bulk_deleter>;
 
+       line_bulk_ptr make_line_bulk_ptr(void) const;
        line_bulk_ptr to_line_bulk(void) const;
 
        ::std::vector<line> _m_bulk;
index c24e91d59d4fab7ad04cf5683a14f7446936514c..1de90eb806b92734948fb827ab2e1fc9b6693615 100644 (file)
@@ -256,8 +256,7 @@ line_bulk line_bulk::event_wait(const ::std::chrono::nanoseconds& timeout) const
        this->throw_if_empty();
        line::chip_guard lock_chip(this->_m_bulk.front());
 
-       auto ev_bulk = ::gpiod_line_bulk_new(this->size());
-       line_bulk_ptr ev_bulk_deleter(ev_bulk);
+       auto ev_bulk = this->make_line_bulk_ptr();
        auto bulk = this->to_line_bulk();
        ::timespec ts;
        line_bulk ret;
@@ -266,16 +265,16 @@ line_bulk line_bulk::event_wait(const ::std::chrono::nanoseconds& timeout) const
        ts.tv_sec = timeout.count() / 1000000000ULL;
        ts.tv_nsec = timeout.count() % 1000000000ULL;
 
-       rv = ::gpiod_line_event_wait_bulk(bulk.get(), ::std::addressof(ts), ev_bulk);
+       rv = ::gpiod_line_event_wait_bulk(bulk.get(), ::std::addressof(ts), ev_bulk.get());
        if (rv < 0) {
                throw ::std::system_error(errno, ::std::system_category(),
                                          "error polling for events");
        } else if (rv > 0) {
                auto chip = this->_m_bulk[0].get_chip();
-               auto num_lines = ::gpiod_line_bulk_num_lines(ev_bulk);
+               auto num_lines = ::gpiod_line_bulk_num_lines(ev_bulk.get());
 
                for (unsigned int i = 0; i < num_lines; i++)
-                       ret.append(line(::gpiod_line_bulk_get_line(ev_bulk, i), chip));
+                       ret.append(line(::gpiod_line_bulk_get_line(ev_bulk.get(), i), chip));
        }
 
        return ret;
@@ -340,10 +339,21 @@ void line_bulk::throw_if_empty(void) const
                throw ::std::logic_error("line_bulk not holding any GPIO lines");
 }
 
-line_bulk::line_bulk_ptr line_bulk::to_line_bulk(void) const
+line_bulk::line_bulk_ptr line_bulk::make_line_bulk_ptr(void) const
 {
        line_bulk_ptr bulk(::gpiod_line_bulk_new(this->size()));
 
+       if (!bulk)
+               throw ::std::system_error(errno, ::std::system_category(),
+                                         "unable to allocate new bulk object");
+
+       return bulk;
+}
+
+line_bulk::line_bulk_ptr line_bulk::to_line_bulk(void) const
+{
+       line_bulk_ptr bulk = this->make_line_bulk_ptr();
+
        for (auto& it: this->_m_bulk)
                ::gpiod_line_bulk_add_line(bulk.get(), it._m_line);