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

jmp_buf  env;

void alarmHandler()
    {
        printf("\n in alarm Handle");

        longjmp(env,1);
    }



int main()
    {
        signal(SIGALRM,alarmHandler);

        alarm(2);

    for(;;)
    {
        printf("\nhello");
        sleep(1);

        if(setjmp(env))
            {

                printf("\n inside if");
                signal(SIGALRM,alarmHandler);
                alarm(2);
            }

    }


return 0;

    }

At start, actives monitor for signal then active alarm for 2 sec.(countdown). Inside the for loop, every time, it keeps saving setjmp(env) as time ends last setjmp(env) will be called using longjmp(). As setjmp() by default return 0 if called from longjmp(), whatever is second arg value is that value return.

neileap
  • 63
  • 3
  • 2
    Please indent your code; it is really hard to read when there's no indentation! – Jonathan Leffler Aug 09 '16 at 05:50
  • 1
    Note that `setjmp()` returns zero when first invoked, and returns non-zero when the return is from `longjmp()`. You should end your `printf()` with a newline, too. Otherwise, the output might not be seen. – Jonathan Leffler Aug 09 '16 at 05:54
  • @JonathanLeffler made change in `printf()` still not working! – neileap Aug 09 '16 at 06:01
  • See also [How to avoid using `printf()` in a signal handler](http://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler/). You shouldn't officially use `printf()` — or `strlen()` and a number of other surprising omissions from the list of safe functions — inside a signal handler. – Jonathan Leffler Aug 09 '16 at 06:01

2 Answers2

4

The longjmp function is not considered a safe function to call in signal handlers.

By jumping like that you never actually leave the signal handler, the context of the process will still be the context of the signal handler. So how could another signal handler be called when we haven't even left the first one? That's why you should not do what you do.

Instead set a flag in the signal handler, and poll that flag in your loop instead. Then return from the signal handler normally, and let the process go on like normal.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

I got this code to work on Mac OS X 10.11.6 with GCC 6.1.0, but there are multiple things that could prevent it working elsewhere. Amongst others, POSIX doesn't designate either longjmp() or siglongjmp() as safe for use in a signal handler (see POSIX Signal Concepts). You shouldn't use printf() — or strlen() either — in a signal handler.

My default compilation options require the alarm handler to be static or declared before defined; the argument is necessary to avoid mismatches in the type of the pointer passed to signal(); the signal number needs to be used (but I could have use longjmp(env, signum) to do that).

However, you can often get away with abusing the rules.

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

jmp_buf env;

static
void alarmHandler(int signum)
{
    printf("\nin alarm Handle (%d)\n", signum);
    longjmp(env, 1);
}

int main(void)
{
    signal(SIGALRM, alarmHandler);

    alarm(2);

    for ( ; ; )
    {
        printf("\nhello");
        sleep(1);

        if (setjmp(env))
        {
            printf("\ninside if\n");
            signal(SIGALRM, alarmHandler);
            alarm(2);
        }
    }
    printf("Exiting\n");

    return 0;
}

Sample output:

hello
hello
in alarm Handle (14)

inside if

hello
hello
in alarm Handle (14)

inside if

hello
hello
in alarm Handle (14)

inside if

hello
hello
in alarm Handle (14)

I got bored and interrupted it at that point.

I'm not sure if the addition of the newlines after the printf() statements is sufficient to make it work.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278