Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport Android API 19 support #291

Open
wants to merge 5 commits into
base: mobile-master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions android-configure
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

# In order to cross-compile node for Android using NDK, run:
# source android-configure <path_to_ndk> [arch]
# source android-configure <path_to_ndk> [arch] [targetapi]
#
# By running android-configure with source, will allow environment variables to
# be persistent in current session. This is useful for installing native node
Expand All @@ -15,6 +15,12 @@ else
ARCH="$2"
fi

if [ -z "$3" ]; then
TARGET_API=21
else
TARGET_API="$3"
fi

CC_VER="4.9"
case $ARCH in
arm)
Expand Down Expand Up @@ -55,7 +61,7 @@ function make_toolchain {
--install-dir=$TOOLCHAIN \
--stl=libc++ \
--force \
--platform=android-21
--platform=android-$TARGET_API
}

export TOOLCHAIN=$PWD/android-toolchain
Expand Down
17 changes: 15 additions & 2 deletions deps/uv/src/unix/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,19 @@ extern char** environ;
# endif
#endif

#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
# include <dlfcn.h> /* for dlsym */
#endif

#if defined(__MVS__)
#include <sys/ioctl.h>
#endif

#if defined(__linux__)
# include <sys/syscall.h>
# define uv__accept4 accept4
# if !(defined(__ANDROID_API__) && __ANDROID_API__ < 21)
# define uv__accept4 accept4
# endif
#endif

static int uv__run_pending(uv_loop_t* loop);
Expand Down Expand Up @@ -1029,7 +1035,7 @@ int uv__open_cloexec(const char* path, int flags) {


int uv__dup2_cloexec(int oldfd, int newfd) {
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__linux__)
#if defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__linux__) && !(defined(__ANDROID_API__) && __ANDROID_API__ < 21))
int r;

r = dup3(oldfd, newfd, O_CLOEXEC);
Expand Down Expand Up @@ -1154,6 +1160,13 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
size_t shell_size;
long initsize;
int r;
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
int (*getpwuid_r)(uid_t, struct passwd*, char*, size_t, struct passwd**);

getpwuid_r = dlsym(RTLD_DEFAULT, "getpwuid_r");
if (getpwuid_r == NULL)
return UV_ENOSYS;
#endif

if (pwd == NULL)
return UV_EINVAL;
Expand Down
4 changes: 4 additions & 0 deletions deps/uv/src/unix/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,11 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
return utimensat(req->file, NULL, ts, 0);
#else
return futimens(req->file, ts);
#endif
#elif defined(__APPLE__) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
Expand Down
15 changes: 15 additions & 0 deletions deps/uv/src/unix/linux-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,17 @@ static uint64_t read_cpufreq(unsigned int cpunum);

int uv__platform_loop_init(uv_loop_t* loop) {
int fd;

/* It was reported that EPOLL_CLOEXEC is not defined on Android API < 21,
* a.k.a. Lollipop. Since EPOLL_CLOEXEC is an alias for O_CLOEXEC on all
* architectures, we just use that instead.
*/
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
fd = -1;
errno = ENOSYS;
#else
fd = epoll_create1(O_CLOEXEC);
#endif

/* epoll_create1() can fail either because it's not implemented (old kernel)
* or because it doesn't understand the O_CLOEXEC flag.
Expand Down Expand Up @@ -310,11 +320,16 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
abort();

if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
nfds = -1;
errno = ENOSYS;
#else
nfds = epoll_pwait(loop->backend_fd,
events,
ARRAY_SIZE(events),
timeout,
&sigset);
#endif
if (nfds == -1 && errno == ENOSYS) {
uv__store_relaxed(&no_epoll_pwait_cached, 1);
no_epoll_pwait = 1;
Expand Down
67 changes: 47 additions & 20 deletions deps/uv/src/unix/linux-inotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include <assert.h>
#include <errno.h>

#include <sys/inotify.h>
#include <sys/types.h>
#include <unistd.h>

Expand Down Expand Up @@ -65,17 +64,45 @@ static void uv__inotify_read(uv_loop_t* loop,
static void maybe_free_watcher_list(struct watcher_list* w,
uv_loop_t* loop);

static int init_inotify(uv_loop_t* loop) {
static int new_inotify_fd(void) {
int err;
int fd;

fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC);
if (fd != -1)
return fd;

if (errno != ENOSYS)
return UV__ERR(errno);

fd = uv__inotify_init();
if (fd == -1)
return UV__ERR(errno);

err = uv__cloexec(fd, 1);
if (err == 0)
err = uv__nonblock(fd, 1);

if (err) {
uv__close(fd);
return err;
}

return fd;
}


static int init_inotify(uv_loop_t* loop) {
int err;

if (loop->inotify_fd != -1)
return 0;

fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (fd < 0)
return UV__ERR(errno);
err = new_inotify_fd();
if (err < 0)
return err;

loop->inotify_fd = fd;
loop->inotify_fd = err;
uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd);
uv__io_start(loop, &loop->inotify_read_watcher, POLLIN);

Expand Down Expand Up @@ -159,15 +186,15 @@ static void maybe_free_watcher_list(struct watcher_list* w, uv_loop_t* loop) {
if ((!w->iterating) && QUEUE_EMPTY(&w->watchers)) {
/* No watchers left for this path. Clean up. */
RB_REMOVE(watcher_root, CAST(&loop->inotify_watchers), w);
inotify_rm_watch(loop->inotify_fd, w->wd);
uv__inotify_rm_watch(loop->inotify_fd, w->wd);
uv__free(w);
}
}

