Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
android /platform /bionic /refs/heads/main /. /libc /bionic /signal.cpp
blob: 77e6acf1fbeab1d466c619fc8b757f5c1984ca13 [file] [log] [blame] [edit]
/*
* Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include<errno.h>
#include<pthread.h>
#include<signal.h>
#include<string.h>
#include<sys/epoll.h>
#include<sys/signalfd.h>
#include<sys/types.h>
#include<time.h>
#include<unistd.h>
#include<platform/bionic/reserved_signals.h>
#include"private/ErrnoRestorer.h"
#include"private/SigSetConverter.h"
extern"C"int __rt_sigpending(constsigset64_t*,size_t);
extern"C"int __rt_sigqueueinfo(pid_t,int,siginfo_t*);
extern"C"int __rt_sigsuspend(constsigset64_t*,size_t);
extern"C"int __rt_sigtimedwait(constsigset64_t*,siginfo_t*,const timespec*,size_t);
int pthread_sigmask(int how,constsigset_t* new_set,sigset_t* old_set){
ErrnoRestorer errno_restorer;
return(sigprocmask(how, new_set, old_set)==-1)? errno:0;
}
int pthread_sigmask64(int how,constsigset64_t* new_set,sigset64_t* old_set){
ErrnoRestorer errno_restorer;
return(sigprocmask64(how, new_set, old_set)==-1)? errno:0;
}
template<typenameSigSetT>
intSigAddSet(SigSetT*set,int sig){
int bit= sig-1;// Signal numbers start at 1, but bit positions start at 0.
unsignedlong* local_set=reinterpret_cast<unsignedlong*>(set);
if(set==nullptr|| bit<0|| bit>=static_cast<int>(8*sizeof(*set))){
errno= EINVAL;
return-1;
}
local_set[bit/ LONG_BIT]|=1UL<<(bit% LONG_BIT);
return0;
}
int sigaddset(sigset_t*set,int sig){
returnSigAddSet(set, sig);
}
int sigaddset64(sigset64_t*set,int sig){
returnSigAddSet(set, sig);
}
unionBsdSigSet{
int mask;
sigset64_tset;
};
// This isn't in our header files, but is exposed on all architectures except riscv64.
extern"C"int sigblock(int mask){
BsdSigSet in{.mask= mask}, out;
if(sigprocmask64(SIG_BLOCK,&in.set,&out.set)==-1)return-1;
return out.mask;
}
// This isn't in our header files, but is exposed on all architectures except riscv64.
extern"C"int sigsetmask(int mask){
BsdSigSet in{.mask= mask}, out;
if(sigprocmask64(SIG_SETMASK,&in.set,&out.set)==-1)return-1;
return out.mask;
}
template<typenameSigSetT>
intSigDelSet(SigSetT*set,int sig){
int bit= sig-1;// Signal numbers start at 1, but bit positions start at 0.
unsignedlong* local_set=reinterpret_cast<unsignedlong*>(set);
if(set==nullptr|| bit<0|| bit>=static_cast<int>(8*sizeof(*set))){
errno= EINVAL;
return-1;
}
local_set[bit/ LONG_BIT]&=~(1UL<<(bit% LONG_BIT));
return0;
}
int sigdelset(sigset_t*set,int sig){
returnSigDelSet(set, sig);
}
int sigdelset64(sigset64_t*set,int sig){
returnSigDelSet(set, sig);
}
template<typenameSigSetT>
intSigEmptySet(SigSetT*set){
if(set==nullptr){
errno= EINVAL;
return-1;
}
memset(set,0,sizeof(*set));
return0;
}
int sigemptyset(sigset_t*set){
returnSigEmptySet(set);
}
int sigemptyset64(sigset64_t*set){
returnSigEmptySet(set);
}
template<typenameSigSetT>
intSigFillSet(SigSetT*set){
if(set==nullptr){
errno= EINVAL;
return-1;
}
memset(set,0xff,sizeof(*set));
return0;
}
int sigfillset(sigset_t*set){
returnSigFillSet(set);
}
int sigfillset64(sigset64_t*set){
returnSigFillSet(set);
}
int sighold(int sig){
sigset64_tset={};
if(sigaddset64(&set, sig)==-1)return-1;
return sigprocmask64(SIG_BLOCK,&set,nullptr);
}
int sigignore(int sig){
struct sigaction64 sa={.sa_handler= SIG_IGN};
return sigaction64(sig,&sa,nullptr);
}
int siginterrupt(int sig,int flag){
struct sigaction64 act;
sigaction64(sig,nullptr,&act);
if(flag){
act.sa_flags&=~SA_RESTART;
}else{
act.sa_flags|= SA_RESTART;
}
return sigaction64(sig,&act,nullptr);
}
template<typenameSigSetT>
intSigIsMember(constSigSetT*set,int sig){
int bit= sig-1;// Signal numbers start at 1, but bit positions start at 0.
constunsignedlong* local_set=reinterpret_cast<constunsignedlong*>(set);
if(set==nullptr|| bit<0|| bit>=static_cast<int>(8*sizeof(*set))){
errno= EINVAL;
return-1;
}
returnstatic_cast<int>((local_set[bit/ LONG_BIT]>>(bit% LONG_BIT))&1);
}
int sigismember(constsigset_t*set,int sig){
returnSigIsMember(set, sig);
}
int sigismember64(constsigset64_t*set,int sig){
returnSigIsMember(set, sig);
}
__LIBC_HIDDEN__sighandler_t _signal(int sig,sighandler_t handler,int flags){
struct sigaction64 sa={.sa_handler= handler,.sa_flags= flags};
return(sigaction64(sig,&sa,&sa)==-1)? SIG_ERR: sa.sa_handler;
}
sighandler_t signal(int sig,sighandler_t handler){
return _signal(sig, handler, SA_RESTART);
}
int sigpause(int sig){
sigset64_tset={};
if(sigprocmask64(SIG_SETMASK,nullptr,&set)==-1|| sigdelset64(&set, sig)==-1)return-1;
return sigsuspend64(&set);
}
int sigpending(sigset_t* bionic_set){
SigSetConverterset{bionic_set};
if(__rt_sigpending(set.ptr,sizeof(sigset64_t))==-1)return-1;
set.copy_out();
return0;
}
int sigpending64(sigset64_t*set){
return __rt_sigpending(set,sizeof(*set));
}
int sigqueue(pid_t pid,int sig,const sigval value){
siginfo_t info={.si_code= SI_QUEUE};
info.si_signo= sig;
info.si_pid= getpid();
info.si_uid= getuid();
info.si_value= value;
return __rt_sigqueueinfo(pid, sig,&info);
}
int sigrelse(int sig){
sigset64_tset={};
if(sigaddset64(&set, sig)==-1)return-1;
return sigprocmask64(SIG_UNBLOCK,&set,nullptr);
}
sighandler_t sigset(int sig,sighandler_t disp){
struct sigaction64 new_sa;
if(disp!= SIG_HOLD) new_sa={.sa_handler= disp};
struct sigaction64 old_sa;
if(sigaction64(sig,(disp== SIG_HOLD)?nullptr:&new_sa,&old_sa)==-1){
return SIG_ERR;
}
sigset64_t new_mask={};
sigaddset64(&new_mask, sig);
sigset64_t old_mask;
if(sigprocmask64(disp== SIG_HOLD? SIG_BLOCK: SIG_UNBLOCK,&new_mask,&old_mask)==-1){
return SIG_ERR;
}
return sigismember64(&old_mask, sig)? SIG_HOLD: old_sa.sa_handler;
}
int sigsuspend(constsigset_t* bionic_set){
SigSetConverterset{bionic_set};
return sigsuspend64(set.ptr);
}
int sigsuspend64(constsigset64_t*set){
sigset64_t mutable_set;
sigset64_t* mutable_set_ptr=nullptr;
if(set){
mutable_set= filter_reserved_signals(*set, SIG_SETMASK);
mutable_set_ptr=&mutable_set;
}
return __rt_sigsuspend(mutable_set_ptr,sizeof(*set));
}
int sigtimedwait(constsigset_t* bionic_set,siginfo_t* info,const timespec* timeout){
SigSetConverterset{bionic_set};
return sigtimedwait64(set.ptr, info, timeout);
}
int sigtimedwait64(constsigset64_t*set,siginfo_t* info,const timespec* timeout){
sigset64_t mutable_set;
sigset64_t* mutable_set_ptr=nullptr;
if(set){
mutable_set= filter_reserved_signals(*set, SIG_SETMASK);
mutable_set_ptr=&mutable_set;
}
return __rt_sigtimedwait(mutable_set_ptr, info, timeout,sizeof(*set));
}
int sigwait(constsigset_t* bionic_set,int* sig){
SigSetConverterset{bionic_set};
return sigwait64(set.ptr, sig);
}
int sigwait64(constsigset64_t*set,int* sig){
// sigtimedwait64() doesn't fail with EINVAL on Linux,
// and EAGAIN can only happen with a timeout,
// so the error reporting here is effectively dead code.
ErrnoRestorer errno_restorer;
int result= TEMP_FAILURE_RETRY(sigtimedwait64(set,nullptr,nullptr));
if(result==-1)return errno;
*sig= result;
return0;
}
int sigwaitinfo(constsigset_t*set,siginfo_t* info){
return sigtimedwait(set, info,nullptr);
}
int sigwaitinfo64(constsigset64_t*set,siginfo_t* info){
return sigtimedwait64(set, info,nullptr);
}

[8]ページ先頭

©2009-2025 Movatter.jp