www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to execute cleanup code on Ctrl-C (Break)?

reply "Paul Dufresne" <dufresnep gmail.com> writes:
I am trying to translate some C++ code to D to learn D.

And the first lines to translate are:
signal(SIGINT, (sighandler_t) shutdownClient);
signal(SIGTERM, (sighandler_t) shutdownClient);

So I come to try:
import std.stdio;
void main(){
     try {
	  while (true) writeln("H1!!");
	} finally writeln("oh... Bye then!");
}

Using 2.059 dmd on Windows.
I expected the "ob... Bye then!" to show up on Ctrl-C, but it did 
not:
H1!!
H1!!
H1!!
H1!!
^C
C:\Users\Paul\myd>

I have seens that there is std.signals but that does not really 
seems related.

Help!
Jul 08 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, July 08, 2012 18:57:17 Paul Dufresne wrote:
 I am trying to translate some C++ code to D to learn D.
 
 And the first lines to translate are:
 signal(SIGINT, (sighandler_t) shutdownClient);
 signal(SIGTERM, (sighandler_t) shutdownClient);
 
 So I come to try:
 import std.stdio;
 void main(){
      try {
 	  while (true) writeln("H1!!");
 	} finally writeln("oh... Bye then!");
 }
 
 Using 2.059 dmd on Windows.
 I expected the "ob... Bye then!" to show up on Ctrl-C, but it did
 not:
 H1!!
 H1!!
 H1!!
 H1!!
 ^C
 C:\Users\Paul\myd>
 
 I have seens that there is std.signals but that does not really
 seems related.
 
 Help!
I wouldn't expect an exception from ctrl-c. That sends a signal to kill the program, which normally means that you're program is killed without any exceptions being thrown or anything of the sort. You just get to do something in the signal handler if you catch the kill signal and _then_ the program dies. But maybe Windows does something differently. I don't know. I use Linux almost exclusively, and you definitely _don't_ get an exception in Linux.
Jul 08 2012
parent reply "Paul Dufresne" <dufresnep gmail.com> writes:
Well, I was looking the documentation and not finding how to 
catch signals.

I thought, hey, does Windows have Posix signals?
And the answer seems to be that Windows conform to Posix.1 (which 
is old, but does define signals)... after all, the code I want to 
translate does run in MinGW.

So, I search back this list... and the answer I am following 
right now, is

"That module is part of druntime, and you can import it with
  import core.sys.posix.signal;

  The documentation isn't on dlang.org, probably because dlang.org
  doesn't contain the documentation for OS-specific modules (it's 
hard
  to generate the documentation for those when you're not on the 
same
  OS).

So I am now reading this file on my installation:
C:\dmd2\src\druntime\import\core\sys\posix\signal.di
Jul 08 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, July 09, 2012 03:31:52 Paul Dufresne wrote:
 Well, I was looking the documentation and not finding how to
 catch signals.
 
 I thought, hey, does Windows have Posix signals?
 And the answer seems to be that Windows conform to Posix.1 (which
 is old, but does define signals)... after all, the code I want to
 translate does run in MinGW.
 
 So, I search back this list... and the answer I am following
 right now, is
 
 "That module is part of druntime, and you can import it with
   import core.sys.posix.signal;
 
   The documentation isn't on dlang.org, probably because dlang.org
   doesn't contain the documentation for OS-specific modules (it's
 hard
   to generate the documentation for those when you're not on the
 same
   OS).
 
 So I am now reading this file on my installation:
 C:\dmd2\src\druntime\import\core\sys\posix\signal.di
With POSIX signal handling, you do whatever cleanup you do in the signal handler and that's it. You can make it so that the signal is ignored, I believe, but if it's a -9, then you can't (and in that case, I'm not even sure that you get to handle it). Normally, you let the OS kill your program after you've done whatever handling you do in your signal handler, in which case there is no graceful shutdown. But if you want a graceful shutdown, you may be able to have your signal handler eat the kill signal and then tell all of the threads in your program to shutdown, in which case, they would each have to handle shutting themselves down gracefully. And unless you have all of your threads keep checking a shared global variable which indicates that they should shutdown or (preferrably) you're using std.concurrency and each thread is watching for messages to shutdown, there's no way to get the threads to shutdown gracefully. You can't do anything like have all of your threads suddenly throw exceptions from wherever they are. - Jonathan M Davis
Jul 08 2012
parent reply "Paul Dufresne" <dufresnep gmail.com> writes:
Well, I just want to close a socket before quiting if the user 
press Ctrl-C.

That said, looking through the code, I would say that it have no 
implementation for Windows... even if it should have signals.

And even there, I do not really understand how I am suppose to 
use it.
I think it should looks like:

import std.stdio;
import core.sys.posix.signal;

void mybye(int value){
   writeln("oh... Bye then!");
}

void main(){
     sigset(SIGINT, &mybye);
	while (true) writeln("H1!!");
}

which gives me:
C:\Users\Paul\myd>dmd loop2.d
loop2.d(9): Error: undefined identifier sigset

Which I guess is because there is no Windows implementation... 
yet.
Jul 08 2012
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, July 09, 2012 04:15:08 Paul Dufresne wrote:
 Well, I just want to close a socket before quiting if the user
 press Ctrl-C.
 
 That said, looking through the code, I would say that it have no
 implementation for Windows... even if it should have signals.
 
 And even there, I do not really understand how I am suppose to
 use it.
 I think it should looks like:
 
 import std.stdio;
 import core.sys.posix.signal;
 
 void mybye(int value){
    writeln("oh... Bye then!");
 }
 
 void main(){
      sigset(SIGINT, &mybye);
 	while (true) writeln("H1!!");
 }
 
 which gives me:
 C:\Users\Paul\myd>dmd loop2.d
 loop2.d(9): Error: undefined identifier sigset
 
 Which I guess is because there is no Windows implementation...
 yet.
core.sys.posix is for _POSIX_ OSes only. Much as Windows does implement some POSIX functions, it's is not a POSIX OS (version(Posix) blocks will not compile for it). If you want Windows stuff, you need to look in core.sys.windows, which unfortunately is currently rather sparse overall, so I very much doubt that there's any kind of signal handling in it right now. If you want additional Win32 functions, take at look at this 3rd party project: http://dsource.org/projects/bindings/wiki/WindowsApi - Jonathan M Davis
Jul 08 2012
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On 07/09/2012 11:15 AM, Paul Dufresne wrote:
 Well, I just want to close a socket before quiting if the user press
 Ctrl-C.

 That said, looking through the code, I would say that it have no
 implementation for Windows... even if it should have signals.

 And even there, I do not really understand how I am suppose to use it.
 I think it should looks like:

 import std.stdio;
 import core.sys.posix.signal;

 void mybye(int value){
    writeln("oh... Bye then!");
 }

 void main(){
      sigset(SIGINT, &mybye);
      while (true) writeln("H1!!");
 }

 which gives me:
 C:\Users\Paul\myd>dmd loop2.d
 loop2.d(9): Error: undefined identifier sigset

 Which I guess is because there is no Windows implementation... yet.
There *won't* be a Windows implementation. THis is a Posix API, not a D one. In Windows, you need to use SetConsoleCtrlHandler. http://msdn.microsoft.com/en-us/library/windows/desktop/ms686016(v=vs.85).aspx
Jul 08 2012