Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I close a socket in a signal handler?

I'm writing a very simple server that loops forever until Ctrl-C is pressed. I'd like to have the signal handler for ctrl-c close the open sockets and shut down the server, but I don't know what the scope is for a signal handler, and I don't like the idea of declaring the socket(s) I would need to close to be global.

Can someone offer suggestions? Is there some standard way to do this?

like image 390
Zxaos Avatar asked Jan 16 '09 05:01

Zxaos


People also ask

What are you allowed to do in a signal handler?

Signal handlers can be specified for all but two signals (SIGKILL and SIGSTOP cannot be caught, blocked or ignored). If the signal reports an error within the program (and the signal is not asynchronous), the signal handler can terminate by calling abort() , exit() , or longjmp() .

Can you sleep in a signal handler?

The C standard pretty much only allows you to do one thing in a signal handler that affects global state. Set a volatile sig_atomic_t variable. Calling printf , sleep and such in a signal handler is not allowed.

Can a signal handler be interrupted?

The signal handler can indeed be interrupted by another signal (assuming it isn't the same signal as the one which invoked the handler in the first place). your handler can still be interrupted by delivery of another kind of signal.

What happens when a signal handler returns?

24.4. 1 Signal Handlers that ReturnSee Program Error Signals. Handlers that return normally must modify some global variable in order to have any effect. Typically, the variable is one that is examined periodically by the program during normal operation.


1 Answers

Well, since you have signal handlers, I'm going to assume you're on a Unix variant. If so:

  • A socket is identified to the kernel by the file number, which is an int. See socket(2).
  • That int is valid for your process
  • That int is valid for any processes forked after creating it
  • If not close-on-exec, it is valid for any process you exec.

So, it's perfectly valid in your signal handler. How you make your signal handler aware of which number to use depends on the language you're writing in, which you didn't specify. There are two approaches that will work in pretty much any language

  • If you don't have any cleanup to do except close and exit, just call exit. Or set the signal action to default, which is exit. The kernel will close the sockets.
  • Set a flag (which will generally be a global of some sort) to tell your select/poll loop to clean up and exit. Advantageous in that you don't have to worry about if various parts of your program are safe to call from a signal handler.
like image 123
derobert Avatar answered Nov 15 '22 23:11

derobert