static void uv__inotify_read(uv_loop_t* loop,
uv__io_t* dummy,
unsigned int events) {
const struct inotify_event* e;
const struct uv__inotify_event* e;
struct watcher_list* w;
uv_fs_event_t* h;
QUEUE queue;
Expand All @@ -192,12 +219,12 @@ static void uv__inotify_read(uv_loop_t* loop,

/* Now we have one or more inotify_event structs. */
for (p = buf; p < buf + size; p += sizeof(*e) + e->len) {
e = (const struct inotify_event*) p;
e = (const struct uv__inotify_event*)p;

events = 0;
if (e->mask & (IN_ATTRIB|IN_MODIFY))
if (e->mask & (UV__IN_ATTRIB|UV__IN_MODIFY))
events |= UV_CHANGE;
if (e->mask & ~(IN_ATTRIB|IN_MODIFY))
if (e->mask & ~(UV__IN_ATTRIB|UV__IN_MODIFY))
events |= UV_RENAME;

w = find_watcher(loop, e->wd);
Expand Down Expand Up @@ -263,16 +290,16 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (err)
return err;

events = IN_ATTRIB
| IN_CREATE
| IN_MODIFY
| IN_DELETE
| IN_DELETE_SELF
| IN_MOVE_SELF
| IN_MOVED_FROM
| IN_MOVED_TO;
events = UV__IN_ATTRIB
| UV__IN_CREATE
| UV__IN_MODIFY
| UV__IN_DELETE
| UV__IN_DELETE_SELF
| UV__IN_MOVE_SELF
| UV__IN_MOVED_FROM
| UV__IN_MOVED_TO;

wd = inotify_add_watch(handle->loop->inotify_fd, path, events);
wd = uv__inotify_add_watch(handle->loop->inotify_fd, path, events);
if (wd == -1)
return UV__ERR(errno);

Expand Down
109 changes: 91 additions & 18 deletions deps/uv/src/unix/linux-syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,46 @@
# endif
#endif /* __arm__ */

#ifndef __NR_inotify_init
# if defined(__x86_64__)
# define __NR_inotify_init 253
# elif defined(__i386__)
# define __NR_inotify_init 291
# elif defined(__arm__)
# define __NR_inotify_init (UV_SYSCALL_BASE + 316)
# endif
#endif /* __NR_inotify_init */

#ifndef __NR_inotify_init1
# if defined(__x86_64__)
# define __NR_inotify_init1 294
# elif defined(__i386__)
# define __NR_inotify_init1 332
# elif defined(__arm__)
# define __NR_inotify_init1 (UV_SYSCALL_BASE + 360)
# endif
#endif /* __NR_inotify_init1 */

#ifndef __NR_inotify_add_watch
# if defined(__x86_64__)
# define __NR_inotify_add_watch 254
# elif defined(__i386__)
# define __NR_inotify_add_watch 292
# elif defined(__arm__)
# define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317)
# endif
#endif /* __NR_inotify_add_watch */

#ifndef __NR_inotify_rm_watch
# if defined(__x86_64__)
# define __NR_inotify_rm_watch 255
# elif defined(__i386__)
# define __NR_inotify_rm_watch 293
# elif defined(__arm__)
# define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318)
# endif
#endif /* __NR_inotify_rm_watch */

#ifndef __NR_recvmmsg
# if defined(__x86_64__)
# define __NR_recvmmsg 299
Expand Down Expand Up @@ -146,6 +186,42 @@

struct uv__mmsghdr;

int uv__inotify_init(void) {
#if defined(__NR_inotify_init)
return syscall(__NR_inotify_init);
#else
return errno = ENOSYS, -1;
#endif
}


int uv__inotify_init1(int flags) {
#if defined(__NR_inotify_init1)
return syscall(__NR_inotify_init1, flags);
#else
return errno = ENOSYS, -1;
#endif
}


int uv__inotify_add_watch(int fd, const char* path, uint32_t mask) {
#if defined(__NR_inotify_add_watch)
return syscall(__NR_inotify_add_watch, fd, path, mask);
#else
return errno = ENOSYS, -1;
#endif
}


int uv__inotify_rm_watch(int fd, int32_t wd) {
#if defined(__NR_inotify_rm_watch)
return syscall(__NR_inotify_rm_watch, fd, wd);
#else
return errno = ENOSYS, -1;
#endif
}


int uv__sendmmsg(int fd,
struct uv__mmsghdr* mmsg,
unsigned int vlen,
Expand All @@ -172,28 +248,28 @@ int uv__recvmmsg(int fd,


ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
#if defined(__NR_preadv)
return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
#else
#if !defined(__NR_preadv) || defined(__ANDROID_API__) && __ANDROID_API__ < 24
return errno = ENOSYS, -1;
#else
return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
#endif
}


ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
#if defined(__NR_pwritev)
return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
#else
#if !defined(__NR_pwritev) || defined(__ANDROID_API__) && __ANDROID_API__ < 24
return errno = ENOSYS, -1;
#else
return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
#endif
}


int uv__dup3(int oldfd, int newfd, int flags) {
#if defined(__NR_dup3)
return syscall(__NR_dup3, oldfd, newfd, flags);
#else
#if !defined(__NR_dup3) || defined(__ANDROID_API__) && __ANDROID_API__ < 21
return errno = ENOSYS, -1;
#else
return syscall(__NR_dup3, oldfd, newfd, flags);
#endif
}

Expand Down Expand Up @@ -225,21 +301,18 @@ int uv__statx(int dirfd,
int flags,
unsigned int mask,
struct uv__statx* statxbuf) {
/* __NR_statx make Android box killed by SIGSYS.
* That looks like a seccomp2 sandbox filter rejecting the system call.
*/
#if defined(__NR_statx) && !defined(__ANDROID__)
return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
#else
#if !defined(__NR_statx) || defined(__ANDROID_API__) && __ANDROID_API__ < 30
return errno = ENOSYS, -1;
#else
return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
#endif
}


ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) {
#if defined(__NR_getrandom)
return syscall(__NR_getrandom, buf, buflen, flags);
#else
#if !defined(__NR_getrandom) || defined(__ANDROID_API__) && __ANDROID_API__ < 28
return errno = ENOSYS, -1;
#else
return syscall(__NR_getrandom, buf, buflen, flags);
#endif
}
Loading