2
Copyright (c) 1997-98 by Michael Van Canneyt
4
Unit to catch segmentation faults and Ctrl-C and exit gracefully
7
See the file COPYING.FPC, included in this distribution,
8
for details about the copyright.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
**********************************************************************}
44
NewSignal,OldSigSegm,OldSigILL,
45
OldSigInt,OldSigFPE : SignalHandler;
49
CtrlCPressed : Boolean = false;
51
Procedure EnableCatchSignals;
52
Procedure DisableCatchSignals;
55
procedure Generate_SIGSEGV;
56
procedure Generate_SIGFPE;
62
StopJmpValid : boolean = false;
81
SIGTIMR = 303; { Internal for setitimer (SIGALRM, SIGPROF) }
101
LastCtrlC : longint = 0;
104
{$ifdef useresstrings}
109
msg_quitconfirm = 'Do You really want to quit?';
113
procedure Generate_SIGSEGV;
118
l:=pointer (ptrint ($ffffffff));
122
procedure Generate_SIGFPE;
134
{$ifndef SignalIsFunction}
135
Procedure Catchsignal(Sig : Longint);cdecl;
136
{$else SignalIsFunction}
137
{$ifdef SignalIsCdecl}
138
Function Catchsignal(Sig : longint):longint; cdecl;
139
{$else not SignalIsCdecl}
140
Function Catchsignal(Sig : longint):longint;
141
{$endif not SignalIsCdecl}
142
{$endif SignalIsFunction}
143
var MustQuit: boolean;
148
LongJmp(StopJmp,SIGSEGV);
149
if Assigned(Application) then IDEApp.Done;
150
Writeln('Internal SIGSEGV Error caught');
159
LongJmp(StopJmp,SIGFPE);
160
if Assigned(Application) then IDEApp.Done;
161
Writeln('Internal SIGFPE Error caught');
170
LongJmp(StopJmp,SIGILL);
171
if Assigned(Application) then IDEApp.Done;
172
Writeln('Internal SIGILL Error caught');
181
LongJmp(StopJmp,SIGINT);
182
IF NOT CtrlCPressed and Assigned(Application) then
186
if GetDosTicks>LastCtrlC+10 then
189
Keyboard.PutKeyEvent((kbCtrl shl 16) or kbCtrlC);
190
LastCtrlC:=GetDosTicks;
196
if Assigned(Application) then
197
MustQuit:=MessageBox(#3+msg_QuitConfirm,nil,mferror+mfyesbutton+mfnobutton)=cmYes
203
if Assigned(Application) then IDEApp.Done;
212
{$ifdef SignalIsFunction}
214
{$endif SignalIsFunction}
216
{$endif def HasSignal}
220
CatchSignalsEnabled : boolean = false;
222
Procedure EnableCatchSignals;
227
if CatchSignalsEnabled then
230
if GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @Mode) then
233
Writeln(stderr,'Starting value of ConsoleMode is $',hexstr(Mode,8));
235
SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)),
236
(Mode or ENABLE_MOUSE_INPUT) and not ENABLE_PROCESSED_INPUT);
241
Writeln(stderr,'Call to GetConsoleMode failed, GetLastError=',
248
I think that it was an error to put that here PM
249
djgpp_set_ctrl_c(false);
250
at least since that this is now handled in fpusrscr.pas unit
255
NewSignal:=@CatchSignal;
257
NewSignal:=SignalHandler(CatchSignal);
259
OldSigSegm:={$ifdef unix}{$ifdef ver1_0}Signal{$else}fpSignal{$endif}{$else}Signal{$endif}(SIGSEGV,NewSignal);
260
OldSigInt:={$ifdef unix}{$ifdef ver1_0}Signal{$else}fpSignal{$endif}{$else}Signal{$endif}(SIGINT,NewSignal);
261
OldSigFPE:={$ifdef unix}{$ifdef ver1_0}Signal{$else}fpSignal{$endif}{$else}Signal{$endif}(SIGFPE,NewSignal);
262
OldSigILL:={$ifdef unix}{$ifdef ver1_0}Signal{$else}fpSignal{$endif}{$else}Signal{$endif}(SIGILL,NewSignal);
263
CatchSignalsEnabled:=true;
267
Procedure DisableCatchSignals;
270
if not CatchSignalsEnabled then
272
{$ifdef unix}{$ifdef ver1_0}Signal{$else}fpSignal{$endif}{$else}Signal{$endif}(SIGSEGV,OldSigSegm);
273
{$ifdef unix}{$ifdef ver1_0}Signal{$else}fpSignal{$endif}{$else}Signal{$endif}(SIGINT,OldSigInt);
274
{$ifdef unix}{$ifdef ver1_0}Signal{$else}fpSignal{$endif}{$else}Signal{$endif}(SIGFPE,OldSigFPE);
275
{$ifdef unix}{$ifdef ver1_0}Signal{$else}fpSignal{$endif}{$else}Signal{$endif}(SIGILL,OldSigILL);
276
CatchSignalsEnabled:=false;