Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
299 views
in Technique[技术] by (71.8m points)

c - why is a signal-handler calling signal() in his method-body?

In university we are currently learning about daemons and how to handle signals. But why is the signal-handler calling signal()? In the main-method signal(...) is already being called. So to my understanding when pkill -SIGUSR1 for example is sent to the thread the one signal(...)call in the main-method should be sufficient in catching and delegating to the handler. Maybe someone can explain.

In our textbook there is this example:

void sighandler (int sig) {
printf ("Caught signal %d
", sig);
signal (SIGINT, sighandler);
signal (SIGALRM, sighandler);
}

int main (int argc, char *argv [], char *envp []) {

char buffer [1024];
int len;
signal (SIGINT, sighandler);
signal (SIGALRM, sighandler);
alarm (5);

for (len = 0; len < 10; len++)
 printf ("Counting %d...
", len), sleep (1);

alarm (10);

while (1) {

 len = read (0, buffer, sizeof (buffer) - 1);

 if (len == -1) {
  perror ("read () failed");
  continue;
  }

 if (len == 0) {
  printf ("Exiting
");
  exit (0);
  }

 buffer [len] = '';

 if (!strncmp (buffer, "exit", 4))
  exit (0);

 write (1, buffer, strlen (buffer));
  }
}
question from:https://stackoverflow.com/questions/65598703/why-is-a-signal-handler-calling-signal-in-his-method-body

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Answer

The code is re-installing the signal handlers so that subsequent SIGINTs and SIGALRMs invoke the same signal handler again.

Why? Historically, some implementations of signal() reset the signal disposition to the default (SIG_DFL) upon invoking a user-defined signal handler, effectively making the signal handler a "one shot" affair. Some did not do this.

Thus, a common practice was to have user-defined signal handlers re-install themselves to make the handler effectively permanent. (On systems that did not reset disposition, this merely made the signal handler slightly less efficient by introducing a pointless syscall.)

sigaction(), the successor to signal() which was standardized in POSIX.1-1988, resolves this ambiguity by providing a flag, SA_RESETHAND, to control whether or not the handler is reset.


Aside

The commenters above are quite right: the code you are studying is a bad example.

Any use of signal() is dubious in modern, production-quality code. That alone would not pass code review in many shops.

Even allowing signal(), the fact that the handler is not re-installed right away, before the printf(), is a bit odd.

printf() is not async-signal-safe. In very simple toy programs it can be used without problems in a signal handler, but even this very example is not safe. What if the printf() in the handler is called during the main loop's printf()? What if that five second ALRM handler call interrupts an INT handler call?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...