-/*
- * Copyright (C) 2004-2010 Andre Noll <maan@systemlinux.org>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* SPDX-License-Identifier: GPL-2.0 */
#include <string.h>
#include <errno.h>
#include "log.h"
#include "str.h"
#include "file.h"
+#include "sig.h"
static int signal_pipe[2];
goto err_out;
return signal_pipe[0];
err_out:
- DSS_EMERG_LOG("%s\n", dss_strerror(-ret));
+ DSS_EMERG_LOG(("%s\n", dss_strerror(-ret)));
exit(EXIT_FAILURE);
}
-/*
- * just write one integer to signal pipe
- */
+/* Write the signal number to the signal pipe, abort on errors. */
static void generic_signal_handler(int s)
{
- write(signal_pipe[1], &s, sizeof(int));
+ /*
+ * 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)) {
+ errno = save_errno;
+ return;
+ }
+ if (ret < 0)
+ DSS_EMERG_LOG(("%s\n", strerror(errno)));
+ else
+ DSS_EMERG_LOG(("short write to signal pipe\n"));
+ exit(EXIT_FAILURE);
}
/**
if (*pid < 0)
return -ERRNO_TO_DSS_ERROR(errno);
if (WIFEXITED(*status))
- DSS_DEBUG_LOG("child %i exited. Exit status: %i\n", (int)*pid,
- WEXITSTATUS(*status));
+ DSS_DEBUG_LOG(("child %i exited. Exit status: %i\n", (int)*pid,
+ WEXITSTATUS(*status)));
else if (WIFSIGNALED(*status))
- DSS_DEBUG_LOG("child %i was killed by signal %i\n", (int)*pid,
- WTERMSIG(*status));
+ DSS_DEBUG_LOG(("child %i was killed by signal %i\n", (int)*pid,
+ WTERMSIG(*status)));
else
- DSS_WARNING_LOG("child %i terminated abormally\n", (int)*pid);
+ DSS_WARNING_LOG(("child %i terminated abormally\n", (int)*pid));
return 1;
}
*/
int install_sighandler(int sig)
{
- DSS_DEBUG_LOG("catching signal %d\n", sig);
+ DSS_DEBUG_LOG(("catching signal %d\n", sig));
if (signal(sig, &generic_signal_handler) != SIG_ERR)
return 1;
return -E_SIGNAL_SIG_ERR;
r = read(signal_pipe[0], &s, sizeof(s));
if (r == sizeof(s)) {
- DSS_DEBUG_LOG("next signal: %d\n", s);
+ DSS_DEBUG_LOG(("next signal: %d\n", s));
return s;
}
err = errno;
assert(r < 0);
if (err == EAGAIN)
return 0;
- DSS_ERROR_LOG("failed to read from signal pipe\n");
+ DSS_ERROR_LOG(("failed to read from signal pipe\n"));
return -ERRNO_TO_DSS_ERROR(err);
}