diff --git a/ndk/sources/android/libportable/Android.mk b/ndk/sources/android/libportable/Android.mk index a32886a15..135001273 100644 --- a/ndk/sources/android/libportable/Android.mk +++ b/ndk/sources/android/libportable/Android.mk @@ -28,6 +28,9 @@ LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_CFLAGS := -I $(LOCAL_PATH)/common/include +# Uncomment the next line to easily enable Lib-Portable logging during development. +# LOCAL_CFLAGS += -DLOG_NDEBUG=0 + ifeq ($(TARGET_ARCH),mips) libportable_arch_src_files += \ arch-mips/clone.c \ diff --git a/ndk/sources/android/libportable/arch-mips/errno.c b/ndk/sources/android/libportable/arch-mips/errno.c index b86290221..8adf248b9 100644 --- a/ndk/sources/android/libportable/arch-mips/errno.c +++ b/ndk/sources/android/libportable/arch-mips/errno.c @@ -15,6 +15,7 @@ */ #include +#include #include #include @@ -25,7 +26,7 @@ #error Bad build environment #endif -__hidden int ntop_errno(int native_errno) +__hidden int errno_ntop(int native_errno) { switch (native_errno) { case ENAMETOOLONG: return ENAMETOOLONG_PORTABLE; @@ -128,7 +129,7 @@ __hidden int ntop_errno(int native_errno) return native_errno; } -static inline int pton_errno(int portable_errno) +__hidden int errno_pton(int portable_errno) { switch (portable_errno) { case ENAMETOOLONG_PORTABLE: return ENAMETOOLONG; @@ -287,8 +288,9 @@ volatile int* __errno_portable() p = errno_key_data(); - ALOGV("%s(): { save_errno:%d p=%p->{pshadow:%d perrno:%d}", __func__, - save_errno, p, p->pshadow,p->perrno); + ALOGV(" "); + ALOGV("%s(): { save_errno = errno:%d, (p:%p)->{pshadow:%d, perrno:%d}", __func__, + save_errno, p, p->pshadow, p->perrno); if (save_errno == 0 && p->pshadow != p->perrno) { /* @@ -296,32 +298,32 @@ volatile int* __errno_portable() * - copy portable error back to native */ p->pshadow = p->perrno; - save_errno = pton_errno(p->perrno); + save_errno = errno_pton(p->perrno); } else if (save_errno != 0 && p->pshadow == p->perrno) { /* - * native errno has changed but portable hasn't - * - copy native error to portable + * Native errno has changed but portable hasn't + * - copy native error to portable. */ - p->pshadow = p->perrno = ntop_errno(save_errno); + p->pshadow = p->perrno = errno_ntop(save_errno); save_errno = 0; } else if (save_errno != 0 && p->pshadow != p->perrno) { /* - * both native and portable errno values have changed + * Both native and portable errno values have changed * so give priority to native errno * - copy native error to portable */ - p->pshadow = p->perrno = ntop_errno(save_errno); + p->pshadow = p->perrno = errno_ntop(save_errno); save_errno = 0; } - ALOGV("%s: new save_errno=%d p=%p->{pshadow=%d perrno=%d}", __func__, - save_errno, p, p->pshadow,p->perrno); + ALOGV("%s: new save_errno:%d p:%p->{pshadow:%d, perrno:%d}", __func__, + save_errno, p, p->pshadow, p->perrno); errno = save_errno; - ALOGV("%s: return &p->perrno:%p; }", __func__, &p->perrno); + ALOGV("%s: return (&p->perrno):%p; }", __func__, &p->perrno); /* return pointer to the modifiable portable errno value */ return &p->perrno; @@ -339,17 +341,28 @@ void __set_errno_portable(int portable_errno) p = errno_key_data(); - ALOGV("%s(): { save_errno:%d p=%p->{pshadow:%d perrno:%d}", __func__, - save_errno, p, p->pshadow,p->perrno); + ALOGV("%s(): { save_errno = errno:%d, p:%p->{pshadow:%d, perrno:%d}", __func__, + save_errno, p, p->pshadow, p->perrno); p->pshadow = p->perrno = portable_errno; - save_errno = pton_errno(portable_errno); + save_errno = errno_pton(portable_errno); - ALOGV("%s: new save_errno=%d p=%p->{pshadow=%d perrno=%d}", __func__, - save_errno, p, p->pshadow,p->perrno); + ALOGV("%s: new save_errno:%d, p:%p->{pshadow:%d, perrno:%d}", __func__, + save_errno, p, p->pshadow, p->perrno); errno = save_errno; ALOGV("%s: return; }", __func__); } + +char *strerror_portable(int errnum) +{ + return strerror(errno_pton(errnum)); +} + +/* BSD style strerror_r */ +int strerror_r_portable(int errnum, char *buf, size_t buflen) +{ + return strerror_r(errno_pton(errnum), buf, buflen); +} diff --git a/ndk/sources/android/libportable/arch-mips/fcntl.c b/ndk/sources/android/libportable/arch-mips/fcntl.c index 8a2343203..07ba5757b 100644 --- a/ndk/sources/android/libportable/arch-mips/fcntl.c +++ b/ndk/sources/android/libportable/arch-mips/fcntl.c @@ -61,7 +61,11 @@ static char *map_portable_cmd_to_name(int cmd) return name; } -static int mips_change_cmd(int cmd) + +/* + * Maps a fcntl portable cmd to a native command. + */ +static int fcntl_cmd_pton(int cmd) { switch(cmd) { case F_DUPFD_PORTABLE: /* 0 --> 0 */ @@ -225,7 +229,7 @@ int fcntl_portable(int fd, int portable_cmd, ...) int result = 0; struct flock flock; /* Native MIPS structure */ struct flock64 flock64; /* Native MIPS structure */ - int mips_cmd = mips_change_cmd(portable_cmd); + int mips_cmd = fcntl_cmd_pton(portable_cmd); char *portable_cmd_name = map_portable_cmd_to_name(portable_cmd); struct flock_portable *flock_portable = NULL; struct flock64_portable *flock64_portable = NULL; @@ -307,11 +311,11 @@ int fcntl_portable(int fd, int portable_cmd, ...) case F_SETFL: flags = mips_change_flags((int)arg); - result = __fcntl64(fd, mips_change_cmd(mips_cmd), (void *)flags); + result = __fcntl64(fd, fcntl_cmd_pton(mips_cmd), (void *)flags); break; case F_GETFL: - result = __fcntl64(fd, mips_change_cmd(mips_cmd), arg); + result = __fcntl64(fd, fcntl_cmd_pton(mips_cmd), arg); if (result != -1) result = portable_change_flags(result); break; diff --git a/ndk/sources/android/libportable/arch-mips/open.c b/ndk/sources/android/libportable/arch-mips/open.c index 436797bab..4307e2cca 100644 --- a/ndk/sources/android/libportable/arch-mips/open.c +++ b/ndk/sources/android/libportable/arch-mips/open.c @@ -17,16 +17,23 @@ #include #include #include +#include #include +#define PORTABLE_TAG "open_portable" +#include + #if O_CREAT_PORTABLE==O_CREAT #error Bad build environment #endif -static inline int mips_change_flags(int flags) +static inline int open_flags_pton(int flags) { int mipsflags = flags & O_ACCMODE_PORTABLE; + + ALOGV("%s(flags:0x%x) {", __func__, flags); + if (flags & O_CREAT_PORTABLE) mipsflags |= O_CREAT; if (flags & O_EXCL_PORTABLE) @@ -56,6 +63,7 @@ static inline int mips_change_flags(int flags) if (flags & O_NDELAY_PORTABLE) mipsflags |= O_NDELAY; + ALOGV("%s: return(mipsflags:0x%x); }", __func__, mipsflags); return mipsflags; } @@ -63,10 +71,16 @@ extern int __open(const char*, int, int); int open_portable(const char *pathname, int flags, ...) { mode_t mode = 0; + int native_flags; + int fd; + + ALOGV(" "); + ALOGV("%s(pathname:%p, flags:0x%x, ...) {", __func__, + pathname, flags); + flags |= O_LARGEFILE_PORTABLE; - if (flags & O_CREAT_PORTABLE) - { + if (flags & O_CREAT_PORTABLE) { va_list args; va_start(args, flags); @@ -74,18 +88,32 @@ int open_portable(const char *pathname, int flags, ...) va_end(args); } - return __open(pathname, mips_change_flags(flags), mode); + native_flags = open_flags_pton(flags); + + fd = __open(pathname, native_flags, mode); + if (fd == -1) { + /* Can't print pathname as a string, might be bogus */ + ALOGV("%s: fd = %d = __open(pathname:%p, native_flags:0x%x, mode:0x%x);", __func__, + fd, pathname, native_flags, mode); + } + ALOGV("%s: return(fd:%d); }", __func__, fd); + return fd; } extern int __openat(int, const char*, int, int); -int openat_portable(int fd, const char *pathname, int flags, ...) +int openat_portable(int dirfd, const char *pathname, int flags, ...) { mode_t mode = 0; + int native_flags; + int fd; + + ALOGV(" "); + ALOGV("%s(dirfd:%d, pathname:0x%p, flags:0x%x, ...) {", __func__, + dirfd, pathname, flags); flags |= O_LARGEFILE_PORTABLE; - if (flags & O_CREAT_PORTABLE) - { + if (flags & O_CREAT_PORTABLE) { va_list args; va_start(args, flags); @@ -93,5 +121,14 @@ int openat_portable(int fd, const char *pathname, int flags, ...) va_end(args); } - return __openat(fd, pathname, mips_change_flags(flags), mode); + native_flags = open_flags_pton(flags); + + fd = __openat(dirfd, pathname, native_flags, mode); + + if (fd == -1) { + ALOGV("%s: fd = %d = __open(pathname:0x%p, native_flags:0x%x, mode:0x%d);", __func__, + fd, pathname, native_flags, mode); + } + ALOGV("%s: return(fd:%d); }", __func__, fd); + return fd; } diff --git a/ndk/sources/android/libportable/arch-mips/pthread.c b/ndk/sources/android/libportable/arch-mips/pthread.c index a00701f2c..39f4b8738 100644 --- a/ndk/sources/android/libportable/arch-mips/pthread.c +++ b/ndk/sources/android/libportable/arch-mips/pthread.c @@ -61,7 +61,7 @@ ALOGV(" "); \ ALOGV("%s" fmt, __func__, STRIP_PARENS(CALLARGS)); \ rv = fn CALLARGS; \ - portable_rv = ntop_errno(rv); \ + portable_rv = errno_ntop(rv); \ ALOGV("%s: return(portable_rv:%d); rv:%d;", __func__, \ portable_rv, rv); \ return portable_rv; \ @@ -276,9 +276,9 @@ int pthread_kill_portable(pthread_t thread, int portable_signum) thread, mips_signum); ret = pthread_kill(thread, mips_signum); } - portable_ret = ntop_errno(ret); + portable_ret = errno_ntop(ret); - ALOGV("%s: return portable_ret:%d; ret:%d;", __func__, \ + ALOGV("%s: return portable_ret:%d; ret:%d;", __func__, portable_ret, ret); return portable_ret; @@ -295,7 +295,7 @@ int pthread_sigmask_portable(int portable_how, const sigset_portable_t *portable ret = do_sigmask(portable_how, portable_sigset, portable_oldset, pthread_sigmask); - portable_ret = ntop_errno(ret); + portable_ret = errno_ntop(ret); ALOGV("%s: return portable_ret:%d; ret:%d;", __func__, portable_ret, ret); @@ -311,4 +311,3 @@ PTHREAD_WRAPPER(pthread_once, (pthread_once_t *once_control, void (*init_routine PTHREAD_WRAPPER(pthread_setname_np, (pthread_t thid, const char *thname), (thid, thname), "(thid:%lx, thname:\"%s\")"); - diff --git a/ndk/sources/android/libportable/arch-mips/signal.c b/ndk/sources/android/libportable/arch-mips/signal.c index 61849c954..a3cbf6811 100644 --- a/ndk/sources/android/libportable/arch-mips/signal.c +++ b/ndk/sources/android/libportable/arch-mips/signal.c @@ -31,6 +31,8 @@ #error Bad build environment #endif +typedef void (*sig3handler_t)(int, siginfo_t *, void *); + /* * The next five hidden functions are not exposed in the * libportable shared object. They are used here and other @@ -419,7 +421,7 @@ static void mips_sigaction_handler(int mips_signum, siginfo_t *sip, void *ucp) */ portable_si_signo = signum_ntop(sip->si_signo); portable_si_signame = map_portable_signum_to_name(portable_si_signo); - portable_si_errno = ntop_errno(sip->si_errno); + portable_si_errno = errno_ntop(sip->si_errno); mips_si_signame = map_mips_signum_to_name(sip->si_signo); diff --git a/ndk/sources/android/libportable/arch-mips/socket.c b/ndk/sources/android/libportable/arch-mips/socket.c index 8008fb9cf..8312d21f4 100644 --- a/ndk/sources/android/libportable/arch-mips/socket.c +++ b/ndk/sources/android/libportable/arch-mips/socket.c @@ -20,6 +20,10 @@ #include #include +#include + +#define PORTABLE_TAG "socket_portable" +#include #if SOCK_STREAM==SOCK_STREAM_PORTABLE @@ -42,40 +46,116 @@ # define SOCK_CLOEXEC O_CLOEXEC #endif -static inline int mips_change_type(int type) -{ - int mipstype = 0; - if (type & SOCK_NONBLOCK_PORTABLE) { - mipstype |= SOCK_NONBLOCK; - type &= ~SOCK_NONBLOCK_PORTABLE; +/* + * Portable to Native socktype mapper. + */ +static inline int socktype_pton(int portable_type) +{ + int native_type = 0; + + ALOGV("%s(portable_type:0x%x) {", __func__, portable_type); + + if (portable_type & SOCK_NONBLOCK_PORTABLE) { + native_type |= SOCK_NONBLOCK; + portable_type &= ~SOCK_NONBLOCK_PORTABLE; } #if defined(SOCK_CLOEXEC_PORTABLE) && defined(SOCK_CLOEXEC) - if (type & SOCK_CLOEXEC_PORTABLE) { - mipstype |= SOCK_CLOEXEC; - type &= ~SOCK_CLOEXEC_PORTABLE; + if (portable_type & SOCK_CLOEXEC_PORTABLE) { + native_type |= SOCK_CLOEXEC; + portable_type &= ~SOCK_CLOEXEC_PORTABLE; } #endif - switch (type) { - case SOCK_STREAM_PORTABLE: mipstype |= SOCK_STREAM; break; - case SOCK_DGRAM_PORTABLE: mipstype |= SOCK_DGRAM; break; - case SOCK_RAW_PORTABLE: mipstype |= SOCK_RAW; break; - case SOCK_RDM_PORTABLE: mipstype |= SOCK_RDM; break; - case SOCK_SEQPACKET_PORTABLE: mipstype |= SOCK_SEQPACKET; break; - case SOCK_PACKET_PORTABLE: mipstype |= SOCK_PACKET; break; - default: mipstype |= type; + switch (portable_type) { + case SOCK_STREAM_PORTABLE: native_type |= SOCK_STREAM; break; + case SOCK_DGRAM_PORTABLE: native_type |= SOCK_DGRAM; break; + case SOCK_RAW_PORTABLE: native_type |= SOCK_RAW; break; + case SOCK_RDM_PORTABLE: native_type |= SOCK_RDM; break; + case SOCK_SEQPACKET_PORTABLE: native_type |= SOCK_SEQPACKET; break; + case SOCK_PACKET_PORTABLE: native_type |= SOCK_PACKET; break; + default: + ALOGE("%s: case default: native_type:0x%x |= portable_type:0x%x:[UNKNOWN!];", __func__, + native_type, portable_type); + + native_type |= portable_type; + break; } - return mipstype; + ALOGV("%s: return(native_type:%d); }", __func__, native_type); + return native_type; } + +/* + * Native to Portable socktype mapper. + */ +static inline int socktype_ntop(int native_type) +{ + int portable_type = 0; + + ALOGV("%s(native_type:0x%x) {", __func__, native_type); + + if (native_type & SOCK_NONBLOCK) { + portable_type |= SOCK_NONBLOCK_PORTABLE; + native_type &= ~SOCK_NONBLOCK; + } + +#if defined(SOCK_CLOEXEC_PORTABLE) && defined(SOCK_CLOEXEC) + if (native_type & SOCK_CLOEXEC) { + portable_type |= SOCK_CLOEXEC_PORTABLE; + native_type &= ~SOCK_CLOEXEC; + } +#endif + + switch (native_type) { + case SOCK_STREAM: portable_type |= SOCK_STREAM_PORTABLE; break; + case SOCK_DGRAM: portable_type |= SOCK_DGRAM_PORTABLE; break; + case SOCK_RAW: portable_type |= SOCK_RAW_PORTABLE; break; + case SOCK_RDM: portable_type |= SOCK_RDM_PORTABLE; break; + case SOCK_SEQPACKET: portable_type |= SOCK_SEQPACKET_PORTABLE; break; + case SOCK_PACKET: portable_type |= SOCK_PACKET_PORTABLE; break; + default: + portable_type |= native_type; + ALOGE("%s: case default: portable_type:0x%x |= native_type:0x%x:[UNKNOWN!];", __func__, + portable_type, native_type); + } + ALOGV("%s: return(portable_type:%d); }", __func__, portable_type); + return portable_type; +} + + extern int socket(int, int, int); int socket_portable(int domain, int type, int protocol) { - return socket(domain, mips_change_type(type), protocol); + int rv; + + ALOGV(" "); + ALOGV("%s(domain:%d, type:%d, protocol:%d) {", __func__, + domain, type, protocol); + + rv = socket(domain, socktype_pton(type), protocol); + + ALOGV("%s: return(rv:%d); }", __func__, rv); + return rv; } + int socketpair_portable(int domain, int type, int protocol, int sv[2]) { - return socketpair(domain, mips_change_type(type), protocol, sv); + int rv; + + ALOGV(" "); + ALOGV("%s(domain:%d, type:%d, protocol:%d, sv[2]:%p) {", __func__, + domain, type, protocol, sv); + + rv = socketpair(domain, socktype_pton(type), protocol, sv); + + if ((rv != 0) || invalid_pointer(sv)) { + ALOGV("%s: return(rv:%d); }", __func__, + rv); + } else { + ALOGV("%s: return(rv:%d); sv[0]:%d; sv[1]:%d;}", __func__, + rv, sv[0], sv[1]); + } + return rv; } diff --git a/ndk/sources/android/libportable/common/include/errno_portable.h b/ndk/sources/android/libportable/common/include/errno_portable.h index 07b87318f..17f4d0a5d 100644 --- a/ndk/sources/android/libportable/common/include/errno_portable.h +++ b/ndk/sources/android/libportable/common/include/errno_portable.h @@ -127,6 +127,7 @@ #define EOWNERDEAD_PORTABLE 130 #define ENOTRECOVERABLE_PORTABLE 131 -extern __hidden int ntop_errno(int native_errno); +extern __hidden int errno_ntop(int native_errno); +extern __hidden int errno_pton(int native_errno); #endif /* _ERRNO_PORTABLE_H */