diff --git a/ndk/sources/android/libportable/arch-mips/signal.c b/ndk/sources/android/libportable/arch-mips/signal.c new file mode 100644 index 000000000..7da280157 --- /dev/null +++ b/ndk/sources/android/libportable/arch-mips/signal.c @@ -0,0 +1,17 @@ +/* + * Copyright 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include diff --git a/ndk/sources/android/libportable/common/include/signal_portable.h b/ndk/sources/android/libportable/common/include/signal_portable.h new file mode 100644 index 000000000..e80db4b85 --- /dev/null +++ b/ndk/sources/android/libportable/common/include/signal_portable.h @@ -0,0 +1,442 @@ +/* + * Copyright 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SIGNAL_PORTABLE_H_ +#define _SIGNAL_PORTABLE_H_ + +#if (__mips__) + +#include +#include +#include +#include + +struct stack_t_portable { + void *ss_sp; + int ss_flags; + size_t ss_size; +}; + +static inline void stack_t_pton(const struct stack_t_portable *ptr_p, stack_t *ptr_n) { + memset(ptr_n, '\0', sizeof(stack_t)); + ptr_n->ss_sp = ptr_p->ss_sp; + ptr_n->ss_flags = ptr_p->ss_flags; + ptr_n->ss_size = ptr_p->ss_size; +} + +static inline void stack_t_ntop(const stack_t *ptr_n, struct stack_t_portable *ptr_p) { + memset(ptr_p, '\0', sizeof(struct stack_t_portable)); + ptr_p->ss_sp = ptr_n->ss_sp; + ptr_p->ss_flags = ptr_n->ss_flags; + ptr_p->ss_size = ptr_n->ss_size; +} + +int WRAP(sigaltstack)(const struct stack_t_portable *ss, struct stack_t_portable *oss) { + stack_t ss_n, oss_n; + if (ss != NULL) { + stack_t_pton(ss, &ss_n); + if (oss != NULL){ + int ret = REAL(sigaltstack)(&ss_n, &oss_n); + stack_t_ntop(&oss_n, oss); + return ret; + } + else + return REAL(sigaltstack)(&ss_n, NULL); + } + else if (oss != NULL) { + int ret = REAL(sigaltstack)(NULL, &oss_n); + stack_t_ntop(&oss_n, oss); + return ret; + } + else + return REAL(sigaltstack)(NULL, NULL); +} + +#define SIGHUP_PORTABLE 1 +#define SIGINT_PORTABLE 2 +#define SIGQUIT_PORTABLE 3 +#define SIGILL_PORTABLE 4 +#define SIGTRAP_PORTABLE 5 +#define SIGABRT_PORTABLE 6 +#define SIGIOT_PORTABLE 6 +#define SIGBUS_PORTABLE 7 +#define SIGFPE_PORTABLE 8 +#define SIGKILL_PORTABLE 9 +#define SIGUSR1_PORTABLE 10 +#define SIGSEGV_PORTABLE 11 +#define SIGUSR2_PORTABLE 12 +#define SIGPIPE_PORTABLE 13 +#define SIGALRM_PORTABLE 14 +#define SIGTERM_PORTABLE 15 +// unsupported in MIPS +#define SIGSTKFLT_PORTABLE 16 +// +#define SIGCHLD_PORTABLE 17 +#define SIGCONT_PORTABLE 18 +#define SIGSTOP_PORTABLE 19 +#define SIGTSTP_PORTABLE 20 +#define SIGTTIN_PORTABLE 21 +#define SIGTTOU_PORTABLE 22 +#define SIGURG_PORTABLE 23 +#define SIGXCPU_PORTABLE 24 +#define SIGXFSZ_PORTABLE 25 +#define SIGVTALRM_PORTABLE 26 +#define SIGPROF_PORTABLE 27 +#define SIGWINCH_PORTABLE 28 +#define SIGIO_PORTABLE 29 +#define SIGPOLL_PORTABLE SIGIO_PORTABLE +#define SIGPWR_PORTABLE 30 +#define SIGSYS_PORTABLE 31 +#define SIGUNUSED_PORTABLE 31 +// unsupported in MIPS +#define SIGSWI_PORTABLE 32 +// + +static inline int signo_pton(int signum_p) { + switch(signum_p) { + case SIGHUP_PORTABLE: return SIGHUP; + case SIGINT_PORTABLE: return SIGINT; + case SIGQUIT_PORTABLE: return SIGQUIT; + case SIGILL_PORTABLE: return SIGILL; + case SIGTRAP_PORTABLE: return SIGTRAP; + case SIGABRT_PORTABLE: return SIGABRT; + case SIGBUS_PORTABLE: return SIGBUS; + case SIGFPE_PORTABLE: return SIGFPE; + case SIGKILL_PORTABLE: return SIGKILL; + case SIGUSR1_PORTABLE: return SIGUSR1; + case SIGSEGV_PORTABLE: return SIGSEGV; + case SIGUSR2_PORTABLE: return SIGUSR2; + case SIGPIPE_PORTABLE: return SIGPIPE; + case SIGALRM_PORTABLE: return SIGALRM; + case SIGTERM_PORTABLE: return SIGTERM; + case SIGCHLD_PORTABLE: return SIGCHLD; + case SIGCONT_PORTABLE: return SIGCONT; + case SIGSTOP_PORTABLE: return SIGSTOP; + case SIGTSTP_PORTABLE: return SIGTSTP; + case SIGTTIN_PORTABLE: return SIGTTIN; + case SIGTTOU_PORTABLE: return SIGTTOU; + case SIGURG_PORTABLE: return SIGURG; + case SIGXCPU_PORTABLE: return SIGXCPU; + case SIGXFSZ_PORTABLE: return SIGXFSZ; + case SIGVTALRM_PORTABLE: return SIGVTALRM; + case SIGPROF_PORTABLE: return SIGPROF; + case SIGWINCH_PORTABLE: return SIGWINCH; + case SIGIO_PORTABLE: return SIGIO; + case SIGPWR_PORTABLE: return SIGPWR; + case SIGSYS_PORTABLE: return SIGSYS; + default: + fprintf(stderr, "Unknown SIGNAL:%d\n", signum_p); + abort(); + } +} + +static inline int signo_ntop(int signum_n) { + switch(signum_n) { + case SIGHUP: return SIGHUP_PORTABLE; + case SIGINT: return SIGINT_PORTABLE; + case SIGQUIT: return SIGQUIT_PORTABLE; + case SIGILL: return SIGILL_PORTABLE; + case SIGTRAP: return SIGTRAP_PORTABLE; + case SIGABRT: return SIGABRT_PORTABLE; + case SIGBUS: return SIGBUS_PORTABLE; + case SIGFPE: return SIGFPE_PORTABLE; + case SIGKILL: return SIGKILL_PORTABLE; + case SIGUSR1: return SIGUSR1_PORTABLE; + case SIGSEGV: return SIGSEGV_PORTABLE; + case SIGUSR2: return SIGUSR2_PORTABLE; + case SIGPIPE: return SIGPIPE_PORTABLE; + case SIGALRM: return SIGALRM_PORTABLE; + case SIGTERM: return SIGTERM_PORTABLE; + case SIGCHLD: return SIGCHLD_PORTABLE; + case SIGCONT: return SIGCONT_PORTABLE; + case SIGSTOP: return SIGSTOP_PORTABLE; + case SIGTSTP: return SIGTSTP_PORTABLE; + case SIGTTIN: return SIGTTIN_PORTABLE; + case SIGTTOU: return SIGTTOU_PORTABLE; + case SIGURG: return SIGURG_PORTABLE; + case SIGXCPU: return SIGXCPU_PORTABLE; + case SIGXFSZ: return SIGXFSZ_PORTABLE; + case SIGVTALRM: return SIGVTALRM_PORTABLE; + case SIGPROF: return SIGPROF_PORTABLE; + case SIGWINCH: return SIGWINCH_PORTABLE; + case SIGIO: return SIGIO_PORTABLE; + case SIGPWR: return SIGPWR_PORTABLE; + case SIGSYS: return SIGSYS_PORTABLE; + default: + fprintf(stderr, "Unknown SIGNAL:%d\n", signum_n); + abort(); + } +} + +#define SA_NOCLDSTOP_PORTABLE 0x00000001 +#define SA_NOCLDWAIT_PORTABLE 0x00000002 +#define SA_SIGINFO_PORTABLE 0x00000004 +// unsupported in MIPS +#define SA_THIRTYTWO_PORTABLE 0x02000000 +#define SA_RESTORER_PORTABLE 0x04000000 +// +#define SA_ONSTACK_PORTABLE 0x08000000 +#define SA_RESTART_PORTABLE 0x10000000 +#define SA_NODEFER_PORTABLE 0x40000000 +#define SA_RESETHAND_PORTABLE 0x80000000 +#define SA_NOMASK_PORTABLE SA_NODEFER_PORTABLE +#define SA_ONESHOT_PORTABLE SA_RESETHAND_PORTABLE + +static inline int sa_flags_pton(int sa_flags_p) { + int sa_flags_n = 0; + sa_flags_n |= (sa_flags_p & SA_NOCLDSTOP_PORTABLE) ? SA_NOCLDSTOP : 0; + sa_flags_n |= (sa_flags_p & SA_NOCLDWAIT_PORTABLE) ? SA_NOCLDWAIT : 0; + sa_flags_n |= (sa_flags_p & SA_SIGINFO_PORTABLE) ? SA_SIGINFO : 0; + sa_flags_n |= (sa_flags_p & SA_ONSTACK_PORTABLE) ? SA_ONSTACK : 0; + sa_flags_n |= (sa_flags_p & SA_RESTART_PORTABLE) ? SA_RESTART : 0; + sa_flags_n |= (sa_flags_p & SA_NODEFER_PORTABLE) ? SA_NODEFER : 0; + sa_flags_n |= (sa_flags_p & SA_RESETHAND_PORTABLE) ? SA_RESETHAND : 0; + return sa_flags_n; +} + +static inline int sa_flags_ntop(int sa_flags_n) { + int sa_flags_p = 0; + sa_flags_p |= (sa_flags_n & SA_NOCLDSTOP) ? SA_NOCLDSTOP_PORTABLE : 0; + sa_flags_p |= (sa_flags_n & SA_NOCLDWAIT) ? SA_NOCLDWAIT_PORTABLE : 0; + sa_flags_p |= (sa_flags_n & SA_SIGINFO) ? SA_SIGINFO_PORTABLE : 0; + sa_flags_p |= (sa_flags_n & SA_ONSTACK) ? SA_ONSTACK_PORTABLE : 0; + sa_flags_p |= (sa_flags_n & SA_RESTART) ? SA_RESTART_PORTABLE : 0; + sa_flags_p |= (sa_flags_n & SA_NODEFER) ? SA_NODEFER_PORTABLE : 0; + sa_flags_p |= (sa_flags_n & SA_RESETHAND) ? SA_RESETHAND_PORTABLE : 0; + return sa_flags_p; +} + +typedef unsigned long sigset_t_portable; +struct sigaction_portable { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t_portable sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); // obsolete +}; + +static inline void sigset_t_pton(const sigset_t_portable *ptr_p, sigset_t *ptr_n) { + memset(ptr_n, '\0', sizeof(sigset_t)); + ptr_n->sig[0] = *ptr_p; +} + +static inline void sigset_t_ntop(const sigset_t *ptr_n, sigset_t_portable *ptr_p) { + memset(ptr_p, '\0', sizeof(sigset_t_portable)); + *ptr_p = ptr_n->sig[0]; +} + +static inline void sigaction_pton(const struct sigaction_portable *ptr_p, struct sigaction *ptr_n) { + memset(ptr_n, '\0', sizeof(struct sigaction)); + ptr_n->sa_sigaction = ptr_p->_u._sa_sigaction; + sigset_t_pton(&ptr_p->sa_mask, &ptr_n->sa_mask); + ptr_n->sa_flags = sa_flags_pton(ptr_p->sa_flags); +} + +static inline void sigaction_ntop(const struct sigaction *ptr_n, struct sigaction_portable *ptr_p) { + memset(ptr_p, '\0', sizeof(struct sigaction_portable)); + ptr_p->_u._sa_sigaction = ptr_n->sa_sigaction; + sigset_t_ntop(&ptr_n->sa_mask, &ptr_p->sa_mask); + ptr_p->sa_flags = sa_flags_ntop(ptr_n->sa_flags); +} + +int WRAP(sigaction)(int signum, const struct sigaction_portable *act, struct sigaction_portable *oldact) { + struct sigaction act_n, oldact_n; + int signum_n = signo_pton(signum); + + if (act != NULL) { + sigaction_pton(act, &act_n); + if (oldact != NULL) { + int ret = REAL(sigaction)(signum_n, &act_n, &oldact_n); + sigaction_ntop(&oldact_n, oldact); + return ret; + } + else + return REAL(sigaction)(signum_n, &act_n, NULL); + } + else if (oldact != NULL) { + int ret = REAL(sigaction)(signum_n, NULL, &oldact_n); + sigaction_ntop(&oldact_n, oldact); + return ret; + } + else + return REAL(sigaction)(signum_n, NULL, NULL); +} + +int WRAP(sigaddset)(sigset_t_portable *set, int signum) { + int signum_n = signo_pton(signum); + sigset_t set_n; + sigset_t_pton(set, &set_n); + int ret = REAL(sigaddset)(&set_n, signum_n); + sigset_t_ntop(&set_n, set); + return ret; +} + +int WRAP(sigdelset)(sigset_t_portable *set, int signum) { + int signum_n = signo_pton(signum); + sigset_t set_n; + sigset_t_pton(set, &set_n); + int ret = REAL(sigdelset)(&set_n, signum_n); + sigset_t_ntop(&set_n, set); + return ret; +} + +int WRAP(sigemptyset)(sigset_t_portable *set){ + sigset_t set_n; + sigset_t_pton(set, &set_n); + int ret = REAL(sigemptyset)(&set_n); + sigset_t_ntop(&set_n, set); + return ret; +} + +int WRAP(sigfillset)(sigset_t_portable *set){ + sigset_t set_n; + sigset_t_pton(set, &set_n); + int ret = REAL(sigfillset)(&set_n); + sigset_t_ntop(&set_n, set); + return ret; +} + +int WRAP(sigismember)(const sigset_t_portable *set, int signum) { + int signum_n = signo_pton(signum); + sigset_t set_n; + sigset_t_pton(set, &set_n); + return REAL(sigismember)(&set_n, signum_n); +} + +int WRAP(sigpending)(sigset_t_portable *set) { + sigset_t set_n; + sigset_t_pton(set, &set_n); + int ret = REAL(sigpending)(&set_n); + sigset_t_ntop(&set_n, set); + return ret; +} + +#define SIG_BLOCK_PORTABLE 0 +#define SIG_UNBLOCK_PORTABLE 1 +#define SIG_SETMASK_PORTABLE 2 + +int WRAP(sigprocmask)(int how, const sigset_t_portable *set, sigset_t_portable *oldset) { + int how_n; + switch(how) { + case SIG_BLOCK_PORTABLE: how_n = SIG_BLOCK; break; + case SIG_UNBLOCK_PORTABLE: how_n = SIG_UNBLOCK; break; + case SIG_SETMASK_PORTABLE: how_n = SIG_SETMASK; break; + default: + fprintf(stderr, "Unknown sigprocmask action:%d\n", how); + abort(); + } + sigset_t set_n, oldset_n; + if (set != NULL) { + sigset_t_pton(set, &set_n); + if (oldset != NULL) { + int ret = REAL(sigprocmask)(how_n, &set_n, &oldset_n); + sigset_t_ntop(&oldset_n, oldset); + return ret; + } + else + return REAL(sigprocmask)(how_n, &set_n, NULL); + } + else if (oldset != NULL) { + int ret = REAL(sigprocmask)(how_n, NULL, &oldset_n); + sigset_t_ntop(&oldset_n, oldset); + return ret; + } + else + return REAL(sigprocmask)(how_n, NULL, NULL); +} + +int WRAP(sigsuspend)(const sigset_t_portable *mask) { + sigset_t mask_n; + sigset_t_pton(mask, &mask_n); + return REAL(sigsuspend)(&mask_n); +} + +int WRAP(sigwait)(const sigset_t_portable *set, int *sig) { + sigset_t set_n; + sigset_t_pton(set, &set_n); + int ret = REAL(sigwait)(&set_n, sig); + *sig = signo_ntop(*sig); + return ret; +} + +int WRAP(kill)(pid_t pid, int sig) { + int sig_n = signo_pton(sig); + return REAL(kill)(pid, sig_n); +} + +// sigset_t related function +#include +int WRAP(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t_portable *sigmask) { + sigset_t sigmask_n; + sigset_t_pton(sigmask, &sigmask_n); + return REAL(pselect)(nfds, readfds, writefds, exceptfds, timeout, sigmask_n); +} + +#include +int WRAP(signalfd)(int fd, const sigset_t_portable* mask, int flags) { + sigset_t mask_n; + sigset_t_pton(mask, &mask_n); + return REAL(signalfd)(fd, mask_n, flags); +} + +#include +int WRAP(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, const sigset_t_portable *sigmask) { + sigset_t sigmask_n; + sigset_t_pton(sigmask, &sigmask_n); + return REAL(ppoll)(fds, nfds, timeout_ts, sigmask_n); +} + +#include +int WRAP(pthread_sigmask)(int how, const sigset_t_portable *set, sigset_t_portable *oldset) { + int how_n; + switch(how) { + case SIG_BLOCK_PORTABLE: how_n = SIG_BLOCK; break; + case SIG_UNBLOCK_PORTABLE: how_n = SIG_UNBLOCK; break; + case SIG_SETMASK_PORTABLE: how_n = SIG_SETMASK; break; + default: + fprintf(stderr, "Unknown pthread_sigmask action:%d\n", how); + abort(); + } + sigset_t set_n, oldset_n; + if (set != NULL) { + sigset_t_pton(set, &set_n); + if (oldset != NULL) { + int ret = REAL(pthread_sigmask)(how_n, &set_n, &oldset_n); + sigset_t_ntop(&oldset_n, oldset); + return ret; + } + else + return REAL(pthread_sigmask)(how_n, &set_n, NULL); + } + else if (oldset != NULL) { + int ret = REAL(pthread_sigmask)(how_n, NULL, &oldset_n); + sigset_t_ntop(&oldset_n, oldset); + return ret; + } + else + return REAL(pthread_sigmask)(how_n, NULL, NULL); +} + +#include +int WRAP(epoll_pwait)(int fd, struct epoll_event* events, int max_events, int timeout, const sigset_t_portable* ss) { + sigset_t ss_n; + sigset_t_pton(ss, &ss_n); + return REAL(epoll_pwait)(fd, events, max_events, timeout, ss_n); +} +#endif /* __mips__ */ +#endif /* _SIGNAL_PORTABLE_H */