UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#1 2009-09-16 03:49 AM

compkid
Member
Registered: 2009-09-03
Posts: 6

Re: signal handler

Hi, I want to write a code to handle signal. Suppose I am executing an infinite loop, if I press ctrl+d I want to get out of the loop. The program should not terminate however.

some thing like:

for(; ;)
   printf("\n I am inside for loop");

printf("\n For loop terminated");

Can some body write a sample code for this?

Offline

#2 2009-09-16 01:48 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: signal handler

Ctrl-D typically doesn't generate any signal that can be caught...  It simply simulates
an EOF event...  So, in order for your trick to work, you'd have to select() on stdin,
and try reading, to notice when you got EOF...

However, if you instead meant Ctrl-C, that does indeed generate SIGINT...  There are
various approaches you could use...  One simple one is just to set some static/global
variable from the handler, which you then check on to terminate your loop...  Eg:

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

static volatile int sigcnt;

static void handler (int sig)
{
    sigcnt++;
}

int main ()
{
    signal (SIGINT, handler);

    while (!sigcnt)
        printf ("Inside loop\n");

    printf ("\nOut of loop...\n");

    return (0);
}

Or, if you switched to low-level FD-based I/O, you could detect when you got hit
with the signal without needing an external variable...  Eg:

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

static void handler (int sig)
{
}

int main ()
{
    char *msg = "Inside loop\n";
    int len = strlen (msg);
    struct sigaction act;

    memset (&act, '\0', sizeof (act));
    act.sa_handler = handler;
    sigaction (SIGINT, &act, NULL);

    for (;;) {
        if (write (1, msg, len) < len)
            break;
    }

    printf ("\nOut of loop...\n");

    return (0);
}

Note: the sigaction() is necessary just to ensure your system doesn't auto-restart
interrupted syscalls, which it may do when just using signal()...

Another more complicated approach is to use sigsetjmp()/siglongjmp()...  Eg:

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

static sigjmp_buf sjbuf;

static void handler (int sig)
{
    siglongjmp (sjbuf, 1);
}

int main ()
{
    signal (SIGINT, handler);

    if (sigsetjmp (sjbuf, 1)) {
        printf ("\nOut of loop...\n");
    } else {
        for (;;)
            printf ("Inside loop\n");
    }

    return (0);
}

Offline

#3 2009-09-16 11:21 PM

compkid
Member
Registered: 2009-09-03
Posts: 6

Re: signal handler

Thanks RobSeace, that was really handy.

Offline

Board footer

Powered by FluxBB