Why can't I call the function (signal handler) returned by function signal?

北慕城南 提交于 2019-12-13 02:15:27

问题


After figuring out the signature of the signal function, I modified the example given by https://en.cppreference.com/w/c/program/signal.

But why can't I call the function (the signal handler) returned by the signal, instead I can call it direclty ?


void (*signal( int sig, void (*handler) (int))) (int);

The signal function returns a pointer to function, which is void (*)(int).

Return value

Previous signal handler on success or SIG_ERR on failure (setting a signal handler can be disabled on some implementations).

#include <signal.h>
#include <stdio.h>

void signal_handler(int signal)
{
    printf("hahahah\n");
}

int main(void)
{
    void (*f1)(int);
    f1 = signal(SIGINT, signal_handler);
    f1(3);  //Get signal SIGSEGV and failed
//    signal_handler(3); //OK
    raise(SIGINT);

}

I know it might look like a meaningless question, but the point is, f1 points to signal_handler, so calling f1(3) is just like calling signal_handler(3), I don't understand why the latter is ok but not the former, there should be not "tricks" that can make between these two calling function statments, I think.


回答1:


In the following line:

f1 = signal(SIGINT, signal_handler);

f1 is assigned a previous signal handler (which is not signal_handler in the code) which may not be a pointer to a function that you can call with an int argument.

To achieve the effect you want to have define a second signal handler and assign it to f1 after the line mentioned above.

Something like this:

#include <signal.h>
#include <stdio.h>

void signal_handler2(int signal)
{
    printf("hahahah2222\n");
}

void signal_handler(int signal)
{
    printf("hahahah\n");
}

int main(void)
{
    void (*f1)(int);
    f1 = signal(SIGINT, signal_handler);
    f1 = signal(SIGINT, signal_handler2);
    f1(3);  //Success
    signal_handler2(3); //OK
    raise(SIGINT);    
}

Output:

hahahah
hahahah2222
hahahah2222

See Live Demo




回答2:


There are at least 3 values that signal() can return that are not pointers to real functions:

  1. SIG_DFL — typically ((void (*)(int))0)
  2. SIG_IGN — typically ((void (*)(int))1)
  3. SIG_ERR — typically ((void (*)(int))-1)

When a program starts, the signals are either in SIG_IGN or SIG_DFL mode; you can subsequently set them to another value.

When you call f1 = signal(SIGINT, signal_handler);, you get back one of SIG_DFL and SIG_IGN — and neither of those is a pointer to a callable function (even though their type is pointer to a function of the correct type).



来源:https://stackoverflow.com/questions/55390218/why-cant-i-call-the-function-signal-handler-returned-by-function-signal

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!