Merge "Make `union semun` usable."
diff --git a/libc/include/sys/sem.h b/libc/include/sys/sem.h
index 904c334..be0e22d 100644
--- a/libc/include/sys/sem.h
+++ b/libc/include/sys/sem.h
@@ -39,9 +39,17 @@
 
 #include <linux/sem.h>
 
+__BEGIN_DECLS
+
 #define semid_ds semid64_ds
 
-__BEGIN_DECLS
+union semun {
+  int val;
+  struct semid_ds* buf;
+  unsigned short* array;
+  struct seminfo* __buf;
+  void* __pad;
+};
 
 int semctl(int, int, int, ...) __INTRODUCED_IN(26);
 int semget(key_t, int, int) __INTRODUCED_IN(26);
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index c22f684..5198dbe 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -70,6 +70,8 @@
     "semid_ds": "__kernel_legacy_semid_ds",
     "shmid_ds": "__kernel_legacy_shmid_ds",
     "ipc_perm": "__kernel_legacy_ipc_perm",
+    # The kernel semun isn't usable (https://github.com/android-ndk/ndk/issues/400).
+    "semun": "__kernel_legacy_semun",
     # The kernel's _NSIG/NSIG are one less than the userspace value, so we need to move them aside.
     "_NSIG": "_KERNEL__NSIG",
     "NSIG": "_KERNEL_NSIG",
diff --git a/libc/kernel/uapi/linux/sem.h b/libc/kernel/uapi/linux/sem.h
index 6916556..df815db 100644
--- a/libc/kernel/uapi/linux/sem.h
+++ b/libc/kernel/uapi/linux/sem.h
@@ -52,7 +52,7 @@
   short sem_flg;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
-union semun {
+union __kernel_legacy_semun {
   int val;
   struct __kernel_legacy_semid_ds __user * buf;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/tests/sys_sem_test.cpp b/tests/sys_sem_test.cpp
index d8d83c5..eaf2b8f 100644
--- a/tests/sys_sem_test.cpp
+++ b/tests/sys_sem_test.cpp
@@ -98,3 +98,19 @@
   ASSERT_EQ(-1, semtimedop(-1, nullptr, 0, nullptr));
   ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
 }
+
+TEST(sys_sem, union_semun) {
+  // https://github.com/android-ndk/ndk/issues/400
+#if defined(__BIONIC__)
+  semun arg;
+  semid_ds i1;
+  seminfo i2;
+  unsigned short a[] = { 1u, 2u };
+  arg.val = 123;
+  arg.buf = &i1;
+  arg.array = a;
+  arg.__buf = &i2;
+#else
+  // glibc already mostly removed this cruft (although it's still in <linux/sem.h>).
+#endif
+}