/*
- * Copyright (C) 2004-2011 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2004-2013 Andre Noll <maan@systemlinux.org>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
* during the application's startup part, followed by subsequent calls
* to para_install_sighandler() for each signal that should be caught.
*
- * para_signal_init() installs a generic signal handler which is used for all
- * signals simultaneously. When a signal arrives, this generic signal handler
- * writes the corresponding signal number to the signal pipe so that the
- * application can test for pending signals simply by checking the signal pipe
- * for reading, e.g. by using the select(2) system call.
+ * A generic signal handler is used for all signals simultaneously. When a
+ * signal arrives, the signal handler writes the number of the signal received
+ * to one end of the signal pipe. The application can test for pending signals
+ * by checking if the file descriptor of the other end of the signal pipe is
+ * ready for reading, see select(2).
*
- * \return This function either succeeds or calls exit(2) to terminate
- * the current process. On success, the file descriptor of the signal pipe is
- * returned.
+ * \return This function either succeeds or calls exit(2) to terminate the
+ * current process. On success, the file descriptor of the read end of the
+ * signal pipe is returned.
*/
int para_signal_init(void)
{
exit(EXIT_FAILURE);
}
-/*
- * just write one integer to signal pipe
- */
+/* Write the signal number to signal pipe. */
static void generic_signal_handler(int s)
{
+ /*
+ * Signal handlers that make system calls must save a copy of errno on
+ * entry to the handler and restore it on exit, to prevent the
+ * possibility of overwriting a errno value that had previously been
+ * set in the main program.
+ */
+ int save_errno = errno;
ssize_t ret = write(signal_pipe[1], &s, sizeof(int));
- if (ret == sizeof(int))
+ if (ret == sizeof(int)) {
+ errno = save_errno;
return;
+ }
if (ret < 0)
PARA_EMERG_LOG("%s\n", strerror(errno));
else