mirror of https://github.com/red-prig/fpPS4.git
327 lines
9.5 KiB
Plaintext
327 lines
9.5 KiB
Plaintext
unit signal;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
const
|
|
_SIG_WORDS =4;
|
|
_SIG_MAXSIG =128;
|
|
|
|
const
|
|
SIG_BLOCK =1;
|
|
SIG_UNBLOCK =2;
|
|
SIG_SETMASK =3;
|
|
|
|
SIGPROCMASK_OLD =$0001;
|
|
SIGPROCMASK_PROC_LOCKED =$0002;
|
|
SIGPROCMASK_PS_LOCKED =$0004;
|
|
SIGPROCMASK_FASTBLK =$0008;
|
|
|
|
const
|
|
SIGHUP =1; // hangup
|
|
SIGINT =2; // interrupt
|
|
SIGQUIT =3; // quit
|
|
SIGILL =4; // illegal instr. (not reset when caught)
|
|
SIGTRAP =5; // trace trap (not reset when caught)
|
|
SIGABRT =6; // abort()
|
|
SIGIOT =SIGABRT; // compatibility
|
|
SIGEMT =7; // EMT instruction
|
|
SIGFPE =8; // floating point exception
|
|
SIGKILL =9; // kill (cannot be caught or ignored)
|
|
SIGBUS =10; // bus error
|
|
SIGSEGV =11; // segmentation violation
|
|
SIGSYS =12; // non-existent system call invoked
|
|
SIGPIPE =13; // write on a pipe with no one to read it
|
|
SIGALRM =14; // alarm clock
|
|
SIGTERM =15; // software termination signal from kill
|
|
SIGURG =16; // urgent condition on IO channel
|
|
SIGSTOP =17; // sendable stop signal not from tty
|
|
SIGTSTP =18; // stop signal from tty
|
|
SIGCONT =19; // continue a stopped process
|
|
SIGCHLD =20; // to parent on child stop or exit
|
|
SIGTTIN =21; // to readers pgrp upon background tty read
|
|
SIGTTOU =22; // like TTIN if (tp->t_local<OSTOP)
|
|
SIGIO =23; // input/output possible signal
|
|
SIGXCPU =24; // exceeded CPU time limit
|
|
SIGXFSZ =25; // exceeded file size limit
|
|
SIGVTALRM=26; // virtual time alarm
|
|
SIGPROF =27; // profiling time alarm
|
|
SIGWINCH =28; // window size changes
|
|
SIGINFO =29; // information request
|
|
SIGUSR1 =30; // user defined signal 1
|
|
SIGUSR2 =31; // user defined signal 2
|
|
SIGTHR =32; // reserved by thread library.
|
|
SIGLWP =SIGTHR;
|
|
SIGCANCEL=SIGTHR;
|
|
|
|
NSIG=32;
|
|
|
|
SIGRTMIN=65;
|
|
SIGRTMAX=126;
|
|
|
|
SIG_DFL = 0; //default
|
|
SIG_IGN = 1; //ignore
|
|
SIG_ERR =-1;
|
|
SIG_CATCH= 2; //See signalvar.h
|
|
SIG_HOLD = 3;
|
|
|
|
SA_ONSTACK =$0001; // take signal on signal stack
|
|
SA_RESTART =$0002; // restart system call on signal return
|
|
SA_RESETHAND =$0004; // reset to SIG_DFL when taking signal
|
|
SA_NODEFER =$0010; // don't mask the signal we're delivering
|
|
SA_NOCLDWAIT =$0020; // don't keep zombies around
|
|
SA_SIGINFO =$0040; // signal handler with SA_SIGINFO args
|
|
|
|
SI_NOINFO =0; // No signal info besides si_signo.
|
|
SI_USER =$10001; // Signal sent by kill().
|
|
SI_QUEUE =$10002; // Signal sent by the sigqueue().
|
|
SI_TIMER =$10003; // Signal generated by expiration of a timer set by timer_settime().
|
|
SI_ASYNCIO=$10004; // Signal generated by completion of an asynchronous I/O request.
|
|
SI_MESGQ =$10005; // Signal generated by arrival of a message on an empty message queue.
|
|
SI_KERNEL =$10006;
|
|
SI_LWP =$10007; // Signal sent by thr_kill
|
|
|
|
//mc_fpformat
|
|
_MC_FPFMT_NODEV=$10000; // device not present or configured
|
|
_MC_FPFMT_XMM =$10002;
|
|
|
|
//mc_ownedfp
|
|
_MC_FPOWNED_NONE=$20000; // FP state not used
|
|
_MC_FPOWNED_FPU =$20001; // FP state came from FPU
|
|
_MC_FPOWNED_PCB =$20002; // FP state came from PCB
|
|
|
|
//mc_flags bits. Shall be in sync with TF_XXX.
|
|
_MC_HASSEGS =$1; //mc_ds,mc_es,mc_fs,mc_gs
|
|
_MC_HASBASES =$2; //mc_fsbase,mc_gsbase
|
|
_MC_HASFPXSTATE=$4; //xmm
|
|
_MC_FLAG_MASK =(_MC_HASSEGS or _MC_HASBASES or _MC_HASFPXSTATE);
|
|
|
|
TF_HASSEGS =$1;
|
|
TF_HASBASES =$2;
|
|
TF_HASFPXSTATE=$4;
|
|
|
|
type
|
|
p_sigset_t=^sigset_t;
|
|
sigset_t=packed record //16
|
|
Case Byte of
|
|
0:(bits:array[0.._SIG_WORDS-1] of DWORD);
|
|
1:(qwords:array[0..(_SIG_WORDS div 2)-1] of QWORD);
|
|
end;
|
|
{$IF sizeof(sigset_t)<>16}{$STOP sizeof(sigset_t)<>16}{$ENDIF}
|
|
|
|
sigval=packed record //8
|
|
Case Byte of
|
|
// Members as suggested by Annex C of POSIX 1003.1b.
|
|
0:(sival_int:Integer);
|
|
1:(sival_ptr:Pointer);
|
|
//6.0 compatibility
|
|
2:(sigval_int:Integer);
|
|
3:(sigval_ptr:Pointer);
|
|
end;
|
|
{$IF sizeof(sigval)<>8}{$STOP sizeof(sigval)<>8}{$ENDIF}
|
|
|
|
p_sigevent=^sigevent;
|
|
sigevent=packed record
|
|
sigev_notify:Integer; //Notification type
|
|
sigev_signo :Integer; //Signal number
|
|
sigev_value :sigval; //Signal value
|
|
|
|
_sigev_un:packed record
|
|
Case Byte of
|
|
0:(_threadid:Integer); //__lwpid_t
|
|
1:(_sigev_thread:packed record
|
|
_function :Pointer; //void (*_function)(union sigval);
|
|
_attribute:Pointer; //pthread_attr_t
|
|
end);
|
|
2:(__spare__:array[0..7] of QWORD);
|
|
end;
|
|
|
|
end;
|
|
|
|
p_siginfo_t=^siginfo_t;
|
|
siginfo_t=packed record //80
|
|
si_signo:Integer; //signal number
|
|
si_errno:Integer; //errno association
|
|
{
|
|
* Cause of signal, one of the SI_ macros or signal-specific
|
|
* values, i.e. one of the FPE_... values for SIGFPE. This
|
|
* value is equivalent to the second argument to an old-style
|
|
* FreeBSD signal handler.
|
|
}
|
|
si_code :Integer; // signal code SI_USER
|
|
si_pid :Integer; // sending process
|
|
si_uid :DWORD; // sender's ruid
|
|
si_status:Integer; // exit value
|
|
si_addr :Pointer; // faulting instruction
|
|
si_value :sigval; // signal value
|
|
|
|
_reason:packed record
|
|
Case Byte of
|
|
0:(_fault:packed record
|
|
_trapno:Integer; // machine specific trap code
|
|
end);
|
|
1:(_timer:packed record
|
|
_timerid:Integer;
|
|
_overrun:Integer;
|
|
end);
|
|
2:(_mesgq:packed record
|
|
_mqd:Integer;
|
|
end);
|
|
3:(_poll:packed record
|
|
_band:QWORD; // band event for SIGPOLL
|
|
end);
|
|
4:(__spare__:packed record
|
|
__spare1__:QWORD;
|
|
__spare2__:array[0..7] of Integer;
|
|
end);
|
|
end;
|
|
|
|
end;
|
|
{$IF sizeof(siginfo_t)<>80}{$STOP sizeof(siginfo_t)<>80}{$ENDIF}
|
|
|
|
sa_handler =procedure(sig,code:Integer;ctx:Pointer); SysV_ABI_CDecl;
|
|
sa_sigaction=procedure(sig:Integer;info:p_siginfo_t;ctx:Pointer); SysV_ABI_CDecl;
|
|
|
|
sig_t=sa_handler;
|
|
|
|
p_sigaction_t=^sigaction_t;
|
|
sigaction_t=packed record //28
|
|
|
|
u:packed record // signal handler
|
|
Case Byte of
|
|
0:(code:Ptrint); //SIG_DFL
|
|
1:(sa_handler:sa_handler); //void (*__sa_handler)(int);
|
|
2:(sa_sigaction:sa_sigaction); //void (*__sa_sigaction)(int, struct __siginfo *, void *); (sa_flags and SA_SIGINFO)<>0
|
|
end;
|
|
|
|
sa_flags:Integer; //SA_SIGINFO
|
|
sa_mask :sigset_t; //signal mask to apply (signal mask inside signal)
|
|
end;
|
|
{$IF sizeof(sigaction_t)<>28}{$STOP sizeof(sigaction_t)<>28}{$ENDIF}
|
|
|
|
sigaltstack=packed record
|
|
ss_sp :Pointer; //signal stack base
|
|
ss_size :size_t; //signal stack length SIGSTKSZ
|
|
ss_flags:Integer; //SS_DISABLE and/or SS_ONSTACK
|
|
_align :Integer;
|
|
end;
|
|
|
|
p_stack_t=^stack_t;
|
|
stack_t=sigaltstack;
|
|
{$IF sizeof(stack_t)<>24}{$STOP sizeof(stack_t)<>24}{$ENDIF}
|
|
|
|
const
|
|
SA_NOCLDSTOP=$0008; // do not generate SIGCHLD on child stop
|
|
|
|
SS_ONSTACK =$0001; // take signal on alternate stack
|
|
SS_DISABLE =$0004; // disable taking signals on alternate stack
|
|
MINSIGSTKSZ =(512*4); // minimum stack size
|
|
SIGSTKSZ =(MINSIGSTKSZ+32768); // recommended stack size
|
|
|
|
// uc_flags
|
|
_UC_SIGMASK=$01; // valid uc_sigmask
|
|
_UC_STACK =$02; // valid uc_stack
|
|
_UC_CPU =$04; // valid GPR context in uc_mcontext
|
|
_UC_FPU =$08; // valid FPU context in uc_mcontext
|
|
|
|
function _SIG_IDX(sig:Integer):DWORD; inline;
|
|
function _SIG_VALID(sig:Integer):Boolean; inline;
|
|
function _SIG_VALID_32(sig:Integer):Boolean; inline;
|
|
function _SIG_WORD(sig:Integer):DWORD; inline;
|
|
function _SIG_BIT(sig:Integer):DWORD; inline;
|
|
|
|
procedure ps_mtx_lock; external;
|
|
procedure ps_mtx_unlock; external;
|
|
|
|
function sigdeferstop:Integer; external;
|
|
procedure sigallowstop; external;
|
|
|
|
Function sigonstack(sp:size_t):Integer; external;
|
|
Function cursig(td:Pointer;stop_allowed:Integer):Integer; external;
|
|
procedure tdsignal(td:Pointer;sig:Integer); external;
|
|
procedure sigexit(td:Pointer;sig:Integer); external;
|
|
|
|
procedure ast; external;
|
|
|
|
Function kern_sigprocmask(td:Pointer;
|
|
how:Integer;
|
|
_set:p_sigset_t;
|
|
oset:p_sigset_t;
|
|
flags:Integer
|
|
):Integer; external;
|
|
|
|
function _get_sig_str(signum:Integer):RawByteString;
|
|
|
|
implementation
|
|
|
|
function _SIG_IDX(sig:Integer):DWORD; inline;
|
|
begin
|
|
Result:=sig-1;
|
|
end;
|
|
|
|
function _SIG_VALID(sig:Integer):Boolean; inline;
|
|
begin
|
|
Result:=(sig<=_SIG_MAXSIG) and (sig>0);
|
|
end;
|
|
|
|
function _SIG_VALID_32(sig:Integer):Boolean; inline;
|
|
begin
|
|
Result:=(sig<=32) and (sig>0);
|
|
end;
|
|
|
|
function _SIG_WORD(sig:Integer):DWORD; inline;
|
|
begin
|
|
Result:=_SIG_IDX(sig) shr 5;
|
|
end;
|
|
|
|
function _SIG_BIT(sig:Integer):DWORD; inline;
|
|
begin
|
|
Result:=1 shl (_SIG_IDX(sig) and 31);
|
|
end;
|
|
|
|
function _get_sig_str(signum:Integer):RawByteString;
|
|
begin
|
|
case signum of
|
|
SIGHUP :Result:='SIGHUP';
|
|
SIGINT :Result:='SIGINT';
|
|
SIGQUIT :Result:='SIGQUIT';
|
|
SIGILL :Result:='SIGILL';
|
|
SIGTRAP :Result:='SIGTRAP';
|
|
SIGABRT :Result:='SIGABRT';
|
|
SIGEMT :Result:='SIGEMT';
|
|
SIGFPE :Result:='SIGFPE';
|
|
SIGKILL :Result:='SIGKILL';
|
|
SIGBUS :Result:='SIGBUS';
|
|
SIGSEGV :Result:='SIGSEGV';
|
|
SIGSYS :Result:='SIGSYS';
|
|
SIGPIPE :Result:='SIGPIPE';
|
|
SIGALRM :Result:='SIGALRM';
|
|
SIGTERM :Result:='SIGTERM';
|
|
SIGURG :Result:='SIGURG';
|
|
SIGSTOP :Result:='SIGSTOP';
|
|
SIGTSTP :Result:='SIGTSTP';
|
|
SIGCONT :Result:='SIGCONT';
|
|
SIGCHLD :Result:='SIGCHLD';
|
|
SIGTTIN :Result:='SIGTTIN';
|
|
SIGTTOU :Result:='SIGTTOU';
|
|
SIGIO :Result:='SIGIO';
|
|
SIGXCPU :Result:='SIGXCPU';
|
|
SIGXFSZ :Result:='SIGXFSZ';
|
|
SIGVTALRM:Result:='SIGVTALRM';
|
|
SIGPROF :Result:='SIGPROF';
|
|
SIGWINCH :Result:='SIGWINCH';
|
|
SIGINFO :Result:='SIGINFO';
|
|
SIGUSR1 :Result:='SIGUSR1';
|
|
SIGUSR2 :Result:='SIGUSR2';
|
|
SIGTHR :Result:='SIGTHR';
|
|
else
|
|
Str(signum,Result);
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|
|
|