コード例 #1
0
            public TtyContext(ITrace trace, int fd, bool echo)
            {
                EnsureArgument.NotNull(trace, nameof(trace));
                EnsureArgument.PositiveOrZero(fd, nameof(fd));

                _trace = trace;
                _fd    = fd;

                int error = 0;

                // Capture current terminal settings so we can restore them later
                if ((error = Termios.tcgetattr(_fd, out termios t)) != 0)
                {
                    throw new InteropException("Failed to get initial terminal settings", error);
                }

                _originalTerm = t;

                // Set desired echo state
                _trace.WriteLine($"Setting terminal echo state to '{echo}'");
                t.c_lflag &= echo
                    ? LocalFlags.ECHO
                    : ~LocalFlags.ECHO;

                if ((error = Termios.tcsetattr(_fd, SetActionFlags.TCSAFLUSH, ref t)) != 0)
                {
                    throw new InteropException("Failed to set terminal settings", error);
                }
            }
コード例 #2
0
        /// <inheritdoc/>
        public override Task <IPtyConnection> StartTerminalAsync(PtyOptions options, TraceSource trace, CancellationToken cancellationToken)
        {
            var winSize = new WinSize((ushort)options.Rows, (ushort)options.Cols);

            string?[] terminalArgs = GetExecvpArgs(options);

            var controlCharacters = new Dictionary <TermSpecialControlCharacter, sbyte>
            {
                { TermSpecialControlCharacter.VEOF, 4 },
                { TermSpecialControlCharacter.VEOL, -1 },
                { TermSpecialControlCharacter.VEOL2, -1 },
                { TermSpecialControlCharacter.VERASE, 0x7f },
                { TermSpecialControlCharacter.VWERASE, 23 },
                { TermSpecialControlCharacter.VKILL, 21 },
                { TermSpecialControlCharacter.VREPRINT, 18 },
                { TermSpecialControlCharacter.VINTR, 3 },
                { TermSpecialControlCharacter.VQUIT, 0x1c },
                { TermSpecialControlCharacter.VSUSP, 26 },
                { TermSpecialControlCharacter.VSTART, 17 },
                { TermSpecialControlCharacter.VSTOP, 19 },
                { TermSpecialControlCharacter.VLNEXT, 22 },
                { TermSpecialControlCharacter.VDISCARD, 15 },
                { TermSpecialControlCharacter.VMIN, 1 },
                { TermSpecialControlCharacter.VTIME, 0 },
                { TermSpecialControlCharacter.VDSUSP, 25 },
                { TermSpecialControlCharacter.VSTATUS, 20 },
            };

            var term = new Termios(
                inputFlag: TermInputFlag.ICRNL | TermInputFlag.IXON | TermInputFlag.IXANY | TermInputFlag.IMAXBEL | TermInputFlag.BRKINT | TermInputFlag.IUTF8,
                outputFlag: TermOuptutFlag.OPOST | TermOuptutFlag.ONLCR,
                controlFlag: TermConrolFlag.CREAD | TermConrolFlag.CS8 | TermConrolFlag.HUPCL,
                localFlag: TermLocalFlag.ICANON | TermLocalFlag.ISIG | TermLocalFlag.IEXTEN | TermLocalFlag.ECHO | TermLocalFlag.ECHOE | TermLocalFlag.ECHOK | TermLocalFlag.ECHOKE | TermLocalFlag.ECHOCTL,
                speed: TermSpeed.B38400,
                controlCharacters: controlCharacters);

            int controller = 0;
            int pid        = forkpty(ref controller, null, ref term, ref winSize);

            if (pid == -1)
            {
                throw new InvalidOperationException($"forkpty(4) failed with error {Marshal.GetLastWin32Error()}");
            }

            if (pid == 0)
            {
                // We are in a forked process! See http://man7.org/linux/man-pages/man2/fork.2.html for details.
                // Only our thread is running. We inherited open file descriptors and get a copy of the parent process memory.
                Environment.CurrentDirectory = options.Cwd;
                execvpe(options.App, terminalArgs, options.Environment);

                // Unreachable code after execvpe()
            }

            // We have forked the terminal
            return(Task.FromResult <IPtyConnection>(new PtyConnection(controller, pid)));
        }
コード例 #3
0
            public void Dispose()
            {
                if (_isDisposed)
                {
                    return;
                }

                int error = 0;

                // Restore original terminal settings
                if ((error = Termios.tcsetattr(_fd, SetActionFlags.TCSAFLUSH, ref _originalTerm)) != 0)
                {
                    _trace.WriteLine($"Failed to get restore terminal settings (error: {error:x}");
                }

                _isDisposed = true;
            }
コード例 #4
0
 internal static extern int forkpty(ref int master, StringBuilder?name, ref Termios termp, ref WinSize winsize);
コード例 #5
0
 internal static extern int cfsetospeed(ref Termios termios, IntPtr speed);
コード例 #6
0
 public static void BlitIntPtrToTermios(IntPtr intPtr, ref Termios termios)
 {
     unsafe {
         termios = ((Termios *)intPtr.ToPointer())[0];
     }
 }
コード例 #7
0
 public static void BlitTermiosToIntPtr(Termios termios, IntPtr intPtr)
 {
     unsafe {
         ((Termios *)intPtr.ToPointer())[0] = termios;
     }
 }