summaryrefslogtreecommitdiff
path: root/bus/main.c
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2017-09-27 13:56:34 +0100
committerSimon McVittie <smcv@collabora.com>2017-09-27 15:14:12 +0100
commit3d538ced103c7955e6e62a72866e0f56cf3f52d6 (patch)
tree456e560503b59bff493ad1047b2cd43b84f94929 /bus/main.c
parent3d557ff7b155d1e0f1cdbfd82cff0ac7ed1b7c4b (diff)
downloaddbus-3d538ced103c7955e6e62a72866e0f56cf3f52d6.tar.gz
Make sure non-aborting signal handlers save and restore errno
If an async signal interrupts some function, we can have this anti-pattern: /* in normal code */ result = some_syscall (); /* fails, e.g. errno = EINVAL */ /* interrupted by async signal handler */ write (...); /* fails, e.g. errno = ENOBUFS */ /* back to normal code */ if (errno == EINVAL) /* problem! it should be but it isn't */ The solution is for signal handlers to save and restore errno. This is unnecessary for signal handlers that can't touch errno (like the one in dbus-launch that just sets a flag), and for signal handlers that never return (like the one in test-utils-glib for timeouts). Bug: https://bugs.freedesktop.org/show_bug.cgi?id=103010 Signed-off-by: Simon McVittie <smcv@collabora.com> Reviewed-by: Philip Withnall <withnall@endlessm.com>
Diffstat (limited to 'bus/main.c')
-rw-r--r--bus/main.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/bus/main.c b/bus/main.c
index 0ede03f7..b3fcddd0 100644
--- a/bus/main.c
+++ b/bus/main.c
@@ -67,6 +67,10 @@ typedef enum
static void
signal_handler (int sig)
{
+ /* Signal handlers that might set errno must save and restore the errno
+ * that the interrupted function might have been relying on. */
+ int saved_errno = errno;
+
switch (sig)
{
case SIGHUP:
@@ -134,6 +138,8 @@ signal_handler (int sig)
* signal, but keep -Wswitch-default happy */
break;
}
+
+ errno = saved_errno;
}
#endif /* DBUS_UNIX */