Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

332 Signals Chapter 10


#include "apue.h"
#include <pwd.h>
static void
my_alarm(int signo)
{
struct passwd *rootptr;
printf("in signal handler\n");
if ((rootptr = getpwnam("root")) == NULL)
err_sys("getpwnam(root) error");
alarm(1);
}
int
main(void)
{
struct passwd *ptr;
signal(SIGALRM, my_alarm);
alarm(1);
for ( ; ; ) {
if ((ptr = getpwnam("sar")) == NULL)
err_sys("getpwnam error");
if (strcmp(ptr->pw_name, "sar") != 0)
printf("return value corrupted!, pw_name = %s\n",
ptr->pw_name);
}
}

Figure 10.5Call a nonreentrant function from a signal handler

When this program was run, the results wererandom. Usually,the program would
be terminated by aSIGSEGVsignal when the signal handler returned after several
iterations. An examination of thecorefile showed that themainfunction had called
getpwnam,but that whengetpwnamcalledfree,the signal handler interrupted it and
calledgetpwnam,which in turn calledfree.The data structures maintained by
mallocandfreehad been corrupted when the signal handler (indirectly) calledfree
while themainfunction was also callingfree.Occasionally,the program would run
for several seconds beforecrashing with aSIGSEGVerror.When themainfunction did
runcorrectly after the signal had been caught, the return value was sometimes
corrupted and sometimes fine.
As shown by this example, if we call a nonreentrant function from a signal handler,
the results areunpredictable.

10.7 SIGCLDSemantics


Twosignals that continually generate confusion areSIGCLDandSIGCHLD.The name
SIGCLD(without theH) is fromSystem V,and this signal has different semantics from
the BSD signal, namedSIGCHLD.The POSIX.1 signal is also namedSIGCHLD.
Free download pdf