private static object DoBlock() { Signum[] quitSignals = new Signum[] { Signum.SIGABRT, //Signum.SIGBUS, Disabled because of mysterious MacOS behavior //Signum.SIGCHLD, Disabled because child processes stopping shouldn't kill the parent process Signum.SIGHUP, Signum.SIGILL, Signum.SIGINT, Signum.SIGQUIT, Signum.SIGTERM, Signum.SIGTSTP, Signum.SIGUSR1, Signum.SIGUSR2 }; List<UnixSignal> signals = new List<UnixSignal>(); foreach (Signum quitSignal in quitSignals) signals.Add(new UnixSignal(quitSignal)); // Wait for a signal to be delivered int index = UnixSignal.WaitAny(signals.ToArray(), -1); UnixSignal signal = signals[index]; return signal.Signum; }
public UnixSignal (Signum signum) { this.signum = NativeConvert.FromSignum (signum); this.signal_info = install (this.signum); if (this.signal_info == IntPtr.Zero) { throw new ArgumentException ("Unable to handle signal", "signum"); } }
public SignalWatcher(Context context, Signum signum, Action callback) : this(context, new Signum[] { signum }, (num) => { if (callback != null) { callback(); } }) { }
public static int FromSignum(Signum value) { int result; if (UnsafeNativeMethods.FromSignum(value, out result) == -1) { throw new ArgumentException("value " + value + " is not an acceptable signum"); } return result; }
public void Subscribe(Signum signal, Action handler) { List<Action> subscribers; if (!_subscriptions.TryGetValue(signal, out subscribers)) { subscribers = new List<Action>(); _subscriptions.Add(signal, subscribers); } subscribers.Add(handler); }
private void Handle(Signum signal) { List<Action> subscribers; if (_subscriptions.TryGetValue(signal, out subscribers)) { foreach (var subscriber in subscribers) { try { subscriber(); } catch { } } } }
public SignalWatcher(Context context, Signum[] signals, Action<Signum> callback) { Signals = signals; unixSignals = new UnixSignal[signals.Length]; for (int i = 0; i < signals.Length; i++) { unixSignals[i] = new UnixSignal(signals[i]); } watcher = new AsyncWatcher<Signum>(context, (key) => { if (callback != null) { callback(key); } }); thread = new Thread((o) => { while (true) { var index = UnixSignal.WaitAny(unixSignals); watcher.Send(Signals[index]); } }); }
public static bool TryToSignum (Int32 value, out Signum rval) { return ToSignum (value, out rval) == 0; }
public static Int32 FromSignum (Signum value) { Int32 rval; if (FromSignum (value, out rval) == -1) ThrowArgumentException (value); return rval; }
private static extern int FromSignum (Signum value, out Int32 rval);
public SingalEventArgs(Signum sig) { SigNum = sig; }
private static void OnSignal(Signum sig) { if (sig == Signum.SIGTERM || sig == Signum.SIGINT) { Stop (); } }
private static bool TryFromSignum(Signum value, out int rval) { return(FromSignum(value, out rval) == 0); }
private static bool TryFromSignum(Signum value, out int rval) { return FromSignum(value, out rval) == 0; }
private static int FromSignum(Signum value) { int rval; if (FromSignum(value, out rval) == -1) throw new ArgumentException(); return rval; }
private static extern int ToSignum(Int32 value, out Signum rval);
public static bool TryToSignum(Int32 value, out Signum rval) { return(ToSignum(value, out rval) == 0); }
public static bool TryFromSignum(Signum value, out Int32 rval) { return(FromSignum(value, out rval) == 0); }
public void TestSignumPropertyThrows() { UnixSignal signal1 = new UnixSignal(new RealTimeSignum(0)); Signum s = signal1.Signum; }
public static string strsignal (Signum sig) { int s = UnixConvert.FromSignum (sig); lock (signal_lock) { IntPtr r = sys_strsignal (s); return UnixMarshal.PtrToString (r); } }
static UnixSignal[] CreateSignals (Signum[] signals) { UnixSignal[] s = new UnixSignal [signals.Length]; for (int i = 0; i < signals.Length; ++i) s [i] = new UnixSignal (signals [i]); return s; }
private static int kill(int pid, Signum sig) { var _sig = FromSignum(sig); return sys_kill(pid, _sig); }
static void UnixSignalTrapper() { Signum[] quitSignals = new Signum[] { Signum.SIGABRT, //Signum.SIGBUS, Disabled because of mysterious MacOS behavior //Signum.SIGCHLD, Disabled because child processes stopping shouldn't kill the parent process Signum.SIGHUP, Signum.SIGILL, Signum.SIGINT, Signum.SIGQUIT, Signum.SIGTERM, Signum.SIGTSTP, Signum.SIGUSR1, Signum.SIGUSR2 }; List<UnixSignal> signals = new List<UnixSignal>(); foreach (Signum quitSignal in quitSignals) signals.Add(new UnixSignal(quitSignal)); // Wait for a signal to be delivered while (StayOpen) //Console.WriteLine(UnixSignal.WaitAny(signals.ToArray(), -1).ToString()); UnixSignal.WaitAny(signals.ToArray(), -1); Process.GetCurrentProcess().Kill(); }
public static int SendSignal(int pid, Signum sig) { switch (PlatformIdentifier) { case PlatformID.Unix: return kill(pid, sig); case PlatformID.Win32NT: switch (sig) { case Signum.SIGINT: return SendCtrlC(); default: throw new NotImplementedException(); } default: throw new NotImplementedException(); } }
public static int kill (int pid, Signum sig) { int _sig = UnixConvert.FromSignum (sig); return sys_kill (pid, _sig); }
/// <summary> /// The entry point of the program, where the program control starts and ends. /// </summary> /// <param name='args'> /// The command-line arguments. /// </param> private static void Main(string[] args) { try { Configuration.System.UpTime = DateTime.Now; Core.KernelThread = Thread.CurrentThread; Core.KernelThread.Name = "Kernel"; Configuration.System.Version += " [libirc v. " + libirc.Defs.Version.ToString() + "]"; Thread logger = new Thread(Logging.Exec) { Name = "Logger" }; Core.ThreadManager.RegisterThread(logger); ParseArgs(args); Syslog.WriteNow(Configuration.System.Version); Syslog.WriteNow("Loading..."); logger.Start(); Console.CancelKeyPress += SigInt; messages.LoadLD(); if (Configuration.Load() != 0) { Syslog.WriteNow("Error while loading the config file, exiting", true); Environment.Exit(-2); } Terminal.Init(); Core.Help.CreateHelp(); Core.WriterThread = new Thread(StorageWriter.Exec); Core.ThreadManager.RegisterThread(Core.WriterThread); Core.WriterThread.Name = "Writer"; Core.WriterThread.Start(); if (WMIBMySQL.IsAvailable) { Syslog.Log("Initializing MySQL"); Core.MysqlDB = new WMIBMySQL(); } else { Syslog.Log("Mysql is not configured, disabling it"); } if (PostgreSQL.IsAvailable) { Syslog.Log("Opening connection to PostgreDB"); Core.PostgreDB = new PostgreSQL(); Core.PostgreDB.Connect(); } else { Syslog.Log("Postgres is not configured, not using"); } // let's use postgre as default if (Core.PostgreDB != null) { Syslog.Log("Using Postgres as a default SQL provider"); Core.DB = Core.PostgreDB; } else if (Core.MysqlDB != null) { Syslog.Log("Using MySQL as a default SQL"); Core.DB = Core.MysqlDB; } // register all commands Commands.InitAdminCommands(); Syslog.Log("Loading modules"); ExtensionHandler.SearchMods(); Security.Init(); Security.Global(); Syslog.Log("Connecting"); IRC.Connect(); #if __MonoCS__ UnixSignal[] signals = { new UnixSignal(Signum.SIGINT), new UnixSignal(Signum.SIGTERM), new UnixSignal(Signum.SIGQUIT), new UnixSignal(Signum.SIGHUP) }; #endif while (Core.IsRunning) { #if __MonoCS__ int index = UnixSignal.WaitAny(signals, -1); Signum signal = signals [index].Signum; switch (signal) { case Signum.SIGINT: SigInt(null, null); goto exit; case Signum.SIGTERM: Syslog.WriteNow("SIGTERM - Shutting down", true); Core.Kill(); goto exit; } #endif Thread.Sleep(200); } #if __MonoCS__ exit: #endif // memory cleanup if (Core.DB != null) { ((WMIBMySQL)Core.DB).Dispose(); } } catch (Exception fatal) { Syslog.WriteNow("bot crashed, bellow is debugging information", Syslog.Type.Error); Console.WriteLine("------------------------------------------------------------------------"); Console.WriteLine("Description: " + fatal.Message); Console.WriteLine("Stack trace: " + fatal.StackTrace); Environment.Exit(-2); } }
private static int kill(int pid, Signum sig) { var _sig = FromSignum(sig); return(sys_kill(pid, _sig)); }
public static void Main(string[] args) { #if !__MonoCS__ handler = new ConsoleEventDelegate(ConsoleEventCallback); SetConsoleCtrlHandler(handler, true); #else // http://stackoverflow.com/questions/6546509/detect-when-console-application-is-closing-killed var signums = new Signum [] { Signum.SIGABRT, Signum.SIGINT, Signum.SIGKILL, Signum.SIGQUIT, Signum.SIGTERM, Signum.SIGSTOP, Signum.SIGTSTP }; List<UnixSignal> signals = new List<UnixSignal>(); foreach (var signum in signums) { try { signals.Add(new UnixSignal(signum)); } catch(Exception) {} } new Thread (delegate () { // Wait for a signal to be delivered UnixSignal.WaitAny(signals.ToArray(), -1); app.Shutdown("UnixSignal"); }).Start(); #endif if (string.IsNullOrWhiteSpace(Settings.Default.TempPath)) { Settings.Default.TempPath = Settings.Default.GetAppDataPath() + "tmp"; } if (!Settings.Default.TempPath.EndsWith("" + Path.DirectorySeparatorChar)) { Settings.Default.TempPath += Path.DirectorySeparatorChar; } new DirectoryInfo(Settings.Default.TempPath).Create(); if (string.IsNullOrWhiteSpace(Settings.Default.ReadyPath)) { Settings.Default.ReadyPath = Settings.Default.GetAppDataPath() + "dl"; } if (!Settings.Default.ReadyPath.EndsWith("" + Path.DirectorySeparatorChar)) { Settings.Default.ReadyPath += Path.DirectorySeparatorChar; } new DirectoryInfo(Settings.Default.ReadyPath).Create(); Settings.Default.Save(); if (File.Exists(Settings.Default.GetAppDataPath() + "log4net.xml")) { // load settings from file XmlConfigurator.Configure(new FileInfo(Settings.Default.GetAppDataPath() + "log4net.xml")); } else { // build our own, who logs only fatals to console Logger root = ((Hierarchy)LogManager.GetRepository()).Root; var lAppender = new ConsoleAppender { Name = "Console", Layout = new PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %line:%logger.%message%n"), #if DEBUG Threshold = Level.Info #else Threshold = Level.Fatal #endif }; lAppender.ActivateOptions(); root.AddAppender(lAppender); root.Repository.Configured = true; } #if __MonoCS__ PlatformID id = Environment.OSVersion.Platform; // Don't allow running as root on Linux or Mac try { if ((id == PlatformID.Unix || id == PlatformID.MacOSX) && new UnixUserInfo(UnixEnvironment.UserName).UserId == 0) { LogManager.GetLogger(typeof(Programm)).Fatal("Sorry, you can't run XG with these permissions. Safety first!"); Environment.Exit(-1); } } catch (ArgumentException) { // arch linux fix // https://github.com/lformella/xdcc-grabscher/issues/36 } #endif app = new App(); app.AddPlugin(new Plugin.Irc.Plugin()); if (Settings.Default.UseJabberClient) { app.AddPlugin(new Plugin.Jabber.Plugin()); } if (Settings.Default.UseElasticSearch) { app.AddPlugin(new Plugin.ElasticSearch.Plugin()); } if (Settings.Default.UseWebserver) { var webServer = new Plugin.Webserver.Plugin { RrdDB = app.RrdDb }; webServer.OnShutdown += delegate { app.Shutdown(webServer); }; app.AddPlugin(webServer); } app.OnShutdownComplete += delegate { Environment.Exit(0); }; app.Start(typeof(App).ToString()); } #endregion Methods }
public void Signal(Signum signal) { UnixMarshal.ThrowExceptionForLastErrorIf(Syscall.kill(this.pid, signal)); }
private void runLinux(Control control) { this.mainControl = control; if (userCanvasSize.IsEmpty) { // Create physical canvas with actual terminal size winsize ws = Libc.GetTerminalSize(isDarwin); canvas = new PhysicalCanvas(ws.ws_col, ws.ws_row); } else { canvas = new PhysicalCanvas(userCanvasSize.Width, userCanvasSize.Height); } renderer.Canvas = canvas; renderer.RootElementRect = userRootElementRect.IsEmpty ? new Rect(canvas.Size) : userRootElementRect; renderer.RootElement = mainControl; // mainControl.Invalidate(); // Terminal initialization sequence // This is magic workaround to avoid messing up terminal after program finish // The bug is described at https://bugzilla.xamarin.com/show_bug.cgi?id=15118 bool ignored = Console.KeyAvailable; IntPtr stdscr = NCurses.initscr(); NCurses.cbreak(); NCurses.noecho(); NCurses.nonl(); NCurses.intrflush(stdscr, false); NCurses.keypad(stdscr, true); NCurses.start_color(); HideCursor(); try { renderer.UpdateLayout( ); renderer.FinallyApplyChangesToCanvas( ); termkeyHandle = LibTermKey.termkey_new(0, TermKeyFlag.TERMKEY_FLAG_SPACESYMBOL); // Setup the input mode Console.Write("\x1B[?1002h"); pollfd fd = new pollfd( ); fd.fd = 0; fd.events = POLL_EVENTS.POLLIN; pollfd[] fds = new pollfd[2]; fds[0] = fd; fds[1] = new pollfd( ); int pipeResult = Libc.pipe(pipeFds); if (pipeResult == -1) { throw new InvalidOperationException("Cannot create self-pipe."); } fds[1].fd = pipeFds[0]; fds[1].events = POLL_EVENTS.POLLIN; try { #if !WIN32 // Catch SIGWINCH to handle terminal resizing UnixSignal[] signals = new UnixSignal [] { new UnixSignal(Signum.SIGWINCH) }; Thread signal_thread = new Thread(delegate() { while (true) { // Wait for a signal to be delivered int index = UnixSignal.WaitAny(signals, -1); Signum signal = signals [index].Signum; Libc.writeInt64(pipeFds[1], 2); } } ); signal_thread.IsBackground = false; signal_thread.Start(); #endif TermKeyKey key = new TermKeyKey( ); // this.running = true; this.mainThreadId = Thread.CurrentThread.ManagedThreadId; // int nextwait = -1; while (true) { int pollRes = Libc.poll(fds, 2, nextwait); if (pollRes == 0) { if (nextwait == -1) { throw new InvalidOperationException("Assertion failed."); } if (TermKeyResult.TERMKEY_RES_KEY == LibTermKey.termkey_getkey_force(termkeyHandle, ref key)) { processLinuxInput(key); } } if (pollRes == -1) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != Libc.EINTR) { throw new InvalidOperationException(string.Format("poll() returned with error code {0}", errorCode)); } } if (fds[1].revents != POLL_EVENTS.NONE) { UInt64 u; Libc.readInt64(fds[1].fd, out u); if (u == 1) { // Exit from application #if !WIN32 signal_thread.Abort(); #endif break; } if (u == 2) { // Get new term size and process appropriate INPUT_RECORD event INPUT_RECORD inputRecord = new INPUT_RECORD( ); inputRecord.EventType = EventType.WINDOW_BUFFER_SIZE_EVENT; winsize ws = Libc.GetTerminalSize(isDarwin); inputRecord.WindowBufferSizeEvent.dwSize.X = ( short )ws.ws_col; inputRecord.WindowBufferSizeEvent.dwSize.Y = ( short )ws.ws_row; processInputEvent(inputRecord); } if (u == 3) { // It is signal from async actions invocation stuff } } if ((fds[0].revents & POLL_EVENTS.POLLIN) == POLL_EVENTS.POLLIN || (fds[0].revents & POLL_EVENTS.POLLHUP) == POLL_EVENTS.POLLHUP || (fds[0].revents & POLL_EVENTS.POLLERR) == POLL_EVENTS.POLLERR) { LibTermKey.termkey_advisereadable(termkeyHandle); } TermKeyResult result = (LibTermKey.termkey_getkey(termkeyHandle, ref key)); while (result == TermKeyResult.TERMKEY_RES_KEY) { processLinuxInput(key); result = (LibTermKey.termkey_getkey(termkeyHandle, ref key)); } if (result == TermKeyResult.TERMKEY_RES_AGAIN) { nextwait = LibTermKey.termkey_get_waittime(termkeyHandle); } else { nextwait = -1; } while (true) { bool anyInvokeActions = isAnyInvokeActions( ); bool anyRoutedEvent = !EventManager.IsQueueEmpty( ); bool anyLayoutToRevalidate = renderer.AnyControlInvalidated; if (!anyInvokeActions && !anyRoutedEvent && !anyLayoutToRevalidate) { break; } EventManager.ProcessEvents(); processInvokeActions( ); renderer.UpdateLayout( ); } renderer.FinallyApplyChangesToCanvas( ); } } finally { LibTermKey.termkey_destroy(termkeyHandle); Libc.close(pipeFds[0]); Libc.close(pipeFds[1]); Console.Write("\x1B[?1002l"); } } finally { // Restore cursor visibility before exit ShowCursor( ); NCurses.endwin( ); } renderer.RootElement = null; }
private static extern int FromSignum(Signum value, out int rval);
public void Signal (Signum signal) { int r = Syscall.kill (pid, signal); UnixMarshal.ThrowExceptionForLastErrorIf (r); }
public static bool TryFromSignum (Signum value, out Int32 rval) { return FromSignum (value, out rval) == 0; }
public static int SetSignalAction(Signum signal, SignalAction action) { return(SetSignalAction(NativeConvert.FromSignum(signal), action)); }
private static extern int ToSignum (Int32 value, out Signum rval);
public static void RegisterHandler(Signum signal, SignalHandler handler) { handlers[signal] = handler; SigActionData data = new SigActionData (new SignalHandler (InternalHandler)); sigaction ((int) signal, ref data, IntPtr.Zero); }
public static int raise (Signum sig) { int _sig = UnixConvert.FromSignum (sig); return sys_raise (_sig); }
public void Kill(Signum signum) { Kill((int)signum); }
public static SignalHandler signal (Signum signum, SignalHandler handler) { int _sig = UnixConvert.FromSignum (signum); IntPtr r; if (handler == SIG_DFL) r = sys_signal (_sig, _SIG_DFL); else if (handler == SIG_ERR) r = sys_signal (_sig, _SIG_ERR); else if (handler == SIG_IGN) r = sys_signal (_sig, _SIG_IGN); else r = sys_signal (_sig, handler); return TranslateHandler (r); }
private static int FromSignum (Signum value, out Int32 rval) { throw new System.NotImplementedException(); }
private static int ToSignum (Int32 value, out Signum rval) { throw new System.NotImplementedException(); }
public static int raise(Signum sig) { return(sys_raise(NativeConvert.FromSignum(sig))); }
public static void psignal (Signum sig, string s) { int signum = UnixConvert.FromSignum (sig); psignal (signum, s); }