0

I would like to use a Linux kernel signal to asynchronously communicate the occurrence of an event from a module to a user-space application. I have this working in C in the following way:

void rcv_signal(int n, siginfo_t *info, void *unused)
{
   // Do something interesting with the signal
}

// Register for updates from the kernel
int main(int argc, char *argv[])
{
    struct sigaction sig;
    sig.sa_sigaction = rcv_signal; // Function pointer
    sig.sa_flags = SA_SIGINFO;
    sigaction(SOME_CUSTOM_SIGNAL, &sig, NULL);

    // Code to wait() then return
}

Now, I would like to move to C++ implementation. More specifically, I would like to use boost::function / boost::bind to bind the sa_sigaction to a method InputCapture::receive. However, I am struggling to get the correct function signature.

Here is the definition of the InputCapture Class:

class InputCapture
{
    public: InputCapture(uint8_t intimer) : timer(_timer) {}
    public: ~InputCapture() {}
    private: void receive(int n, siginfo_t *info, void *unused) {}
    private: uint8_t timer;
};

And here is the modified sa_sigaction:

// Register for updates from the kernel
struct sigaction sig;
sig.sa_sigaction = boost::function<void (int n, siginfo_t *info, void *unused)> (
    boost::bind(&InputCapture::receive, this, _1));
sig.sa_flags = SA_SIGINFO;
sigaction(SOME_CUSTOM_SIGNAL, &sig, NULL);

However, I get the following compilation error:

In file included from /home/asymingt/export/rootfs/usr/include/boost/bind.hpp:22:0, from /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/LogicalStamp.hpp:12, from /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.hpp:4, from /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:1: /home/asymingt/export/rootfs/usr/include/boost/bind/bind.hpp: In instantiation of ‘struct boost::_bi::result_traits’: /home/asymingt/export/rootfs/usr/include/boost/bind/bind_template.hpp:15:48: required from ‘class boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >’ /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:41:57: required from here /home/asymingt/export/rootfs/usr/include/boost/bind/bind.hpp:69:37: error: ‘void (timesync::InputCapture::)(int, siginfo, void*)’ is not a class, struct, or union type typedef typename F::result_type type; ^ /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp: In constructor ‘timesync::InputCapture::InputCapture(uint8_t)’: /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:40:19: error: cannot convert ‘boost::function’ to ‘void ()(int, siginfo_t, void*) {aka void ()(int, siginfo, void*)}’ in assignment sig.sa_sigaction = boost::function ( ^ In file included from /home/asymingt/export/rootfs/usr/include/boost/function/detail/maybe_include.hpp:28:0, from /home/asymingt/export/rootfs/usr/include/boost/function/detail/function_iterate.hpp:14, from /home/asymingt/export/rootfs/usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:62, from /home/asymingt/export/rootfs/usr/include/boost/function.hpp:64, from /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:3: /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp: In instantiation of ‘static void boost::detail::function::void_function_obj_invoker3::invoke(boost::detail::function::function_buffer&, T0, T1, T2) [with FunctionObj = boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >; R = void; T0 = int; T1 = siginfo*; T2 = void*]’: /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:907:38: required from ‘void boost::function3::assign_to(Functor) [with Functor = boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >; R = void; T0 = int; T1 = siginfo*; T2 = void*]’ /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:722:7: required from ‘boost::function3::function3(Functor, typename boost::enable_if_c::value>::value, int>::type) [with Functor = boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >; R = void; T0 = int; T1 = siginfo*; T2 = void*; typename boost::enable_if_c::value>::value, int>::type = int]’ /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:1042:16: required from ‘boost::function::function(Functor, typename boost::enable_if_c::value>::value, int>::type) [with Functor = boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >; R = void; T0 = int; T1 = siginfo*; T2 = void*; typename boost::enable_if_c::value>::value, int>::type = int]’ /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:41:58: required from here /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:153:57: error: no match for call to ‘(boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >) (int&, siginfo*&, void*&)’ BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); ^ /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:75:36: note: in definition of macro ‘BOOST_FUNCTION_RETURN’ # define BOOST_FUNCTION_RETURN(X) X

Is what I am trying to achieve possible, and if so, where have I gone wrong?

3
  • are you missing _2 and _3 after the _1 in your bind? Your callback is accepting 3 arguments so I think you need all 3 dummy arguments in the bind as well Commented Apr 27, 2015 at 16:57
  • Good spot -- you are correct. However, it still does not seem to work. I receive an error: `/home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp: In constructor ‘timesync::InputCapture::InputCapture(uint8_t)’: /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:40:19: error: cannot convert ‘boost::function<void(int, siginfo*, void*)>’ to ‘void ()(int, siginfo_t, void*) {aka void ()(int, siginfo, void*)}’ in assignment sig.sa_sigaction = boost::function<void (int n, siginfo_t *info, void *unused)> ( Commented Apr 27, 2015 at 17:30
  • Perhaps it has to do with the different between siginfo_t and siginfo* in the function parameters. Commented Apr 27, 2015 at 17:32

1 Answer 1

1

You cannot do this.

Note that sigaction::sa_sigaction is a pointer to function. Neither boost::function, nor the return value of boost::bind are convertible to a function pointer!

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, Igor. Do you know if there a C++ equivalent of sigation that I can use, which would allow me to bind to a member function?
@Andrew sigaction is a plain C function. For C++ equivalent, you can take a look at Boost.Asio library that provides signal_set object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.