001/* 002 * SPDX-License-Identifier: Apache-2.0 003 * 004 * Copyright 2025-2026 The Enola <https://enola.dev> Authors 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package dev.enola.common.exec.pty; 019 020import static java.util.Objects.requireNonNull; 021 022import org.jline.terminal.Size; 023import org.jline.terminal.Terminal; 024import org.jline.terminal.TerminalBuilder; 025 026import java.io.IOException; 027import java.nio.file.Path; 028 029public class Demo { 030 031 // FTR https://github.com/JetBrains/pty4j/issues/170 032 033 public static void main(String[] args) throws IOException, InterruptedException { 034 try (Terminal terminal = TerminalBuilder.builder().build()) { 035 terminal.enterRawMode(); 036 // NB: terminal.echo() true or false makes no difference (because we're in raw mode) 037 038 int result; 039 // TODO Read from $SHELL (and use cmd.exe on Windows) 040 String[] cmd = {"/usr/bin/fish", "-li"}; 041 System.out.println("Starting: " + String.join(" ", cmd)); 042 try (var runner = 043 new PtyRunner( 044 true, 045 Path.of("."), 046 cmd, 047 System.getenv(), 048 requireNonNull(terminal.input(), "terminal.input"), 049 requireNonNull(terminal.output(), "terminal.output"), 050 null, 051 true)) { 052 resize(terminal, runner); 053 terminal.handle(Terminal.Signal.WINCH, signal -> resize(terminal, runner)); 054 result = runner.waitForExit(); 055 } 056 System.out.println("PTY demo exits!"); 057 System.exit(result); 058 } 059 } 060 061 private static void resize(Terminal terminal, PtyRunner runner) { 062 Size size = terminal.getSize(); 063 var cols = size.getColumns(); 064 var rows = size.getRows(); 065 if (cols > 0 && rows > 0) runner.size(cols, rows); 066 // Do NOT "terminal.writer().flush()" - when exec, this destroys the child process updates! 067 } 068}