daily pastebin goal
57%
SHARE
TWEET

Untitled

a guest Feb 14th, 2018 58 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Runtime.InteropServices;
  3.  
  4. namespace Microsoft.PowerShell.Internal
  5. {
  6.     internal class PlatformUnix
  7.     {
  8.         // termios
  9.         private const int STDIN_FILENO = 0; // File descriptor for Standard Input.
  10.         private const int NCCS = 64; // Size of the array c_cc for control characters.
  11.  
  12.         // Control Characters (c_cc)
  13.         private const uint VTIME = 5; // Timeout in deciseconds.
  14.         private const uint VMIN = 6; // Minimum number of characters to expect.
  15.  
  16.         // Local Modes (c_lflag)
  17.         private const uint ICANON = 0000002; // Canonical input (erase and kill processing).
  18.         private const uint ECHO = 0000010; // Enable echo.
  19.         private const uint IEXTEN = 0100000; // Enable extended input character processing.
  20.  
  21.         // Input Modes (c_iflag)
  22.         private const uint IXON = 0002000; // Enable start/stop output control.
  23.         private const uint IXOFF = 0010000; // Enable start/stop input control.
  24.  
  25.         // Attribute Selection (tcsetattr)
  26.         private const int TCSANOW = 0; // Change attributes immediately.
  27.  
  28.         // Poll Events
  29.         private const ushort POLLIN = 0x0001; // Standard Input is ready.
  30.  
  31.         internal static ConsoleKeyInfo ReadKey()
  32.         {
  33.             BlockUntilKeyAvailable();
  34.             return Console.ReadKey(intercept: true);
  35.         }
  36.  
  37.         [DllImport("libc")]
  38.         private static extern uint tcgetattr(int fd, IntPtr termios_p);
  39.  
  40.         [DllImport("libc")]
  41.         private static extern uint tcsetattr(int fd, int optional_actions, IntPtr termios_p);
  42.  
  43.         [DllImport("libc")]
  44.         private static extern uint poll(ref pollfd fds, uint nfds, int timeout);
  45.  
  46.         private static void BlockUntilKeyAvailable()
  47.         {
  48.             pollfd fds;
  49.             fds.fd = STDIN_FILENO;
  50.             fds.events = POLLIN;
  51.             fds.revents = 0;
  52.  
  53.             termios newTerminal = GetTerminal();
  54.             termios previousTerminal = newTerminal;
  55.             newTerminal.c_iflag &= ~(IXON | IXOFF);
  56.             newTerminal.c_lflag &= ~(ECHO | ICANON | IEXTEN);
  57.             newTerminal.c_cc[VMIN] = 1;
  58.             newTerminal.c_cc[VTIME] = 0;
  59.             SetTerminal(newTerminal);
  60.             try
  61.             {
  62.                 poll(ref fds, 1, -1);
  63.             }
  64.             finally
  65.             {
  66.                 SetTerminal(previousTerminal);
  67.             }
  68.         }
  69.  
  70.         private static termios GetTerminal()
  71.         {
  72.             IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(termios)));
  73.             try
  74.             {
  75.                 if (tcgetattr(STDIN_FILENO, ptr) >= 0)
  76.                 {
  77.                     return Marshal.PtrToStructure<termios>(ptr);
  78.                 }
  79.  
  80.                 return default(termios);
  81.             }
  82.             finally
  83.             {
  84.                 Marshal.FreeHGlobal(ptr);
  85.             }
  86.         }
  87.  
  88.         private static bool SetTerminal(termios termios)
  89.         {
  90.             IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(termios)));
  91.             try
  92.             {
  93.                 Marshal.StructureToPtr<termios>(termios, ptr, fDeleteOld: false);
  94.                 if (tcsetattr(STDIN_FILENO, TCSANOW, ptr) <= 0)
  95.                 {
  96.                     return true;
  97.                 }
  98.  
  99.                 return false;
  100.             }
  101.             finally
  102.             {
  103.                 Marshal.FreeHGlobal(ptr);
  104.             }
  105.         }
  106.  
  107.         [StructLayout(LayoutKind.Sequential)]
  108.         private struct termios
  109.         {
  110.             // Input Mode Flags
  111.             internal uint c_iflag;
  112.  
  113.             // Output Mode Flags
  114.             internal uint c_oflag;
  115.  
  116.             // Control Mode Flags
  117.             internal uint c_cflag;
  118.  
  119.             // Local Mode Flags
  120.             internal uint c_lflag;
  121.  
  122.             internal byte c_line;
  123.  
  124.             /// Control Characters
  125.             [MarshalAs(UnmanagedType.ByValArray, SizeConst=NCCS)]
  126.             internal byte[] c_cc;
  127.         }
  128.  
  129.         [StructLayout(LayoutKind.Sequential)]
  130.         private struct pollfd
  131.         {
  132.             internal uint fd;
  133.  
  134.             internal ushort events;
  135.  
  136.             internal ushort revents;
  137.         }
  138.     }
  139. }
RAW Paste Data
Top