[vte] spawn: Fix double-calling of the child setup data destructor



commit 0b1708033fbd70913c0938ed6ac05622a6a17ddd
Author: Christian Persch <chpe src gnome org>
Date:   Fri May 1 20:03:42 2020 +0200

    spawn: Fix double-calling of the child setup data destructor
    
    The problem was that after moving the SpawnContext into the SpawnOperation,
    ~SpawnContext of the move source's context called the child setup data destructor
    but the data now belongs to the move target.
    
    Fix this by using a std::shared_ptr.
    
    Fixes: https://gitlab.gnome.org/GNOME/vte/-/issues/237

 src/spawn.cc |  2 +-
 src/spawn.hh | 18 +++++++-----------
 2 files changed, 8 insertions(+), 12 deletions(-)
---
diff --git a/src/spawn.cc b/src/spawn.cc
index ced0ba7a..e6bf845b 100644
--- a/src/spawn.cc
+++ b/src/spawn.cc
@@ -436,7 +436,7 @@ SpawnContext::exec(vte::libc::FD& child_report_error_pipe_write) noexcept
 
         /* Finally call an extra child setup */
         if (m_child_setup)
-                m_child_setup(m_child_setup_data);
+                m_child_setup(m_child_setup_data.get());
 
         /* exec */
         _vte_execute(arg0(),
diff --git a/src/spawn.hh b/src/spawn.hh
index 5e8ff733..0a2a5e58 100644
--- a/src/spawn.hh
+++ b/src/spawn.hh
@@ -54,8 +54,7 @@ private:
         std::vector<std::pair<int,int>> m_fd_map{{-1, 0}, {-1, 1}, {-1, 2}};
 
         child_setup_type m_child_setup{(void(*)(void*))0};
-        void* m_child_setup_data{nullptr};
-        GDestroyNotify m_child_setup_data_destroy{nullptr};
+        std::shared_ptr<void> m_child_setup_data{nullptr};
 
         bool m_inherit_environ{true};
         bool m_systemd_scope{true};
@@ -65,12 +64,7 @@ private:
 
 public:
         SpawnContext() = default;
-
-        ~SpawnContext()
-        {
-                if (m_child_setup_data && m_child_setup_data_destroy)
-                        m_child_setup_data_destroy(m_child_setup_data);
-        }
+        ~SpawnContext() = default;
 
         SpawnContext(SpawnContext const&) = delete;
         SpawnContext(SpawnContext&&) = default;
@@ -118,11 +112,13 @@ public:
 
         void set_child_setup(child_setup_type func,
                              void* data,
-                             GDestroyNotify destroy)
+                             void(*destroy)(void*))
         {
                 m_child_setup = func;
-                m_child_setup_data = data;
-                m_child_setup_data_destroy = destroy;
+                if (destroy)
+                        m_child_setup_data = std::shared_ptr<void>(data, destroy);
+                else
+                        m_child_setup_data = std::shared_ptr<void>(data, [](auto p) { });
         }
 
         void add_fds(int const* fds,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]