--- /dev/null +++ b/src/jdk.internal.le/solaris/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java 2023-06-02 10:45:50.331153527 +0100 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.org.jline.terminal.impl.jna; + +import java.io.IOException; +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.impl.jna.solaris.SolarisNativePty; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; + +class JDKNativePty { + + static JnaNativePty current(TerminalProvider.Stream console) throws IOException { + return SolarisNativePty.current(console); + } + + static JnaNativePty open(Attributes attr, Size size) throws IOException { + return SolarisNativePty.open(attr, size); + } + + static int isatty(int fd) { + return SolarisNativePty.isatty(fd); + } + + static String ttyname(int fd) { + return SolarisNativePty.ttyname(fd); + } + +} --- /dev/null +++ b/src/jdk.internal.le/solaris/classes/jdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary.java 2023-06-02 10:47:56.181885176 +0100 @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2002-2020, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.jna.solaris; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; + +//import com.sun.jna.LastErrorException; +//import com.sun.jna.Structure; +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Attributes.ControlChar; +import jdk.internal.org.jline.terminal.Attributes.ControlFlag; +import jdk.internal.org.jline.terminal.Attributes.InputFlag; +import jdk.internal.org.jline.terminal.Attributes.LocalFlag; +import jdk.internal.org.jline.terminal.Attributes.OutputFlag; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; + +public interface CLibrary {//extends com.sun.jna.Library { + + void tcgetattr(int fd, termios termios) throws LastErrorException; + + void tcsetattr(int fd, int cmd, termios termios) throws LastErrorException; + + void ioctl(int fd, long cmd, winsize data) throws LastErrorException; + + int isatty(int fd); + + void ttyname_r(int fd, byte[] buf, int len) throws LastErrorException; + + void openpty(int[] master, int[] slave, byte[] name, termios t, winsize s) throws LastErrorException; + + class winsize { //extends Structure { + public short ws_row; + public short ws_col; + public short ws_xpixel; + public short ws_ypixel; + + public winsize() { + } + + public winsize(Size ws) { + ws_row = (short) ws.getRows(); + ws_col = (short) ws.getColumns(); + } + + public Size toSize() { + return new Size(ws_col, ws_row); + } + +// @Override +// protected List getFieldOrder() { +// return Arrays.asList( // +// "ws_row", // +// "ws_col", // +// "ws_xpixel", // +// "ws_ypixel" // +// ); +// } + } + + class termios {//extends Structure { + + public int c_iflag; + public int c_oflag; + public int c_cflag; + public int c_lflag; + public byte[] c_cc = new byte[32]; + +// @Override +// protected List getFieldOrder() { +// return Arrays.asList( // +// "c_iflag", // +// "c_oflag", // +// "c_cflag", // +// "c_lflag", // +// "c_cc" // +// ); +// } + + public termios() { + } + + public termios(Attributes t) { + // Input flags + c_iflag = setFlag(t.getInputFlag(InputFlag.IGNBRK), IGNBRK, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.BRKINT), BRKINT, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.IGNPAR), IGNPAR, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.PARMRK), PARMRK, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.INPCK), INPCK, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.ISTRIP), ISTRIP, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.INLCR), INLCR, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.IGNCR), IGNCR, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.ICRNL), ICRNL, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.IXON), IXON, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.IXOFF), IXOFF, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.IXANY), IXANY, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.IMAXBEL), IMAXBEL, c_iflag); + c_iflag = setFlag(t.getInputFlag(InputFlag.IUTF8), IUTF8, c_iflag); + // Output flags + c_oflag = setFlag(t.getOutputFlag(OutputFlag.OPOST), OPOST, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONLCR), ONLCR, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.OCRNL), OCRNL, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONOCR), ONOCR, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONLRET), ONLRET, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.OFILL), OFILL, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.NLDLY), NLDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.TABDLY), TABDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.CRDLY), CRDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.FFDLY), FFDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.BSDLY), BSDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.VTDLY), VTDLY, c_oflag); + c_oflag = setFlag(t.getOutputFlag(OutputFlag.OFDEL), OFDEL, c_oflag); + // Control flags + c_cflag = setFlag(t.getControlFlag(ControlFlag.CS5), CS5, c_cflag); + c_cflag = setFlag(t.getControlFlag(ControlFlag.CS6), CS6, c_cflag); + c_cflag = setFlag(t.getControlFlag(ControlFlag.CS7), CS7, c_cflag); + c_cflag = setFlag(t.getControlFlag(ControlFlag.CS8), CS8, c_cflag); + c_cflag = setFlag(t.getControlFlag(ControlFlag.CSTOPB), CSTOPB, c_cflag); + c_cflag = setFlag(t.getControlFlag(ControlFlag.CREAD), CREAD, c_cflag); + c_cflag = setFlag(t.getControlFlag(ControlFlag.PARENB), PARENB, c_cflag); + c_cflag = setFlag(t.getControlFlag(ControlFlag.PARODD), PARODD, c_cflag); + c_cflag = setFlag(t.getControlFlag(ControlFlag.HUPCL), HUPCL, c_cflag); + c_cflag = setFlag(t.getControlFlag(ControlFlag.CLOCAL), CLOCAL, c_cflag); + // Local flags + c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOKE), ECHOKE, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOE), ECHOE, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOK), ECHOK, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHO), ECHO, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHONL), ECHONL, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOPRT), ECHOPRT, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOCTL), ECHOCTL, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.ISIG), ISIG, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.ICANON), ICANON, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.IEXTEN), IEXTEN, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.EXTPROC), EXTPROC, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.TOSTOP), TOSTOP, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.FLUSHO), FLUSHO, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.PENDIN), PENDIN, c_lflag); + c_lflag = setFlag(t.getLocalFlag(LocalFlag.NOFLSH), NOFLSH, c_lflag); + // Control chars + c_cc[VEOF] = (byte) t.getControlChar(ControlChar.VEOF); + c_cc[VEOL] = (byte) t.getControlChar(ControlChar.VEOL); + c_cc[VEOL2] = (byte) t.getControlChar(ControlChar.VEOL2); + c_cc[VERASE] = (byte) t.getControlChar(ControlChar.VERASE); + c_cc[VWERASE] = (byte) t.getControlChar(ControlChar.VWERASE); + c_cc[VKILL] = (byte) t.getControlChar(ControlChar.VKILL); + c_cc[VREPRINT] = (byte) t.getControlChar(ControlChar.VREPRINT); + c_cc[VINTR] = (byte) t.getControlChar(ControlChar.VINTR); + c_cc[VQUIT] = (byte) t.getControlChar(ControlChar.VQUIT); + c_cc[VSUSP] = (byte) t.getControlChar(ControlChar.VSUSP); + c_cc[VSTART] = (byte) t.getControlChar(ControlChar.VSTART); + c_cc[VSTOP] = (byte) t.getControlChar(ControlChar.VSTOP); + c_cc[VLNEXT] = (byte) t.getControlChar(ControlChar.VLNEXT); + c_cc[VDISCARD] = (byte) t.getControlChar(ControlChar.VDISCARD); + c_cc[VMIN] = (byte) t.getControlChar(ControlChar.VMIN); + c_cc[VTIME] = (byte) t.getControlChar(ControlChar.VTIME); + } + + private int setFlag(boolean flag, int value, int org) { + return flag ? (org | value) : org; + } + + public Attributes toAttributes() { + Attributes attr = new Attributes(); + // Input flags + EnumSet iflag = attr.getInputFlags(); + addFlag(c_iflag, iflag, InputFlag.IGNBRK, IGNBRK); + addFlag(c_iflag, iflag, InputFlag.IGNBRK, IGNBRK); + addFlag(c_iflag, iflag, InputFlag.BRKINT, BRKINT); + addFlag(c_iflag, iflag, InputFlag.IGNPAR, IGNPAR); + addFlag(c_iflag, iflag, InputFlag.PARMRK, PARMRK); + addFlag(c_iflag, iflag, InputFlag.INPCK, INPCK); + addFlag(c_iflag, iflag, InputFlag.ISTRIP, ISTRIP); + addFlag(c_iflag, iflag, InputFlag.INLCR, INLCR); + addFlag(c_iflag, iflag, InputFlag.IGNCR, IGNCR); + addFlag(c_iflag, iflag, InputFlag.ICRNL, ICRNL); + addFlag(c_iflag, iflag, InputFlag.IXON, IXON); + addFlag(c_iflag, iflag, InputFlag.IXOFF, IXOFF); + addFlag(c_iflag, iflag, InputFlag.IXANY, IXANY); + addFlag(c_iflag, iflag, InputFlag.IMAXBEL, IMAXBEL); + addFlag(c_iflag, iflag, InputFlag.IUTF8, IUTF8); + // Output flags + EnumSet oflag = attr.getOutputFlags(); + addFlag(c_oflag, oflag, OutputFlag.OPOST, OPOST); + addFlag(c_oflag, oflag, OutputFlag.ONLCR, ONLCR); + addFlag(c_oflag, oflag, OutputFlag.OCRNL, OCRNL); + addFlag(c_oflag, oflag, OutputFlag.ONOCR, ONOCR); + addFlag(c_oflag, oflag, OutputFlag.ONLRET, ONLRET); + addFlag(c_oflag, oflag, OutputFlag.OFILL, OFILL); + addFlag(c_oflag, oflag, OutputFlag.NLDLY, NLDLY); + addFlag(c_oflag, oflag, OutputFlag.TABDLY, TABDLY); + addFlag(c_oflag, oflag, OutputFlag.CRDLY, CRDLY); + addFlag(c_oflag, oflag, OutputFlag.FFDLY, FFDLY); + addFlag(c_oflag, oflag, OutputFlag.BSDLY, BSDLY); + addFlag(c_oflag, oflag, OutputFlag.VTDLY, VTDLY); + addFlag(c_oflag, oflag, OutputFlag.OFDEL, OFDEL); + // Control flags + EnumSet cflag = attr.getControlFlags(); + addFlag(c_cflag, cflag, ControlFlag.CS5, CS5); + addFlag(c_cflag, cflag, ControlFlag.CS6, CS6); + addFlag(c_cflag, cflag, ControlFlag.CS7, CS7); + addFlag(c_cflag, cflag, ControlFlag.CS8, CS8); + addFlag(c_cflag, cflag, ControlFlag.CSTOPB, CSTOPB); + addFlag(c_cflag, cflag, ControlFlag.CREAD, CREAD); + addFlag(c_cflag, cflag, ControlFlag.PARENB, PARENB); + addFlag(c_cflag, cflag, ControlFlag.PARODD, PARODD); + addFlag(c_cflag, cflag, ControlFlag.HUPCL, HUPCL); + addFlag(c_cflag, cflag, ControlFlag.CLOCAL, CLOCAL); + // Local flags + EnumSet lflag = attr.getLocalFlags(); + addFlag(c_lflag, lflag, LocalFlag.ECHOKE, ECHOKE); + addFlag(c_lflag, lflag, LocalFlag.ECHOE, ECHOE); + addFlag(c_lflag, lflag, LocalFlag.ECHOK, ECHOK); + addFlag(c_lflag, lflag, LocalFlag.ECHO, ECHO); + addFlag(c_lflag, lflag, LocalFlag.ECHONL, ECHONL); + addFlag(c_lflag, lflag, LocalFlag.ECHOPRT, ECHOPRT); + addFlag(c_lflag, lflag, LocalFlag.ECHOCTL, ECHOCTL); + addFlag(c_lflag, lflag, LocalFlag.ISIG, ISIG); + addFlag(c_lflag, lflag, LocalFlag.ICANON, ICANON); + addFlag(c_lflag, lflag, LocalFlag.IEXTEN, IEXTEN); + addFlag(c_lflag, lflag, LocalFlag.EXTPROC, EXTPROC); + addFlag(c_lflag, lflag, LocalFlag.TOSTOP, TOSTOP); + addFlag(c_lflag, lflag, LocalFlag.FLUSHO, FLUSHO); + addFlag(c_lflag, lflag, LocalFlag.PENDIN, PENDIN); + addFlag(c_lflag, lflag, LocalFlag.NOFLSH, NOFLSH); + // Control chars + EnumMap cc = attr.getControlChars(); + cc.put(ControlChar.VEOF, (int) c_cc[VEOF]); + cc.put(ControlChar.VEOL, (int) c_cc[VEOL]); + cc.put(ControlChar.VEOL2, (int) c_cc[VEOL2]); + cc.put(ControlChar.VERASE, (int) c_cc[VERASE]); + cc.put(ControlChar.VWERASE, (int) c_cc[VWERASE]); + cc.put(ControlChar.VKILL, (int) c_cc[VKILL]); + cc.put(ControlChar.VREPRINT, (int) c_cc[VREPRINT]); + cc.put(ControlChar.VINTR, (int) c_cc[VINTR]); + cc.put(ControlChar.VQUIT, (int) c_cc[VQUIT]); + cc.put(ControlChar.VSUSP, (int) c_cc[VSUSP]); + cc.put(ControlChar.VSTART, (int) c_cc[VSTART]); + cc.put(ControlChar.VSTOP, (int) c_cc[VSTOP]); + cc.put(ControlChar.VLNEXT, (int) c_cc[VLNEXT]); + cc.put(ControlChar.VDISCARD, (int) c_cc[VDISCARD]); + cc.put(ControlChar.VMIN, (int) c_cc[VMIN]); + cc.put(ControlChar.VTIME, (int) c_cc[VTIME]); + // Return + return attr; + } + + private > void addFlag(int value, EnumSet flags, T flag, int v) { + if ((value & v) != 0) { + flags.add(flag); + } + } + } + + // CONSTANTS + + int _TIOC = ('T' << 8); + int TIOCGWINSZ = (_TIOC | 104); + int TIOCSWINSZ = (_TIOC | 103); + + int VINTR = 0; + int VQUIT = 1; + int VERASE = 2; + int VKILL = 3; + int VEOF = 4; + int VTIME = 5; + int VMIN = 6; + int VSWTC = 7; + int VSTART = 8; + int VSTOP = 9; + int VSUSP = 10; + int VEOL = 11; + int VREPRINT = 12; + int VDISCARD = 13; + int VWERASE = 14; + int VLNEXT = 15; + int VEOL2 = 16; + + int IGNBRK = 0x0000001; + int BRKINT = 0x0000002; + int IGNPAR = 0x0000004; + int PARMRK = 0x0000010; + int INPCK = 0x0000020; + int ISTRIP = 0x0000040; + int INLCR = 0x0000100; + int IGNCR = 0x0000200; + int ICRNL = 0x0000400; + int IUCLC = 0x0001000; + int IXON = 0x0002000; + int IXANY = 0x0004000; + int IXOFF = 0x0010000; + int IMAXBEL = 0x0020000; + int IUTF8 = 0x0040000; + + int OPOST = 0x0000001; + int OLCUC = 0x0000002; + int ONLCR = 0x0000004; + int OCRNL = 0x0000010; + int ONOCR = 0x0000020; + int ONLRET = 0x0000040; + int OFILL = 0x0000100; + int OFDEL = 0x0000200; + int NLDLY = 0x0000400; + int NL0 = 0x0000000; + int NL1 = 0x0000400; + int CRDLY = 0x0003000; + int CR0 = 0x0000000; + int CR1 = 0x0001000; + int CR2 = 0x0002000; + int CR3 = 0x0003000; + int TABDLY = 0x0014000; + int TAB0 = 0x0000000; + int TAB1 = 0x0004000; + int TAB2 = 0x0010000; + int TAB3 = 0x0014000; + int XTABS = 0x0014000; + int BSDLY = 0x0020000; + int BS0 = 0x0000000; + int BS1 = 0x0020000; + int VTDLY = 0x0040000; + int VT0 = 0x0000000; + int VT1 = 0x0040000; + int FFDLY = 0x0100000; + int FF0 = 0x0000000; + int FF1 = 0x0100000; + + int CBAUD = 0x0010017; + int B0 = 0x0000000; + int B50 = 0x0000001; + int B75 = 0x0000002; + int B110 = 0x0000003; + int B134 = 0x0000004; + int B150 = 0x0000005; + int B200 = 0x0000006; + int B300 = 0x0000007; + int B600 = 0x0000010; + int B1200 = 0x0000011; + int B1800 = 0x0000012; + int B2400 = 0x0000013; + int B4800 = 0x0000014; + int B9600 = 0x0000015; + int B19200 = 0x0000016; + int B38400 = 0x0000017; + int EXTA = 0xB19200; + int EXTB = 0xB38400; + int CSIZE = 0x0000060; + int CS5 = 0x0000000; + int CS6 = 0x0000020; + int CS7 = 0x0000040; + int CS8 = 0x0000060; + int CSTOPB = 0x0000100; + int CREAD = 0x0000200; + int PARENB = 0x0000400; + int PARODD = 0x0001000; + int HUPCL = 0x0002000; + int CLOCAL = 0x0004000; + + int ISIG = 0x0000001; + int ICANON = 0x0000002; + int XCASE = 0x0000004; + int ECHO = 0x0000010; + int ECHOE = 0x0000020; + int ECHOK = 0x0000040; + int ECHONL = 0x0000100; + int NOFLSH = 0x0000200; + int TOSTOP = 0x0000400; + int ECHOCTL = 0x0001000; + int ECHOPRT = 0x0002000; + int ECHOKE = 0x0004000; + int FLUSHO = 0x0010000; + int PENDIN = 0x0040000; + int IEXTEN = 0x0100000; + int EXTPROC = 0x0200000; + + int TCSANOW = 0x0; + int TCSADRAIN = 0x1; + int TCSAFLUSH = 0x2; +} --- /dev/null +++ b/src/jdk.internal.le/solaris/classes/jdk/internal/org/jline/terminal/impl/jna/solaris/CLibraryImpl.java 2023-06-02 10:52:24.003243641 +0100 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.org.jline.terminal.impl.jna.solaris; + +import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; + +public final class CLibraryImpl implements CLibrary { + + static { + System.loadLibrary("le"); + initIDs(); + } + + private static native void initIDs(); + + @Override + public native void tcgetattr(int fd, termios termios) throws LastErrorException; + + @Override + public native void tcsetattr(int fd, int cmd, termios termios) throws LastErrorException; + + @Override + public void ioctl(int fd, long cmd, winsize data) throws LastErrorException { + if (cmd == CLibrary.TIOCGWINSZ || cmd == CLibrary.TIOCSWINSZ) { + ioctl0(fd, cmd, data); + } else { + throw new UnsupportedOperationException("Command: " + cmd + ", not supported."); + } + } + + private native void ioctl0(int fd, long cmd, winsize data) throws LastErrorException; + + @Override + public native int isatty(int fd); + + @Override + public native void ttyname_r(int fd, byte[] buf, int len) throws LastErrorException; + + @Override + public void openpty(int[] master, int[] slave, byte[] name, CLibrary.termios t, CLibrary.winsize s) throws LastErrorException { + throw new UnsupportedOperationException(); + } + +} --- /dev/null +++ b/src/jdk.internal.le/solaris/classes/jdk/internal/org/jline/terminal/impl/jna/solaris/SolarisNativePty.java 2023-06-02 10:25:31.059689102 +0100 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2002-2020, the original author(s). + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.jna.solaris; + +import java.io.FileDescriptor; +import java.io.IOException; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.impl.jna.JnaNativePty; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; + +//import com.sun.jna.Native; +//import com.sun.jna.Platform; + +import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.TCSANOW; +import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.TIOCGWINSZ; +import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.TIOCSWINSZ; +import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.termios; +import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.winsize; + +public class SolarisNativePty extends JnaNativePty { + +// private static final CLibrary C_LIBRARY = Native.load(Platform.C_LIBRARY_NAME, CLibrary.class); + private static final CLibrary C_LIBRARY = new CLibraryImpl(); + + public static SolarisNativePty current(TerminalProvider.Stream consoleStream) throws IOException { + switch (consoleStream) { + case Output: + return new SolarisNativePty(-1, null, 0, FileDescriptor.in, 1, FileDescriptor.out, ttyname(0)); + case Error: + return new SolarisNativePty(-1, null, 0, FileDescriptor.in, 2, FileDescriptor.err, ttyname(0)); + default: + throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream); + } + } + + public static SolarisNativePty open(Attributes attr, Size size) throws IOException { + int[] master = new int[1]; + int[] slave = new int[1]; + byte[] buf = new byte[64]; + C_LIBRARY.openpty(master, slave, buf, + attr != null ? new termios(attr) : null, + size != null ? new winsize(size) : null); + int len = 0; + while (buf[len] != 0) { + len++; + } + String name = new String(buf, 0, len); + return new SolarisNativePty(master[0], newDescriptor(master[0]), slave[0], newDescriptor(slave[0]), name); + } + + public SolarisNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, String name) { + super(master, masterFD, slave, slaveFD, name); + } + + public SolarisNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, int slaveOut, FileDescriptor slaveOutFD, String name) { + super(master, masterFD, slave, slaveFD, slaveOut, slaveOutFD, name); + } + + @Override + public Attributes getAttr() throws IOException { + termios termios = new termios(); + C_LIBRARY.tcgetattr(getSlave(), termios); + return termios.toAttributes(); + } + + @Override + protected void doSetAttr(Attributes attr) throws IOException { + termios termios = new termios(attr); + C_LIBRARY.tcsetattr(getSlave(), TCSANOW, termios); + } + + @Override + public Size getSize() throws IOException { + winsize sz = new winsize(); + C_LIBRARY.ioctl(getSlave(), TIOCGWINSZ, sz); + return sz.toSize(); + } + + @Override + public void setSize(Size size) throws IOException { + winsize sz = new winsize(size); + C_LIBRARY.ioctl(getSlave(), TIOCSWINSZ, sz); + } + + public static int isatty(int fd) { + return C_LIBRARY.isatty(fd); + } + + public static String ttyname(int slave) { + byte[] buf = new byte[64]; + C_LIBRARY.ttyname_r(slave, buf, buf.length); + int len = 0; + while (buf[len] != 0) { + len++; + } + return new String(buf, 0, len); + } + +} --- /dev/null +++ b/src/jdk.internal.le/solaris/native/lible/CLibrary.cpp 2023-06-02 11:05:11.905773520 +0100 @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "jni.h" +#include "jni_util.h" +#include "jvm.h" +#include "jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl.h" + +#include +#include +#include +#include +#include + +static jclass lastErrorExceptionClass; +static jmethodID lastErrorExceptionConstructor; + +static jclass termios_j; +static jfieldID c_iflag; +static jfieldID c_oflag; +static jfieldID c_cflag; +static jfieldID c_lflag; +static jfieldID c_cc; + +static jclass winsize_j; +static jfieldID ws_row; +static jfieldID ws_col; +static jfieldID ws_xpixel; +static jfieldID ws_ypixel; + +static void throw_errno(JNIEnv *env); + +JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_initIDs + (JNIEnv *env, jclass unused) { + jclass cls; + cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/LastErrorException"); + CHECK_NULL(cls); + lastErrorExceptionClass = (jclass) env->NewGlobalRef(cls); + lastErrorExceptionConstructor = env->GetMethodID(lastErrorExceptionClass, "", "(J)V"); + CHECK_NULL(lastErrorExceptionConstructor); + + cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary$termios"); + CHECK_NULL(cls); + termios_j = (jclass) env->NewGlobalRef(cls); + c_iflag = env->GetFieldID(termios_j, "c_iflag", "I"); + CHECK_NULL(c_iflag); + c_oflag = env->GetFieldID(termios_j, "c_oflag", "I"); + CHECK_NULL(c_oflag); + c_cflag = env->GetFieldID(termios_j, "c_cflag", "I"); + CHECK_NULL(c_cflag); + c_lflag = env->GetFieldID(termios_j, "c_lflag", "I"); + CHECK_NULL(c_lflag); + c_cc = env->GetFieldID(termios_j, "c_cc", "[B"); + CHECK_NULL(c_cc); + + cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary$winsize"); + CHECK_NULL(cls); + winsize_j = (jclass) env->NewGlobalRef(cls); + ws_row = env->GetFieldID(winsize_j, "ws_row", "S"); + CHECK_NULL(ws_row); + ws_col = env->GetFieldID(winsize_j, "ws_col", "S"); + CHECK_NULL(ws_col); + ws_xpixel= env->GetFieldID(winsize_j, "ws_xpixel", "S"); + CHECK_NULL(ws_xpixel); + ws_ypixel= env->GetFieldID(winsize_j, "ws_ypixel", "S"); + CHECK_NULL(ws_ypixel); +} + +JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_tcgetattr + (JNIEnv *env, jobject, jint fd, jobject result) { + termios data; + + if (tcgetattr(fd, &data) != 0) { + throw_errno(env); + return ; + } + + env->SetIntField(result, c_iflag, data.c_iflag); + env->SetIntField(result, c_oflag, data.c_oflag); + env->SetIntField(result, c_cflag, data.c_cflag); + env->SetIntField(result, c_lflag, data.c_lflag); + jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(result, c_cc); + env->SetByteArrayRegion(c_ccValue, 0, NCCS, (signed char *) data.c_cc);//TODO: cast? +} + +/* + * Class: jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl + * Method: tcsetattr + * Signature: (IILjdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary/termios;)V + */ +JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_tcsetattr + (JNIEnv *env, jobject, jint fd, jint cmd, jobject input) { + termios data; + + data.c_iflag = env->GetIntField(input, c_iflag); + data.c_oflag = env->GetIntField(input, c_oflag); + data.c_cflag = env->GetIntField(input, c_cflag); + data.c_lflag = env->GetIntField(input, c_lflag); + jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(input, c_cc); + env->GetByteArrayRegion(c_ccValue, 0, NCCS, (jbyte *) data.c_cc); + + if (tcsetattr(fd, cmd, &data) != 0) { + throw_errno(env); + } +} + +/* + * Class: jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl + * Method: ioctl0 + * Signature: (IILjdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary/winsize;)V + */ +JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_ioctl0 + (JNIEnv *env, jobject, jint fd, jlong cmd, jobject data) { + winsize ws; + + ws.ws_row = env->GetIntField(data, ws_row); + ws.ws_col = env->GetIntField(data, ws_col); + ws.ws_xpixel = env->GetIntField(data, ws_xpixel); + ws.ws_ypixel = env->GetIntField(data, ws_ypixel); + + if (ioctl(fd, cmd, &ws) != 0) { + throw_errno(env); + return ; + } + + env->SetIntField(data, ws_row, ws.ws_row); + env->SetIntField(data, ws_col, ws.ws_col); + env->SetIntField(data, ws_xpixel, ws.ws_xpixel); + env->SetIntField(data, ws_ypixel, ws.ws_ypixel); +} + +/* + * Class: jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl + * Method: isatty + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_isatty + (JNIEnv *, jobject, jint fd) { + return isatty(fd); +} + +/* + * Class: jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl + * Method: ttyname_r + * Signature: (I[BI)V + */ +JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_ttyname_1r + (JNIEnv *env, jobject, jint fd, jbyteArray buf, jint len) { + char *data = new char[len]; + int error = ttyname_r(fd, data, len); + + if (error != 0) { + throw_errno(env); + return ; + } + + env->SetByteArrayRegion(buf, 0, len, (jbyte *) data); + delete[] data; +} + +/* + * Throws LastErrorException based on the errno: + */ +static void throw_errno(JNIEnv *env) { + jobject exc = env->NewObject(lastErrorExceptionClass, + lastErrorExceptionConstructor, + errno); + env->Throw((jthrowable) exc); +} --- a/make/modules/jdk.internal.le/Lib.gmk Tue May 23 22:32:28 2023 +++ b/make/modules/jdk.internal.le/Lib.gmk Fri Jun 2 11:33:06 2023 @@ -27,7 +27,7 @@ ################################################################################ -ifeq ($(call isTargetOs, linux macosx windows), true) +ifeq ($(call isTargetOs, linux macosx solaris windows), true) $(eval $(call SetupJdkLibrary, BUILD_LIBLE, \ NAME := le, \