开发者

Can we pass parameters to signals in C?

开发者 https://www.devze.com 2023-02-17 02:33 出处:网络
I am implementing a Simple Iterative TCP client/server in C. The server is infinitely listing in a loop.

I am implementing a Simple Iterative TCP client/server in C. The server is infinitely listing in a loop.

Now if Ctrl+c (SIGINT) occurred at any point of time, how would I free up the resources used in server?

F开发者_开发百科or example, I caught the signal in my own signal handler; how would I get socket descriptors and buffers used in the program so as to free them?

I new to socket programming; any suggestions would be appreciated.


Don't install a signal handler. Don't do anything. The default action for SIGINT is to terminate the process, and assuming no other processes have descriptors for your sockets, they'll all naturally be closed and cease to exist when the process terminates.


No. The only parameter passed to your signal handler is an int which is the signal number.

The typical way to deal with the situation you describe is having a global variable such as int stopAndExit that your loop is checking. If it gets flipped to 1 by the signal handler you know to clean up and exit.

Edit: For a more thorough discussion prompted by comments below.

One problem with this is if you are in a non-reentrant function when the signal arrives. To deal with this, you actually want to delay (block) signals, then handle them at a point in your main loop that is safe.

Last Edit: Unless you have some external operations occurring that need to be cleaned up before so you guarantee you exit in a clean state ... it doesn't matter. Your socket descriptors and buffers are all going away anyway when you exit. There's no need to clean up anything.


The code in this answer is horrendously unsafe, invokes all kinds of UB, and shouldn't be used in your case. Using setjmp / longjmp in a signal handler is only remotely workable as a way to deal with null pointer dereferences, and even then it needs to be extremely limited in scope to avoid invoking UB.

Here's another possible way of dealing with cleanup:

static jmp_buf buf;
static int ret = 0;

void handle(int sig)
{
    ret = 1;
    longjmp(buf, 1);
}

int func(void)
{
    FILE *f = fopen(/* yadda */);

    void (*orig)(int) = signal(SIGINT, handle);

    if(setjmp(buf)) goto CLEANUP;

    // use f

  CLEANUP:
    fclose(f);
    signal(SIGINT, orig);
    return ret;
}

Of course, doing a whole lot of hard work in a signal handler isn't guaranteed to work by the standard, but I'm sure if you were worried about that you wouldn't be trying to handle the signal.

0

精彩评论

暂无评论...
验证码 换一张
取 消