Add `sigset64_t` and accompanying functions.

This doesn't address `struct sigaction` and `sigaction`. That will
come later.

Bug: http://b/72493232
Test: ran tests
Change-Id: I4134346757ce3a4dac6feae413361cec16223386
diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp
index 9f1c31f..ec26a50 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -32,8 +32,6 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 
-#include "private/kernel_sigset_t.h"
-
 // We call tgkill(2) directly instead of raise (or even the libc tgkill wrapper), to reduce the
 // number of uninteresting stack frames at the top of a crash.
 static inline __always_inline void inline_tgkill(pid_t pid, pid_t tid, int sig) {
@@ -62,11 +60,11 @@
 
   // Don't block SIGABRT to give any signal handler a chance; we ignore
   // any errors -- X311J doesn't allow abort to return anyway.
-  kernel_sigset_t mask;
-  mask.fill();
-  mask.clear(SIGABRT);
-  __rt_sigprocmask(SIG_SETMASK, &mask, nullptr, sizeof(mask));
+  sigset64_t mask;
+  sigfillset64(&mask);
+  sigdelset64(&mask, SIGABRT);
 
+  sigprocmask64(SIG_SETMASK, &mask, nullptr);
   inline_tgkill(pid, tid, SIGABRT);
 
   // If SIGABRT ignored, or caught and the handler returns,
@@ -76,8 +74,8 @@
   sa.sa_flags   = SA_RESTART;
   sigemptyset(&sa.sa_mask);
   sigaction(SIGABRT, &sa, &sa);
-  __rt_sigprocmask(SIG_SETMASK, &mask, nullptr, sizeof(mask));
 
+  sigprocmask64(SIG_SETMASK, &mask, nullptr);
   inline_tgkill(pid, tid, SIGABRT);
 
   // If we get this far, just exit.
diff --git a/libc/bionic/epoll_create.cpp b/libc/bionic/epoll_create.cpp
deleted file mode 100644
index 74f664f..0000000
--- a/libc/bionic/epoll_create.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <sys/epoll.h>
-
-int epoll_create(int size) {
-  if (size <= 0) {
-    errno = EINVAL;
-    return -1;
-  }
-  return epoll_create1(0);
-}
diff --git a/libc/bionic/epoll_wait.cpp b/libc/bionic/epoll_wait.cpp
deleted file mode 100644
index deb19da..0000000
--- a/libc/bionic/epoll_wait.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/epoll.h>
-
-int epoll_wait(int fd, struct epoll_event* events, int max_events, int timeout) {
-  return epoll_pwait(fd, events, max_events, timeout, NULL);
-}
diff --git a/libc/bionic/pause.cpp b/libc/bionic/pause.cpp
index 2a0779a..534a804 100644
--- a/libc/bionic/pause.cpp
+++ b/libc/bionic/pause.cpp
@@ -26,12 +26,10 @@
  * SUCH DAMAGE.
  */
 
+#include <signal.h>
 #include <unistd.h>
 
-#include "private/kernel_sigset_t.h"
-
 int pause() {
-  kernel_sigset_t mask;
-  if (__rt_sigprocmask(SIG_SETMASK, nullptr, &mask, sizeof(mask)) == -1) return -1;
-  return __rt_sigsuspend(&mask, sizeof(mask));
+  sigset64_t mask = {};
+  return sigsuspend64(&mask);
 }
diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp
index dbc9584..1d72fe5 100644
--- a/libc/bionic/poll.cpp
+++ b/libc/bionic/poll.cpp
@@ -31,51 +31,56 @@
 #include <sys/select.h>
 
 #include "private/bionic_time_conversions.h"
-#include "private/kernel_sigset_t.h"
+#include "private/SigSetConverter.h"
 
-extern "C" int __ppoll(pollfd*, unsigned int, timespec*, const kernel_sigset_t*, size_t);
+extern "C" int __ppoll(pollfd*, unsigned int, timespec*, const sigset64_t*, size_t);
 extern "C" int __pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*);
 
 int poll(pollfd* fds, nfds_t fd_count, int ms) __overloadable {
   timespec ts;
-  timespec* ts_ptr = NULL;
+  timespec* ts_ptr = nullptr;
   if (ms >= 0) {
     timespec_from_ms(ts, ms);
     ts_ptr = &ts;
   }
-  return __ppoll(fds, fd_count, ts_ptr, NULL, 0);
+  return __ppoll(fds, fd_count, ts_ptr, nullptr, 0);
 }
 
 int ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) __overloadable {
+  // The underlying `__ppoll` system call only takes `sigset64_t`.
+  SigSetConverter set;
+  sigset64_t* ss_ptr = nullptr;
+  if (ss != nullptr) {
+    set = {};
+    set.sigset = *ss;
+    ss_ptr = &set.sigset64;
+  }
+  return ppoll64(fds, fd_count, ts, ss_ptr);
+}
+
+int ppoll64(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset64_t* ss) {
+  // The underlying __ppoll system call modifies its `struct timespec` argument.
   timespec mutable_ts;
-  timespec* mutable_ts_ptr = NULL;
-  if (ts != NULL) {
+  timespec* mutable_ts_ptr = nullptr;
+  if (ts != nullptr) {
     mutable_ts = *ts;
     mutable_ts_ptr = &mutable_ts;
   }
-
-  kernel_sigset_t kernel_ss;
-  kernel_sigset_t* kernel_ss_ptr = NULL;
-  if (ss != NULL) {
-    kernel_ss.set(ss);
-    kernel_ss_ptr = &kernel_ss;
-  }
-
-  return __ppoll(fds, fd_count, mutable_ts_ptr, kernel_ss_ptr, sizeof(kernel_ss));
+  return __ppoll(fds, fd_count, mutable_ts_ptr, ss, sizeof(*ss));
 }
 
 int select(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, timeval* tv) {
   timespec ts;
-  timespec* ts_ptr = NULL;
-  if (tv != NULL) {
+  timespec* ts_ptr = nullptr;
+  if (tv != nullptr) {
     if (!timespec_from_timeval(ts, *tv)) {
       errno = EINVAL;
       return -1;
     }
     ts_ptr = &ts;
   }
-  int result = __pselect6(fd_count, read_fds, write_fds, error_fds, ts_ptr, NULL);
-  if (tv != NULL) {
+  int result = __pselect6(fd_count, read_fds, write_fds, error_fds, ts_ptr, nullptr);
+  if (tv != nullptr) {
     timeval_from_timespec(*tv, ts);
   }
   return result;
@@ -83,20 +88,27 @@
 
 int pselect(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
             const timespec* ts, const sigset_t* ss) {
+  // The underlying `__pselect6` system call only takes `sigset64_t`.
+  SigSetConverter set;
+  sigset64_t* ss_ptr = nullptr;
+  if (ss != nullptr) {
+    set = {};
+    set.sigset = *ss;
+    ss_ptr = &set.sigset64;
+  }
+  return pselect64(fd_count, read_fds, write_fds, error_fds, ts, ss_ptr);
+}
+
+int pselect64(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
+              const timespec* ts, const sigset64_t* ss) {
+  // The underlying __pselect6 system call modifies its `struct timespec` argument.
   timespec mutable_ts;
-  timespec* mutable_ts_ptr = NULL;
-  if (ts != NULL) {
+  timespec* mutable_ts_ptr = nullptr;
+  if (ts != nullptr) {
     mutable_ts = *ts;
     mutable_ts_ptr = &mutable_ts;
   }
 
-  kernel_sigset_t kernel_ss;
-  kernel_sigset_t* kernel_ss_ptr = NULL;
-  if (ss != NULL) {
-    kernel_ss.set(ss);
-    kernel_ss_ptr = &kernel_ss;
-  }
-
   // The Linux kernel only handles 6 arguments and this system call really needs 7,
   // so the last argument is a void* pointing to:
   struct pselect6_extra_data_t {
@@ -104,8 +116,8 @@
     size_t ss_len;
   };
   pselect6_extra_data_t extra_data;
-  extra_data.ss_addr = reinterpret_cast<uintptr_t>(kernel_ss_ptr);
-  extra_data.ss_len = sizeof(kernel_ss);
+  extra_data.ss_addr = reinterpret_cast<uintptr_t>(ss);
+  extra_data.ss_len = sizeof(*ss);
 
   return __pselect6(fd_count, read_fds, write_fds, error_fds, mutable_ts_ptr, &extra_data);
 }
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index e3bb112..2edfe97 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -26,8 +26,6 @@
  * SUCH DAMAGE.
  */
 
-#include "private/kernel_sigset_t.h"
-
 #include <errno.h>
 #include <malloc.h>
 #include <pthread.h>
@@ -37,7 +35,6 @@
 #include <time.h>
 
 // System calls.
-extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t);
 extern "C" int __timer_create(clockid_t, sigevent*, __kernel_timer_t*);
 extern "C" int __timer_delete(__kernel_timer_t);
 extern "C" int __timer_getoverrun(__kernel_timer_t);
@@ -74,16 +71,13 @@
 static void* __timer_thread_start(void* arg) {
   PosixTimer* timer = reinterpret_cast<PosixTimer*>(arg);
 
-  kernel_sigset_t sigset{TIMER_SIGNAL};
+  sigset64_t sigset = {};
+  sigaddset64(&sigset, TIMER_SIGNAL);
 
   while (true) {
     // Wait for a signal...
-    siginfo_t si;
-    memset(&si, 0, sizeof(si));
-    int rc = __rt_sigtimedwait(sigset.get(), &si, NULL, sizeof(sigset));
-    if (rc == -1) {
-      continue;
-    }
+    siginfo_t si = {};
+    if (sigtimedwait64(&sigset, &si, nullptr) == -1) continue;
 
     if (si.si_code == SI_TIMER) {
       // This signal was sent because a timer fired, so call the callback.
@@ -149,13 +143,14 @@
 
   // We start the thread with TIMER_SIGNAL blocked by blocking the signal here and letting it
   // inherit. If it tried to block the signal itself, there would be a race.
-  kernel_sigset_t sigset{TIMER_SIGNAL};
-  kernel_sigset_t old_sigset;
-  __rt_sigprocmask(SIG_BLOCK, &sigset, &old_sigset, sizeof(sigset));
+  sigset64_t sigset = {};
+  sigaddset64(&sigset, TIMER_SIGNAL);
+  sigset64_t old_sigset;
+  sigprocmask64(SIG_BLOCK, &sigset, &old_sigset);
 
   int rc = pthread_create(&timer->callback_thread, &thread_attributes, __timer_thread_start, timer);
 
-  __rt_sigprocmask(SIG_SETMASK, &old_sigset, nullptr, sizeof(sigset));
+  sigprocmask64(SIG_SETMASK, &old_sigset, nullptr);
 
   if (rc != 0) {
     free(timer);
diff --git a/libc/bionic/pthread_sigmask.cpp b/libc/bionic/pthread_sigmask.cpp
deleted file mode 100644
index 79f31a1..0000000
--- a/libc/bionic/pthread_sigmask.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include "private/ErrnoRestorer.h"
-
-int pthread_sigmask(int how, const sigset_t* new_set, sigset_t* old_set) {
-  ErrnoRestorer errno_restorer;
-  int result = sigprocmask(how, new_set, old_set);
-  return (result == -1) ? errno : 0;
-}
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index 9a23416..099944a 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -30,19 +30,36 @@
 #include <pthread.h>
 #include <signal.h>
 #include <string.h>
+#include <sys/epoll.h>
+#include <sys/signalfd.h>
 #include <sys/types.h>
 #include <time.h>
 #include <unistd.h>
 
-#include "private/kernel_sigset_t.h"
+#include "private/ErrnoRestorer.h"
+#include "private/SigSetConverter.h"
 
+extern "C" int __rt_sigpending(const sigset64_t*, size_t);
+extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
 extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
-extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t);
+extern "C" int __rt_sigsuspend(const sigset64_t*, size_t);
+extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t);
 
-int sigaddset(sigset_t* set, int signum) {
-  int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
+int pthread_sigmask(int how, const sigset_t* new_set, sigset_t* old_set) {
+  ErrnoRestorer errno_restorer;
+  return (sigprocmask(how, new_set, old_set) == -1) ? errno : 0;
+}
+
+int pthread_sigmask64(int how, const sigset64_t* new_set, sigset64_t* old_set) {
+  ErrnoRestorer errno_restorer;
+  return (sigprocmask64(how, new_set, old_set) == -1) ? errno : 0;
+}
+
+template <typename SigSetT>
+int SigAddSet(SigSetT* set, int sig) {
+  int bit = sig - 1; // Signal numbers start at 1, but bit positions start at 0.
   unsigned long* local_set = reinterpret_cast<unsigned long*>(set);
-  if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
+  if (set == nullptr || bit < 0 || bit >= static_cast<int>(8*sizeof(*set))) {
     errno = EINVAL;
     return -1;
   }
@@ -50,24 +67,28 @@
   return 0;
 }
 
-// This isn't in our header files, but is exposed on all architectures.
-extern "C" int sigblock(int mask) {
-  union {
-    int mask;
-    sigset_t set;
-  } in, out;
-
-  sigemptyset(&in.set);
-  in.mask = mask;
-
-  if (sigprocmask(SIG_BLOCK, &in.set, &out.set) == -1) return -1;
-  return out.mask;
+int sigaddset(sigset_t* set, int sig) {
+  return SigAddSet(set, sig);
 }
 
-int sigdelset(sigset_t* set, int signum) {
-  int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
+int sigaddset64(sigset64_t* set, int sig) {
+  return SigAddSet(set, sig);
+}
+
+// This isn't in our header files, but is exposed on all architectures.
+extern "C" int sigblock(int mask) {
+  SigSetConverter in, out;
+  sigemptyset(&in.sigset);
+  in.bsd = mask;
+  if (sigprocmask(SIG_BLOCK, &in.sigset, &out.sigset) == -1) return -1;
+  return out.bsd;
+}
+
+template <typename SigSetT>
+int SigDelSet(SigSetT* set, int sig) {
+  int bit = sig - 1; // Signal numbers start at 1, but bit positions start at 0.
   unsigned long* local_set = reinterpret_cast<unsigned long*>(set);
-  if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
+  if (set == nullptr || bit < 0 || bit >= static_cast<int>(8*sizeof(*set))) {
     errno = EINVAL;
     return -1;
   }
@@ -75,29 +96,54 @@
   return 0;
 }
 
-int sigemptyset(sigset_t* set) {
-  if (set == NULL) {
+int sigdelset(sigset_t* set, int sig) {
+  return SigDelSet(set, sig);
+}
+
+int sigdelset64(sigset64_t* set, int sig) {
+  return SigDelSet(set, sig);
+}
+
+template <typename SigSetT>
+int SigEmptySet(SigSetT* set) {
+  if (set == nullptr) {
     errno = EINVAL;
     return -1;
   }
-  memset(set, 0, sizeof(sigset_t));
+  memset(set, 0, sizeof(*set));
+  return 0;
+}
+
+int sigemptyset(sigset_t* set) {
+  return SigEmptySet(set);
+}
+
+int sigemptyset64(sigset64_t* set) {
+  return SigEmptySet(set);
+}
+
+template <typename SigSetT>
+int SigFillSet(SigSetT* set) {
+  if (set == nullptr) {
+    errno = EINVAL;
+    return -1;
+  }
+  memset(set, 0xff, sizeof(*set));
   return 0;
 }
 
 int sigfillset(sigset_t* set) {
-  if (set == NULL) {
-    errno = EINVAL;
-    return -1;
-  }
-  memset(set, ~0, sizeof(sigset_t));
-  return 0;
+  return SigFillSet(set);
+}
+
+int sigfillset64(sigset64_t* set) {
+  return SigFillSet(set);
 }
 
 int sighold(int sig) {
-  kernel_sigset_t set;
-  set.clear();
-  if (!set.set(sig)) return -1;
-  return __rt_sigprocmask(SIG_BLOCK, &set, nullptr, sizeof(set));
+  sigset64_t set = {};
+  if (sigaddset64(&set, sig) == -1) return -1;
+  return sigprocmask64(SIG_BLOCK, &set, nullptr);
 }
 
 int sigignore(int sig) {
@@ -119,87 +165,100 @@
   return sigaction(sig, &act, nullptr);
 }
 
-int sigismember(const sigset_t* set, int signum) {
-  int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
+template <typename SigSetT>
+int SigIsMember(const SigSetT* set, int sig) {
+  int bit = sig - 1; // Signal numbers start at 1, but bit positions start at 0.
   const unsigned long* local_set = reinterpret_cast<const unsigned long*>(set);
-  if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
+  if (set == nullptr || bit < 0 || bit >= static_cast<int>(8*sizeof(*set))) {
     errno = EINVAL;
     return -1;
   }
   return static_cast<int>((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1);
 }
 
-__LIBC_HIDDEN__ sighandler_t _signal(int signum, sighandler_t handler, int flags) {
+int sigismember(const sigset_t* set, int sig) {
+  return SigIsMember(set, sig);
+}
+
+int sigismember64(const sigset64_t* set, int sig) {
+  return SigIsMember(set, sig);
+}
+
+__LIBC_HIDDEN__ sighandler_t _signal(int sig, sighandler_t handler, int flags) {
   struct sigaction sa;
   sigemptyset(&sa.sa_mask);
   sa.sa_handler = handler;
   sa.sa_flags = flags;
 
-  if (sigaction(signum, &sa, &sa) == -1) {
+  if (sigaction(sig, &sa, &sa) == -1) {
     return SIG_ERR;
   }
 
   return sa.sa_handler;
 }
 
-sighandler_t signal(int signum, sighandler_t handler) {
-  return _signal(signum, handler, SA_RESTART);
+sighandler_t signal(int sig, sighandler_t handler) {
+  return _signal(sig, handler, SA_RESTART);
 }
 
 int sigpause(int sig) {
-  kernel_sigset_t set;
-  set.clear();
-  if (__rt_sigprocmask(SIG_SETMASK, nullptr, &set, sizeof(set)) == -1) return -1;
-  if (!set.clear(sig)) return -1;
-  return __rt_sigsuspend(&set, sizeof(set));
+  sigset64_t set = {};
+  if (sigprocmask64(SIG_SETMASK, nullptr, &set) == -1 || sigdelset64(&set, sig) == -1) return -1;
+  return sigsuspend64(&set);
 }
 
 int sigpending(sigset_t* bionic_set) {
-  kernel_sigset_t set;
-  int result = __rt_sigpending(&set, sizeof(set));
-  if (result != -1) {
-    *bionic_set = set.bionic;
-  }
-  return result;
+  SigSetConverter set = {};
+  set.sigset = *bionic_set;
+  if (__rt_sigpending(&set.sigset64, sizeof(set.sigset64)) == -1) return -1;
+  *bionic_set = set.sigset;
+  return 0;
+}
+
+int sigpending64(sigset64_t* set) {
+  return __rt_sigpending(set, sizeof(*set));
 }
 
 int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) {
-  kernel_sigset_t new_set;
-  kernel_sigset_t* new_set_ptr = NULL;
-  if (bionic_new_set != NULL) {
-    new_set.set(bionic_new_set);
-    new_set_ptr = &new_set;
+  SigSetConverter new_set;
+  sigset64_t* new_set_ptr = nullptr;
+  if (bionic_new_set != nullptr) {
+    sigemptyset64(&new_set.sigset64);
+    new_set.sigset = *bionic_new_set;
+    new_set_ptr = &new_set.sigset64;
   }
 
-  kernel_sigset_t old_set;
-  if (__rt_sigprocmask(how, new_set_ptr, &old_set, sizeof(old_set)) == -1) {
+  SigSetConverter old_set;
+  if (sigprocmask64(how, new_set_ptr, &old_set.sigset64) == -1) {
     return -1;
   }
 
-  if (bionic_old_set != NULL) {
-    *bionic_old_set = old_set.bionic;
+  if (bionic_old_set != nullptr) {
+    *bionic_old_set = old_set.sigset;
   }
 
   return 0;
 }
 
-int sigqueue(pid_t pid, int signo, const sigval value) {
+int sigprocmask64(int how, const sigset64_t* new_set, sigset64_t* old_set) {
+  return __rt_sigprocmask(how, new_set, old_set, sizeof(*new_set));
+}
+
+int sigqueue(pid_t pid, int sig, const sigval value) {
   siginfo_t info;
   memset(&info, 0, sizeof(siginfo_t));
-  info.si_signo = signo;
+  info.si_signo = sig;
   info.si_code = SI_QUEUE;
   info.si_pid = getpid();
   info.si_uid = getuid();
   info.si_value = value;
-
-  return ___rt_sigqueueinfo(pid, signo, &info);
+  return ___rt_sigqueueinfo(pid, sig, &info);
 }
 
 int sigrelse(int sig) {
-  kernel_sigset_t set;
-  set.clear();
-  if (!set.set(sig)) return -1;
-  return __rt_sigprocmask(SIG_UNBLOCK, &set, nullptr, sizeof(set));
+  sigset64_t set = {};
+  if (sigaddset64(&set, sig) == -1) return -1;
+  return sigprocmask64(SIG_UNBLOCK, &set, nullptr);
 }
 
 sighandler_t sigset(int sig, sighandler_t disp) {
@@ -215,57 +274,68 @@
     return SIG_ERR;
   }
 
-  kernel_sigset_t new_mask{sig};
-  kernel_sigset_t old_mask;
-  if (__rt_sigprocmask(disp == SIG_HOLD ? SIG_BLOCK : SIG_UNBLOCK, &new_mask, &old_mask,
-                       sizeof(new_mask)) == -1) {
+  sigset64_t new_mask = {};
+  sigaddset64(&new_mask, sig);
+  sigset64_t old_mask;
+  if (sigprocmask64(disp == SIG_HOLD ? SIG_BLOCK : SIG_UNBLOCK, &new_mask, &old_mask) == -1) {
     return SIG_ERR;
   }
 
-  return old_mask.is_set(sig) ? SIG_HOLD : old_sa.sa_handler;
+  return sigismember64(&old_mask, sig) ? SIG_HOLD : old_sa.sa_handler;
 }
 
 // This isn't in our header files, but is exposed on all architectures.
 extern "C" int sigsetmask(int mask) {
-  union {
-    int mask;
-    sigset_t set;
-  } in, out;
-
-  sigemptyset(&in.set);
-  in.mask = mask;
-
-  if (sigprocmask(SIG_SETMASK, &in.set, &out.set) == -1) return -1;
-  return out.mask;
+  SigSetConverter in, out;
+  sigemptyset(&in.sigset);
+  in.bsd = mask;
+  if (sigprocmask(SIG_SETMASK, &in.sigset, &out.sigset) == -1) return -1;
+  return out.bsd;
 }
 
 int sigsuspend(const sigset_t* bionic_set) {
-  kernel_sigset_t set(bionic_set);
-  return __rt_sigsuspend(&set, sizeof(set));
+  SigSetConverter set = {};
+  set.sigset = *bionic_set;
+  return __rt_sigsuspend(&set.sigset64, sizeof(set.sigset64));
 }
 
-int sigtimedwait(const sigset_t* set, siginfo_t* info, const timespec* timeout) {
-  kernel_sigset_t sigset(set);
-  return __rt_sigtimedwait(sigset.get(), info, timeout, sizeof(sigset));
+int sigsuspend64(const sigset64_t* set) {
+  return __rt_sigsuspend(set, sizeof(*set));
 }
 
-int sigwait(const sigset_t* set, int* sig) {
-  kernel_sigset_t sigset(set);
+int sigtimedwait(const sigset_t* bionic_set, siginfo_t* info, const timespec* timeout) {
+  SigSetConverter set = {};
+  set.sigset = *bionic_set;
+  return __rt_sigtimedwait(&set.sigset64, info, timeout, sizeof(set.sigset64));
+}
+
+int sigtimedwait64(const sigset64_t* set, siginfo_t* info, const timespec* timeout) {
+  return __rt_sigtimedwait(set, info, timeout, sizeof(*set));
+}
+
+int sigwait(const sigset_t* bionic_set, int* sig) {
+  SigSetConverter set = {};
+  set.sigset = *bionic_set;
+  return sigwait64(&set.sigset64, sig);
+}
+
+int sigwait64(const sigset64_t* set, int* sig) {
   while (true) {
     // __rt_sigtimedwait can return EAGAIN or EINTR, we need to loop
     // around them since sigwait is only allowed to return EINVAL.
-    int result = __rt_sigtimedwait(sigset.get(), NULL, NULL, sizeof(sigset));
+    int result = sigtimedwait64(set, nullptr, nullptr);
     if (result >= 0) {
       *sig = result;
       return 0;
     }
-
-    if (errno != EAGAIN && errno != EINTR) {
-      return errno;
-    }
+    if (errno != EAGAIN && errno != EINTR) return errno;
   }
 }
 
 int sigwaitinfo(const sigset_t* set, siginfo_t* info) {
-  return sigtimedwait(set, info, NULL);
+  return sigtimedwait(set, info, nullptr);
+}
+
+int sigwaitinfo64(const sigset64_t* set, siginfo_t* info) {
+  return sigtimedwait64(set, info, nullptr);
 }
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index e5075f5..7422a0b 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -36,6 +36,7 @@
 #include <unistd.h>
 
 #include "private/ScopedSignalBlocker.h"
+#include "private/SigSetConverter.h"
 
 enum Action {
   kOpen,
@@ -87,8 +88,8 @@
   pid_t pgroup;
   sched_param schedparam;
   int schedpolicy;
-  sigset_t sigmask;
-  sigset_t sigdefault;
+  SigSetConverter sigmask;
+  SigSetConverter sigdefault;
 };
 
 static void ApplyAttrs(short flags, const posix_spawnattr_t* attr) {
@@ -100,7 +101,7 @@
   const struct sigaction default_sa = { .sa_handler = SIG_DFL };
   for (int s = 1; s < _NSIG; ++s) {
     bool reset = false;
-    if (use_sigdefault && sigismember(&(*attr)->sigdefault, s)) {
+    if (use_sigdefault && sigismember64(&(*attr)->sigdefault.sigset64, s)) {
       reset = true;
     } else {
       struct sigaction current;
@@ -126,7 +127,7 @@
   }
 
   if ((flags & POSIX_SPAWN_SETSIGMASK) != 0) {
-    if (sigprocmask(SIG_SETMASK, &(*attr)->sigmask, nullptr)) _exit(127);
+    if (sigprocmask64(SIG_SETMASK, &(*attr)->sigmask.sigset64, nullptr)) _exit(127);
   }
 }
 
@@ -209,22 +210,42 @@
 }
 
 int posix_spawnattr_setsigmask(posix_spawnattr_t* attr, const sigset_t* mask) {
-  (*attr)->sigmask = *mask;
+  (*attr)->sigmask.sigset = *mask;
+  return 0;
+}
+
+int posix_spawnattr_setsigmask64(posix_spawnattr_t* attr, const sigset64_t* mask) {
+  (*attr)->sigmask.sigset64 = *mask;
   return 0;
 }
 
 int posix_spawnattr_getsigmask(const posix_spawnattr_t* attr, sigset_t* mask) {
-  *mask = (*attr)->sigmask;
+  *mask = (*attr)->sigmask.sigset;
+  return 0;
+}
+
+int posix_spawnattr_getsigmask64(const posix_spawnattr_t* attr, sigset64_t* mask) {
+  *mask = (*attr)->sigmask.sigset64;
   return 0;
 }
 
 int posix_spawnattr_setsigdefault(posix_spawnattr_t* attr, const sigset_t* mask) {
-  (*attr)->sigdefault = *mask;
+  (*attr)->sigdefault.sigset = *mask;
+  return 0;
+}
+
+int posix_spawnattr_setsigdefault64(posix_spawnattr_t* attr, const sigset64_t* mask) {
+  (*attr)->sigdefault.sigset64 = *mask;
   return 0;
 }
 
 int posix_spawnattr_getsigdefault(const posix_spawnattr_t* attr, sigset_t* mask) {
-  *mask = (*attr)->sigdefault;
+  *mask = (*attr)->sigdefault.sigset;
+  return 0;
+}
+
+int posix_spawnattr_getsigdefault64(const posix_spawnattr_t* attr, sigset64_t* mask) {
+  *mask = (*attr)->sigdefault.sigset64;
   return 0;
 }
 
diff --git a/libc/bionic/epoll_pwait.cpp b/libc/bionic/sys_epoll.cpp
similarity index 68%
rename from libc/bionic/epoll_pwait.cpp
rename to libc/bionic/sys_epoll.cpp
index f3af93e..9f82912 100644
--- a/libc/bionic/epoll_pwait.cpp
+++ b/libc/bionic/sys_epoll.cpp
@@ -26,18 +26,36 @@
  * SUCH DAMAGE.
  */
 
+#include <errno.h>
 #include <sys/epoll.h>
 
-#include "private/kernel_sigset_t.h"
+#include "private/SigSetConverter.h"
 
-extern "C" int __epoll_pwait(int, epoll_event*, int, int, const kernel_sigset_t*, size_t);
+extern "C" int __epoll_pwait(int, epoll_event*, int, int, const sigset64_t*, size_t);
+
+int epoll_create(int size) {
+  if (size <= 0) {
+    errno = EINVAL;
+    return -1;
+  }
+  return epoll_create1(0);
+}
 
 int epoll_pwait(int fd, epoll_event* events, int max_events, int timeout, const sigset_t* ss) {
-  kernel_sigset_t kernel_ss;
-  kernel_sigset_t* kernel_ss_ptr = NULL;
-  if (ss != NULL) {
-    kernel_ss.set(ss);
-    kernel_ss_ptr = &kernel_ss;
+  SigSetConverter set;
+  sigset64_t* ss_ptr = nullptr;
+  if (ss != nullptr) {
+    set = {};
+    set.sigset = *ss;
+    ss_ptr = &set.sigset64;
   }
-  return __epoll_pwait(fd, events, max_events, timeout, kernel_ss_ptr, sizeof(kernel_ss));
+  return epoll_pwait64(fd, events, max_events, timeout, ss_ptr);
+}
+
+int epoll_pwait64(int fd, epoll_event* events, int max_events, int timeout, const sigset64_t* ss) {
+  return __epoll_pwait(fd, events, max_events, timeout, ss, sizeof(*ss));
+}
+
+int epoll_wait(int fd, struct epoll_event* events, int max_events, int timeout) {
+  return epoll_pwait64(fd, events, max_events, timeout, nullptr);
 }
diff --git a/libc/bionic/sys_signalfd.cpp b/libc/bionic/sys_signalfd.cpp
index 63e1db4..53d1f25 100644
--- a/libc/bionic/sys_signalfd.cpp
+++ b/libc/bionic/sys_signalfd.cpp
@@ -28,11 +28,16 @@
 
 #include <sys/signalfd.h>
 
-#include "private/kernel_sigset_t.h"
+#include "private/SigSetConverter.h"
 
-extern "C" int __signalfd4(int fd, kernel_sigset_t* mask, size_t sizemask, int flags);
+extern "C" int __signalfd4(int, const sigset64_t*, size_t, int);
 
 int signalfd(int fd, const sigset_t* mask, int flags) {
-  kernel_sigset_t in_set(mask);
-  return __signalfd4(fd, &in_set, sizeof(in_set), flags);
+  SigSetConverter set = {};
+  set.sigset = *mask;
+  return signalfd64(fd, &set.sigset64, flags);
+}
+
+int signalfd64(int fd, const sigset64_t* mask, int flags) {
+  return __signalfd4(fd, mask, sizeof(*mask), flags);
 }