mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-08 09:08:15 +02:00
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>
This commit is contained in:
parent
3d557ff7b1
commit
3d538ced10
2 changed files with 12 additions and 0 deletions
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -1138,11 +1138,17 @@ static int babysit_sigchld_pipe = -1;
|
|||
static void
|
||||
babysit_signal_handler (int signo)
|
||||
{
|
||||
/* 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;
|
||||
char b = '\0';
|
||||
|
||||
again:
|
||||
if (write (babysit_sigchld_pipe, &b, 1) <= 0)
|
||||
if (errno == EINTR)
|
||||
goto again;
|
||||
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
static void babysit (pid_t grandchild_pid,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue