Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2014-01

Suppressing ^C signal from stdin

5 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Mark Morgan Lloyd

When reading characters from a program's stdin using fpRead(), what's the best way of suppressing ^C so that it doesn't raise SIGTERM or whatever? I want to be able to handle signals indicating e.g. a UPS power-failure message, but not to get trivial stuff from the keyboard.

Platform is predominantly Linux, possibly also Solaris and one of the BSDs. Anybody porting the program to Windows will have to do their own dirty work :-)

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Sven Barth
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote 9 lines
When reading characters from a program's stdin using fpRead(), what's the best way of suppressing ^C so that it doesn't raise SIGTERM or whatever? I want to be able to handle signals indicating e.g. a UPS power-failure message, but not to get trivial stuff from the keyboard. Platform is predominantly Linux, possibly also Solaris and one of the BSDs. Anybody porting the program to Windows will have to do their own dirty work :-)

For Unix systems you could hook the SIGINT signal:

=== code begin ===

uses
   baseunix;
procedure SigIntHandler(signal: longint; info: psiginfo; context:
psigcontext); cdecl;
begin
   (* ignore signal *)
end;
var
   oldsigrec, newsigrec: sigactionrec;
begin
   FillChar(newsigrec, SizeOf(newsigrec), 0);
   newsigrec.sa_handler := @SigIntHandler;
   FpSigaction(SIGINT, @newsigrec, @oldsigrec);
   // do something
end.

=== code end ===

For Windows there is this:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms685049%28v=vs.85%29.aspx (your application should be of apptype console of course)

Regards,
Sven

Mark Morgan Lloyd
to Sven Barth
Sven Barth wrote 12 lines
On 01.01.2014 20:48, Mark Morgan Lloyd wrote: > When reading characters from a program's stdin using fpRead(), what's > the best way of suppressing ^C so that it doesn't raise SIGTERM or > whatever? I want to be able to handle signals indicating e.g. a UPS > power-failure message, but not to get trivial stuff from the keyboard. > > Platform is predominantly Linux, possibly also Solaris and one of the > BSDs. Anybody porting the program to Windows will have to do their own > dirty work :-) > For Unix systems you could hook the SIGINT signal:

[Slaps head] ^C is SIGINT, not SIGTERM :-) Still, I've just been looking at that siginfo structure and it's going to be interesting to see what one can find out from it.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Tomas Hajny
to Mark Morgan Lloyd: When reading characters from a program's stdin using fpRead(), what's the best way of…
Mark Morgan Lloyd wrote 8 lines
When reading characters from a program's stdin using fpRead(), what's the best way of suppressing ^C so that it doesn't raise SIGTERM or whatever? I want to be able to handle signals indicating e.g. a UPS power-failure message, but not to get trivial stuff from the keyboard. Platform is predominantly Linux, possibly also Solaris and one of the BSDs. Anybody porting the program to Windows will have to do their own dirty work :-)

The general platform independent solution would have been 'Crt.CheckBreak := false' (or System.SysSetCtrlBreakHandler without unit Crt should you not use/need that) - except for the fact that maintainers of most platforms (all those mentioned by you) decided not to implement/support this functionality and thus it would not work for those platforms you are interested in... :-/

Tomas

Mark Morgan Lloyd
to Tomas Hajny
Tomas Hajny wrote 16 lines
On Wed, January 1, 2014 20:48, Mark Morgan Lloyd wrote: > When reading characters from a program's stdin using fpRead(), what's > the best way of suppressing ^C so that it doesn't raise SIGTERM or > whatever? I want to be able to handle signals indicating e.g. a UPS > power-failure message, but not to get trivial stuff from the keyboard. > > Platform is predominantly Linux, possibly also Solaris and one of the > BSDs. Anybody porting the program to Windows will have to do their own > dirty work :-) The general platform independent solution would have been 'Crt.CheckBreak := false' (or System.SysSetCtrlBreakHandler without unit Crt should you not use/need that) - except for the fact that maintainers of most platforms (all those mentioned by you) decided not to implement/support this functionality and thus it would not work for those platforms you are interested in... :-/

Good point. In practice using Crt might be a problem when I come to adding an alternative graphical frontend to the emulator: I think this highlights (as has been discussed elsewhere) the lack of a simple terminal component in Lazarus.

I've played around a bit and find that in Linux (other platforms untested) provided that I add action.Sa_Flags := SA_SIGINFO; I can get the PID inside the signal handler. This is zero for a ^C, which potentially allows one to distinguish between a spurious ^C and a SIGINT sent by kill.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]