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
+}