移植 HevLib 到 Android 系统

打算将 HevSocks5Client 移植到 Android 系统,替换原来的 HevTLSTunnel 实现。先要移植 HevLib,原以为只要增加两个文件 Application.mk 和 Android.mk 就可以了。但编译到 hev-event-source-signal.c 的时候就出错了,报 sys/signalfd.h 文件找不到。于是 android-ndk 目录里搜索了一下,还真没有这个文件的。这才意识到有可能 Android 的用户态目前还没开放这些 API。

如果仅仅是用户态没有导出问题应该不太,关键内核要实现了这些功能。还好我的系统中存在 /proc/config.gz 文件,解压查询确认 SIGNALFD、TIMERFD 及 EVENTFD 都是支持。下面的事情就好办了,就是增加几个系统调用的实现问题了。进一步确认了间接系统调用 syscall 函数是实现了的,连汇编都不用写了。

diff --git a/src/hev-event-source-signal.c b/src/hev-event-source-signal.c
index daf3e96..01f0088 100644
--- a/src/hev-event-source-signal.c
+++ b/src/hev-event-source-signal.c
@@ -11,7 +11,12 @@
 #include <unistd.h>
 #include <signal.h>
 #include <sys/epoll.h>
+#if defined(ANDROID)
+#include <fcntl.h>
+#include <asm/unistd.h>
+#else /* GENERIC */
 #include <sys/signalfd.h>
+#endif
 
 #include "hev-event-source-signal.h"
 
@@ -25,6 +30,31 @@ struct _HevEventSourceSignal
 	int signal_fd;
 };
 
+#if defined(ANDROID)
+#define SFD_NONBLOCK	O_NONBLOCK
+
+struct signalfd_siginfo
+{
+  uint32_t ssi_signo;
+  int32_t ssi_errno;
+  int32_t ssi_code;
+  uint32_t ssi_pid;
+  uint32_t ssi_uid;
+  int32_t ssi_fd;
+  uint32_t ssi_tid;
+  uint32_t ssi_band;
+  uint32_t ssi_overrun;
+  uint32_t ssi_trapno;
+  int32_t ssi_status;
+  int32_t ssi_int;
+  uint64_t ssi_ptr;
+  uint64_t ssi_utime;
+  uint64_t ssi_stime;
+  uint64_t ssi_addr;
+  uint8_t __pad[48];
+};
+#endif
+
 static HevEventSourceFuncs hev_event_source_signal_funcs =
 {
 	.prepare = NULL,
@@ -33,6 +63,14 @@ static HevEventSourceFuncs hev_event_source_signal_funcs =
 	.finalize = hev_event_source_signal_finalize,
 };
 
+#if defined(ANDROID)
+static int
+signalfd (int fd, const sigset_t *mask, int flags)
+{
+	return syscall (__NR_signalfd4, fd, mask, _NSIG / 8, flags);
+}
+#endif
+
 HevEventSource *
 hev_event_source_signal_new (int signal)
 {
diff --git a/src/hev-event-source-timeout.c b/src/hev-event-source-timeout.c
index 57a9b00..cacd196 100644
--- a/src/hev-event-source-timeout.c
+++ b/src/hev-event-source-timeout.c
@@ -11,10 +11,20 @@
 #include <errno.h>
 #include <unistd.h>
 #include <sys/epoll.h>
+#if defined(ANDROID)
+#include <fcntl.h>
+#include <asm/unistd.h>
+#else /* GENERIC */
 #include <sys/timerfd.h>
+#endif
 
 #include "hev-event-source-timeout.h"
 
+#if defined(ANDROID)
+#define TFD_NONBLOCK	O_NONBLOCK
+#define TFD_TIMER_ABSTIME 1
+#endif
+
 static bool hev_event_source_timeout_prepare (HevEventSource *source);
 static bool hev_event_source_timeout_check (HevEventSource *source, HevEventSourceFD *fd);
 static void hev_event_source_timeout_finalize (HevEventSource *source);
@@ -35,6 +45,22 @@ static HevEventSourceFuncs hev_event_source_timeout_funcs =
 	.finalize = hev_event_source_timeout_finalize,
 };
 
+#if defined(ANDROID)
+static int
+timerfd_create (int clockid, int flags)
+{
+	return syscall (__NR_timerfd_create, clockid, flags);
+}
+
+static int
+timerfd_settime (int fd, int flags,
+			const struct itimerspec *new_value,
+			struct itimerspec *old_value)
+{
+	return syscall (__NR_timerfd_settime, fd, flags, new_value, old_value);
+}
+#endif
+
 HevEventSource *
 hev_event_source_timeout_new (unsigned int interval)
 {

Over!

Leave a Reply

Your email address will not be published. Required fields are marked *