facebookarchive / fb-adb

A better shell for Android devices
Other
1.14k stars 128 forks source link

Use ppoll(2) on FreeBSD 10.2 but not GNU/kFreeBSD #39

Closed jbeich closed 8 years ago

jbeich commented 8 years ago

From #38 by @dcolascione:

I'd also love to see properly-supported ppoll and pselect implementations. It's much less awkward to implement those in the kernel than to emulate them using kqueue.

I guess, you're referring to XPPOLL_BROKEN comment. GNU/Linux and GNU/kFreeBSD use glibc thus ppoll(3) maybe a wrapper around poll(2) if ppoll(2) isn't available. With ppoll(2) available it doesn't seem to do anything fancy that'd make it non-atomic.

http://code.metager.de/source/xref/gnu/glibc/sysdeps/unix/sysv/linux/ppoll.c#35

How to detect which ppoll() glibc uses or what to do with non-glibc Linux is left for another time. Otherwise, Linux, glibc or OS X bugs don't apply to BSDs or Solaris which use different kernel, libc, libpthread implementations.

jbeich commented 8 years ago

Note, switching GNU/kFreeBSD from kqueue(2) to ppoll(2) would probably be as gross as on GNU/Linux:

diff --git a/fs.c b/fs.c
index 913783d..d49ddca 100644
--- a/fs.c
+++ b/fs.c
@@ -469,6 +469,13 @@ xppoll(struct pollfd *fds, nfds_t nfds,

     return syscall(__NR_ppoll, fds, nfds, timeout_ts, sigmask, _NSIG/8);
 }
+#elif XPPOLL == XPPOLL_BSD_SYSCALL
+int
+xppoll(struct pollfd *fds, nfds_t nfds,
+       const struct timespec *timeout_ts, const sigset_t *sigmask)
+{
+    return syscall(SYS_ppoll, fds, nfds, timeout_ts, sigmask);
+}
 #elif XPPOLL == XPPOLL_KQUEUE
 int
 xppoll(struct pollfd *fds, nfds_t nfds,
diff --git a/fs.h b/fs.h
index 0fed2cb..c3401da 100644
--- a/fs.h
+++ b/fs.h
@@ -19,6 +19,7 @@
 #include <dirent.h>
 #include <sys/file.h>
 #include <sys/types.h>
+#include <sys/syscall.h>
 #include <unistd.h>
 #include <stdbool.h>
 #include <time.h>
@@ -97,11 +98,14 @@ int dup3(int oldfd, int newfd, int flags);
 #define XPPOLL_KQUEUE 2
 #define XPPOLL_SYSTEM 3
 #define XPPOLL_STUPID_WRAPPER 4
+#define XPPOLL_BSD_SYSCALL 5

 #if defined(__linux__)
 # define XPPOLL XPPOLL_LINUX_SYSCALL
 #elif defined(HAVE_PPOLL) && !defined(__GLIBC__)
 # define XPPOLL XPPOLL_SYSTEM
+#elif defined(SYS_ppoll)
+# define XPPOLL XPPOLL_BSD_SYSCALL
 #elif defined(HAVE_KQUEUE)
 # define XPPOLL XPPOLL_KQUEUE
 #elif defined(HAVE_PPOLL) && defined(__GLIBC__)