FPPS4/sys/signal.pas

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&LTOSTOP)
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.