public override int WaitForExitAndForward() { Mono.Unix.Native.Signum[] exitedSignals = null; using (var sigint = new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGINT)) using (var sigchld = new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGCHLD)) using (var sigterm = new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM)) { var sigs = new[] { sigint, sigterm, sigchld }; Mono.Unix.UnixSignal.WaitAny(sigs); exitedSignals = sigs.Where(s => s.IsSet).Select(s => s.Signum).ToArray(); } var childKill = exitedSignals.Contains(Mono.Unix.Native.Signum.SIGCHLD); if (ChildProcess != null) { if (!childKill) { foreach (var signal in exitedSignals) { Mono.Unix.Native.Syscall.kill(ChildProcess.Id, signal); } } Mono.Unix.Native.Syscall.waitpid(ChildProcess.Id, out int status, 0); if (childKill) { return(Mono.Unix.Native.Syscall.WEXITSTATUS(status)); } } return(0); }
private void SignalThread() { d_unixSignal = new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGINT); d_unixSignal.WaitOne(); if (!d_quitting) { d_quitting = true; d_waitHandle.Set(); } }
private static void SetupTerminationCatchers(Executor executor) { // Catch CTRL+C bool hitCancelOnce = false; Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs eventArgs) { if (hitCancelOnce) { Console.WriteLine("CTRL+C pressed again. Giving up and just exiting"); eventArgs.Cancel = false; // Force exit ExitWith(ExitCode.CTRL_C_FORCED_EXIT); } else { hitCancelOnce = true; Console.WriteLine("Received CTRL+C. Attempting to terminated Executor"); executor.Terminate(/*block=*/ false); eventArgs.Cancel = true; // Don't exit yet } }; // Sending SIGINT to the driver when stdout/stderr is not attached to a TTY does not seem to // trigger the Coinsole.CancelKeyPress event. So here we use a HACK to catch the signals we // care about and ask the Executor to terminate var signals = new Mono.Unix.UnixSignal[] { new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM), // boogie-runner sends this }; bool signalCaught = false; Task.Factory.StartNew(() => { while (true) { Console.WriteLine("Waiting for UNIX signals"); Mono.Unix.UnixSignal.WaitAny(signals); Console.WriteLine("Caught UNIX signal"); if (signalCaught) { Console.WriteLine("Signal received again. Just exiting"); ExitWith(ExitCode.CTRL_C_FORCED_EXIT); } else { executor.Terminate(false); signalCaught = true; } } }); }
private static void CheckSignal() { Mono.Unix.UnixSignal[] signals = new Mono.Unix.UnixSignal[] { new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGINT) }; int index = Mono.Unix.UnixSignal.WaitAny(signals); Mono.Unix.Native.Signum signum = signals[index].Signum; if (signum == Mono.Unix.Native.Signum.SIGINT) { if (service != null) { service.Dispose(); service = null; } } }
private static Task SignalHandler(System.Threading.CancellationToken token, Func <bool> reload, Func <bool> stop) { if (!SystemHelper.IsCurrentOSPosix) { return(Task.FromResult(true)); } var signals = new Mono.Unix.UnixSignal[] { new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGHUP), new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGINT), new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGQUIT), }; var lastctrlc = DateTime.Now.AddHours(-1); return(Task.Run(() => { while (!token.IsCancellationRequested) { var sig = Mono.Unix.UnixSignal.WaitAny(signals, TimeSpan.FromSeconds(5)); if (sig == 0) { ConsoleOutput("Got SIGHUP, sending reload request to server"); reload(); } else if (sig == 1) { var timesincelast = (DateTime.Now - lastctrlc).TotalSeconds; lastctrlc = DateTime.Now; if (timesincelast > 5) { ConsoleOutput("Got CTRL+C, sending reload request, press CTRL+C again within 5 seconds to send stop signal"); reload(); } else { ConsoleOutput("Got CTRL+C twice, sending stop signal"); stop(); } } else if (sig == 2) { ConsoleOutput("Got SIGQUIT, sending stop signal to server"); stop(); } } })); //var asm = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName("Mono.Posix, Culture=neutral, PublicKeyToken=0738eb9f132ed756")); //var unixsignal_t = Type.GetType("Mono.Unix.UnixSignal, Mono.Posix"); //var unixsignum_t = Type.GetType("Mono.Unix.Native.Signum, Mono.Posix"); //if (unixsignal_t == null || unixsignum_t == null) // return Task.FromResult(true); //var sighup = unixsignum_t // .GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public) // .Where(x => x.Name == "SIGHUP") // .Select(x => x.GetValue(null)) // .First(); //var sigint = unixsignum_t // .GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public) // .Where(x => x.Name == "SIGINT") // .Select(x => x.GetValue(null)) // .First(); //var sigquit = unixsignum_t // .GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public) // .Where(x => x.Name == "SIGQUIT") // .Select(x => x.GetValue(null)) // .First(); //var sighup_int = 0; //var sigint_int = 1; //var sigquit_int = 2; //var sigarray = Array.CreateInstance(unixsignal_t, 3); //sigarray.SetValue(Activator.CreateInstance(unixsignal_t, sighup), sighup_int); //sigarray.SetValue(Activator.CreateInstance(unixsignal_t, sigint), sigint_int); //sigarray.SetValue(Activator.CreateInstance(unixsignal_t, sigquit), sigquit_int); //var method = unixsignal_t.GetMethod( // "WaitAny", // System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, // null, // new Type[] { sigarray.GetType(), typeof(TimeSpan) }, // null //); //if (method == null) // return Task.FromResult(true); //var args = new object[] { sigarray, TimeSpan.FromSeconds(5) }; //return Task.Run(() => { // while (!token.IsCancellationRequested) // { // var sig = (int)method.Invoke(null, args); // if (sig == sighup_int || sig == sigint_int) // reload(); // else if (sig == sigquit_int) // stop(); // } //}); }