Browse Source

Add suspend support

Miguel de Icaza 7 years ago
parent
commit
0269b0e9b7
2 changed files with 73 additions and 3 deletions
  1. 2 3
      Core.cs
  2. 71 0
      Driver.cs

+ 2 - 3
Core.cs

@@ -716,9 +716,8 @@ namespace Terminal {
 				// TODO: stop current execution of this container
 				// TODO: stop current execution of this container
 				break;
 				break;
 			case Key.ControlZ:
 			case Key.ControlZ:
-				// TODO: should suspend
-				// console_csharp_send_sigtstp ();
-				break;
+				Driver.Suspend ();
+				return true;
 
 
 #if false
 #if false
 			case Key.F5:
 			case Key.F5:

+ 71 - 0
Driver.cs

@@ -6,6 +6,7 @@
 //
 //
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Runtime.InteropServices;
 using Mono.Terminal;
 using Mono.Terminal;
 using Unix.Terminal;
 using Unix.Terminal;
 
 
@@ -94,6 +95,8 @@ namespace Terminal {
 		public abstract void DrawFrame (Rect region, bool fill);
 		public abstract void DrawFrame (Rect region, bool fill);
 		public abstract void AddSpecial (SpecialChar ch);
 		public abstract void AddSpecial (SpecialChar ch);
 
 
+		public abstract void Suspend ();
+
 		Rect clip;
 		Rect clip;
 		public Rect Clip {
 		public Rect Clip {
 			get => clip;
 			get => clip;
@@ -390,5 +393,73 @@ namespace Terminal {
 				Colors.Error.HotFocus = Curses.A_REVERSE;
 				Colors.Error.HotFocus = Curses.A_REVERSE;
 			}
 			}
 		}
 		}
+
+		public override void Suspend ()
+		{
+			Platform.Suspend ();
+			Curses.Window.Standard.redrawwin ();
+			Curses.refresh ();
+		}
+	}
+
+	internal static class Platform {
+		[DllImport ("libc")]
+		static extern int uname (IntPtr buf);
+
+		[DllImport ("libc")]
+		static extern int killpg (int pgrp, int pid);
+
+		static int suspendSignal;
+
+		static int GetSuspendSignal ()
+		{
+			if (suspendSignal != 0)
+				return suspendSignal;
+			
+			IntPtr buf = Marshal.AllocHGlobal (8192);
+			if (uname (buf) != 0) {
+				Marshal.FreeHGlobal (buf);
+				suspendSignal = -1;
+				return suspendSignal;
+			}
+			try {
+				switch (Marshal.PtrToStringAnsi (buf)) {
+				case "Darwin":
+				case "DragonFly":
+				case "FreeBSD":
+				case "NetBSD":
+				case "OpenBSD":
+					suspendSignal = 18;
+					break;
+				case "Linux":
+					// TODO: should fetch the machine name and 
+					// if it is MIPS return 24
+					suspendSignal = 20;
+					break;
+				case "Solaris":
+					suspendSignal = 24;
+					break;
+				default:
+					suspendSignal = -1;
+					break;
+				}
+				return suspendSignal;
+			} finally {
+				Marshal.FreeHGlobal (buf);
+			}
+		}
+
+		/// <summary>
+		/// Suspends the process by sending SIGTSTP to itself
+		/// </summary>
+		/// <returns>The suspend.</returns>
+		static public bool Suspend ()
+		{
+			int signal = GetSuspendSignal ();
+			if (signal == -1)
+				return false;
+			killpg (0, signal);
+			return true;
+		}
 	}
 	}
 }
 }