Avoid multiple definitions of sigaction.
Before this change, we have the kernel's sigaction in the uapi headers,
and our own sigaction in <bits/signal_types.h> and we rely on callers
making sure to use `#define` to move the kernel type out of the way if
they include a uapi header directly. This is obviously error-prone and
undesireable, and not what we usually do now.
What we _usually_ do now is use the header scrubber's ability to replace
a struct definition with a `#include <bits/STRUCT.h>`, but that doesn't
work here because struct sigaction relies on a lot of other types,
some of which also come from uapi headers.
So instead use our second best trick, which is to "move the kernel struct
out of the way" at header scrubbing time instead. This means that someone
who does `#include <linux/signal.h>` or `#include <asm/signal.h>` won't
get `struct sigaction` (they'll only have `struct __kernel_sigaction`
instead), but it does mean that they can't get two incompatible
definitions if they include a uapi header both directly and indirectly.
So although this doesn't do what I'd set out to do, it's still an
improvement in some cases, and it's our preferred idiom in most cases
anyway. (I'll come back once this is in to tidy up the two other kernel
structs where we're still using the deprecated "rename out of the way
using #define" trick, but this change is already hairy enough, and
there's a possibility it will break code that didn't care that it was
getting the kernel `struct sigaction` rather than the userspace one.)
Bug: http://b/236042740
Test: treehugger
Change-Id: Icff50e330c09c587e8f77ba0fb7cffffd9c3b708
diff --git a/libc/include/bits/signal_types.h b/libc/include/bits/signal_types.h
index 699e257..d98901c 100644
--- a/libc/include/bits/signal_types.h
+++ b/libc/include/bits/signal_types.h
@@ -28,18 +28,11 @@
#pragma once
-#include <limits.h>
#include <sys/cdefs.h>
-#include <sys/types.h>
-/* For 64-bit, the kernel's struct sigaction doesn't match the POSIX one,
- * so we need to expose our own and translate behind the scenes.
- * For 32-bit, we're stuck with the definitions we already shipped,
- * even though they contain a sigset_t that's too small. See sigaction64.
- */
-#define sigaction __kernel_sigaction
+#include <limits.h>
#include <linux/signal.h>
-#undef sigaction
+#include <sys/types.h>
/* The arm and x86 kernel header files don't define _NSIG. */
#ifndef _KERNEL__NSIG
@@ -64,8 +57,13 @@
typedef struct { unsigned long __bits[_KERNEL__NSIG/(8*sizeof(long))]; } sigset64_t;
#endif
+/* The kernel's struct sigaction doesn't match the POSIX one. */
+
#if defined(__LP64__)
+/* For 64-bit, that's the only problem, and we only need two structs
+ * for source compatibility with 32-bit. */
+
#define __SIGACTION_BODY \
int sa_flags; \
union { \
@@ -82,6 +80,12 @@
#else
+/* For 32-bit, Android's ABIs used a too-small sigset_t that doesn't
+ * support RT signals, so we need two different structs.
+ */
+
+/* The arm32 kernel headers also pollute the namespace with these,
+ * but our header scrubber doesn't know how to remove #defines. */
#undef sa_handler
#undef sa_sigaction
@@ -95,7 +99,6 @@
void (*sa_restorer)(void);
};
-/* This matches the kernel's internal structure. */
struct sigaction64 {
union {
sighandler_t sa_handler;
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index ac12fc7..5340216 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -97,6 +97,9 @@
# Remove unused macros (http://b/262917450).
"__force": "",
"__user": "",
+ # Rename the kernel's sigaction so we can expose our POSIX one publicly,
+ # but translate to the kernel's one internally.
+ "sigaction": "__kernel_sigaction",
}
diff --git a/libc/kernel/uapi/asm-arm/asm/signal.h b/libc/kernel/uapi/asm-arm/asm/signal.h
index 838bb13..fde3b9e 100644
--- a/libc/kernel/uapi/asm-arm/asm/signal.h
+++ b/libc/kernel/uapi/asm-arm/asm/signal.h
@@ -52,7 +52,7 @@
#define MINSIGSTKSZ 2048
#define SIGSTKSZ 8192
#include <asm-generic/signal-defs.h>
-struct sigaction {
+struct __kernel_sigaction {
union {
__sighandler_t _sa_handler;
void(* _sa_sigaction) (int, struct siginfo *, void *);
diff --git a/libc/kernel/uapi/asm-generic/signal.h b/libc/kernel/uapi/asm-generic/signal.h
index bea99a7..21c7100 100644
--- a/libc/kernel/uapi/asm-generic/signal.h
+++ b/libc/kernel/uapi/asm-generic/signal.h
@@ -61,7 +61,7 @@
#ifdef SA_RESTORER
#define __ARCH_HAS_SA_RESTORER
#endif
-struct sigaction {
+struct __kernel_sigaction {
__sighandler_t sa_handler;
unsigned long sa_flags;
#ifdef SA_RESTORER
diff --git a/libc/kernel/uapi/asm-x86/asm/signal.h b/libc/kernel/uapi/asm-x86/asm/signal.h
index 2e51445..96ac8fb 100644
--- a/libc/kernel/uapi/asm-x86/asm/signal.h
+++ b/libc/kernel/uapi/asm-x86/asm/signal.h
@@ -56,7 +56,7 @@
#include <asm-generic/signal-defs.h>
#ifndef __ASSEMBLY__
#ifdef __i386__
-struct sigaction {
+struct __kernel_sigaction {
union {
__sighandler_t _sa_handler;
void(* _sa_sigaction) (int, struct siginfo *, void *);
@@ -68,7 +68,7 @@
#define sa_handler _u._sa_handler
#define sa_sigaction _u._sa_sigaction
#else
-struct sigaction {
+struct __kernel_sigaction {
__sighandler_t sa_handler;
unsigned long sa_flags;
__sigrestore_t sa_restorer;