-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Graceful Ctrl+C handling #47
Comments
Handling Ctrl+C inside C#: using System;
using System.Threading;
public class CtrlC
{
public static void Main()
{
Console.WriteLine("Started");
Console.CancelKeyPress += (sender, args) => {
Console.WriteLine("Interrupted");
args.Cancel = true;
};
Thread.Sleep(5000);
Console.WriteLine("Ended");
}
} Inside the handler we'd need to call into the PHP subprocess - but how? |
Seems like Windows PHP would need to use SetConsoleCtrlHandler and not just cleanup and exit, but instead e.g. raise an exception. According to MSDN it's exeucted in a new thread - could that work or would it completely mess up PHP? |
See https://nomadphp.com/rfcs-future-tick-talk/ - for Unix systems w/ PCNTL, this will be easy and maybe the framework can take care of it. For Windows, we need a different solution - maybe based on ticks + IPC? |
For Cygwin, we'll need to wrap #!/bin/sh
_term() {
echo "Caught SIGINT signal!"
kill -TERM "$child" 2>/dev/null
}
trap _term SIGINT
/home/friebe/bin/xp "$@" &
child=$!
wait "$child" See https://unix.stackexchange.com/questions/146756/forward-sigterm-to-child-in-bash |
For Cygwin, using |
The wrapper above doesn't, actually only diff --git a/src/xp.runner/exec/ExecutionModel.cs b/src/xp.runner/exec/ExecutionModel.cs
index 6caa29a..82657d2 100755
--- a/src/xp.runner/exec/ExecutionModel.cs
+++ b/src/xp.runner/exec/ExecutionModel.cs
@@ -18,6 +18,13 @@ namespace Xp.Runners.Exec
/// <summary>Run the process and return its exitcode</summary>
protected int Run(Process proc, Encoding encoding, Func<int> wait = null)
{
+ Console.CancelKeyPress += (sender, args) => {
+ args.Cancel = true;
+
+ Console.WriteLine("Killing PHP");
+ proc.Kill();
+ };
+
using (new Output())
{
proc.StartInfo.RedirectStandardOutput = false;
@@ -29,11 +36,14 @@ namespace Xp.Runners.Exec
if (null == wait)
{
+ Console.WriteLine("WaitForExit");
proc.WaitForExit();
+ Console.WriteLine("Waited {0}", proc.ExitCode);
return proc.ExitCode;
}
else
{
+ Console.WriteLine("wait");
return wait();
}
} $ cat xp.sh
#!/bin/bash
./winpty ./xp.exe "$@"
# Without interrupting
$ sh xp.sh -e 'sleep(2)'
WaitForExit
Waited 0
# With ^C
$ sh xp.sh -e 'sleep(2)'
WaitForExit
Killing PHP
Waited -1073741510
$ echo $?
58 |
WinPTY can be obtained by downloading https://github.com/rprichard/winpty/releases |
<?php
$ffi= FFI::cdef('
typedef bool (close_handler)(int reason);
bool SetConsoleCtrlHandler(close_handler handler, bool add);
', 'kernel32.dll');
$f= function($reason) {
echo "Exiting with $reason...\n";
return false;
};
var_dump($ffi->SetConsoleCtrlHandler($f, true));
sleep(10); $ XP_RT=master winpty xp ffi.php
bool(true)
# Press Ctrl+C here
Exiting with 0... |
Using Windows Terminal (Preview): |
Can we make PHP handle Ctrl+C gracefully by intercepting it inside .NET? Something like installing a signal handler for SIGINT but platform independent.
See https://msdn.microsoft.com/en-us/library/system.console.cancelkeypress.aspx
The text was updated successfully, but these errors were encountered: