问题
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:
SIG_DFL
— typically((void (*)(int))0)
SIG_IGN
— typically((void (*)(int))1)
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