8306983: Do not invoke external programs when switch terminal to raw mode on selected platforms
Co-authored-by: Adam Sotona <asotona@openjdk.org> Reviewed-by: erikj, vromero, bpb
This commit is contained in:
parent
6b65e5754c
commit
a9705196ce
@ -27,14 +27,16 @@ include LibCommon.gmk
|
||||
|
||||
################################################################################
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
ifeq ($(call isTargetOs, linux macosx windows), true)
|
||||
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIBLE, \
|
||||
NAME := le, \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB), \
|
||||
CFLAGS := $(CXXFLAGS_JDKLIB), \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB), \
|
||||
LIBS := $(JDKLIB_LIBS) user32.lib, \
|
||||
LIBS_unix := $(JDKLIB_LIBS) $(LIBCXX), \
|
||||
LIBS_windows := $(JDKLIB_LIBS) user32.lib, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIBLE)
|
||||
|
@ -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.linux.LinuxNativePty;
|
||||
import jdk.internal.org.jline.terminal.spi.TerminalProvider;
|
||||
|
||||
class JDKNativePty {
|
||||
|
||||
static JnaNativePty current(TerminalProvider.Stream console) throws IOException {
|
||||
return LinuxNativePty.current(console);
|
||||
}
|
||||
|
||||
static JnaNativePty open(Attributes attr, Size size) throws IOException {
|
||||
return LinuxNativePty.open(attr, size);
|
||||
}
|
||||
|
||||
static int isatty(int fd) {
|
||||
return LinuxNativePty.isatty(fd);
|
||||
}
|
||||
|
||||
static String ttyname(int fd) {
|
||||
return LinuxNativePty.ttyname(fd);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,389 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2020, the original author or authors.
|
||||
*
|
||||
* 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.linux;
|
||||
|
||||
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.Platform;
|
||||
//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, int cmd, winsize data) throws LastErrorException;
|
||||
|
||||
int isatty(int fd);
|
||||
|
||||
void ttyname_r(int fd, byte[] buf, int len) 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<String> 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_line;
|
||||
public byte[] c_cc = new byte[32];
|
||||
public int c_ispeed;
|
||||
public int c_ospeed;
|
||||
|
||||
// @Override
|
||||
// protected List<String> getFieldOrder() {
|
||||
// return Arrays.asList(//
|
||||
// "c_iflag",//
|
||||
// "c_oflag",//
|
||||
// "c_cflag",//
|
||||
// "c_lflag",//
|
||||
// "c_line",//
|
||||
// "c_cc",//
|
||||
// "c_ispeed",//
|
||||
// "c_ospeed"//
|
||||
// );
|
||||
// }
|
||||
|
||||
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.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.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<InputFlag> 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<OutputFlag> 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<ControlFlag> 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<LocalFlag> 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.EXTPROC, EXTPROC);
|
||||
addFlag(c_lflag, lflag, LocalFlag.TOSTOP, TOSTOP);
|
||||
addFlag(c_lflag, lflag, LocalFlag.FLUSHO, FLUSHO);
|
||||
addFlag(c_lflag, lflag, LocalFlag.NOFLSH, NOFLSH);
|
||||
// Control chars
|
||||
EnumMap<ControlChar, Integer> 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 <T extends Enum<T>> void addFlag(int value, EnumSet<T> flags, T flag, int v) {
|
||||
if ((value & v) != 0) {
|
||||
flags.add(flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CONSTANTS
|
||||
|
||||
int TIOCGWINSZ = /*Platform.isMIPS() || Platform.isPPC() || Platform.isSPARC() ? 0x40087468 : */0x00005413;
|
||||
int TIOCSWINSZ = /*Platform.isMIPS() || Platform.isPPC() || Platform.isSPARC() ? 0x80087467 : */0x00005414;
|
||||
|
||||
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 = 0x0000008;
|
||||
int INPCK = 0x0000010;
|
||||
int ISTRIP = 0x0000020;
|
||||
int INLCR = 0x0000040;
|
||||
int IGNCR = 0x0000080;
|
||||
int ICRNL = 0x0000100;
|
||||
int IUCLC = 0x0000200;
|
||||
int IXON = 0x0000400;
|
||||
int IXANY = 0x0000800;
|
||||
int IXOFF = 0x0001000;
|
||||
int IMAXBEL = 0x0002000;
|
||||
int IUTF8 = 0x0004000;
|
||||
|
||||
int OPOST = 0x0000001;
|
||||
int OLCUC = 0x0000002;
|
||||
int ONLCR = 0x0000004;
|
||||
int OCRNL = 0x0000008;
|
||||
int ONOCR = 0x0000010;
|
||||
int ONLRET = 0x0000020;
|
||||
int OFILL = 0x0000040;
|
||||
int OFDEL = 0x0000080;
|
||||
int NLDLY = 0x0000100;
|
||||
int NL0 = 0x0000000;
|
||||
int NL1 = 0x0000100;
|
||||
int CRDLY = 0x0000600;
|
||||
int CR0 = 0x0000000;
|
||||
int CR1 = 0x0000200;
|
||||
int CR2 = 0x0000400;
|
||||
int CR3 = 0x0000600;
|
||||
int TABDLY = 0x0001800;
|
||||
int TAB0 = 0x0000000;
|
||||
int TAB1 = 0x0000800;
|
||||
int TAB2 = 0x0001000;
|
||||
int TAB3 = 0x0001800;
|
||||
int XTABS = 0x0001800;
|
||||
int BSDLY = 0x0002000;
|
||||
int BS0 = 0x0000000;
|
||||
int BS1 = 0x0002000;
|
||||
int VTDLY = 0x0004000;
|
||||
int VT0 = 0x0000000;
|
||||
int VT1 = 0x0004000;
|
||||
int FFDLY = 0x0008000;
|
||||
int FF0 = 0x0000000;
|
||||
int FF1 = 0x0008000;
|
||||
|
||||
int CBAUD = 0x000100f;
|
||||
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 = 0x0000008;
|
||||
int B1200 = 0x0000009;
|
||||
int B1800 = 0x000000a;
|
||||
int B2400 = 0x000000b;
|
||||
int B4800 = 0x000000c;
|
||||
int B9600 = 0x000000d;
|
||||
int B19200 = 0x000000e;
|
||||
int B38400 = 0x000000f;
|
||||
int EXTA = B19200;
|
||||
int EXTB = B38400;
|
||||
int CSIZE = 0x0000030;
|
||||
int CS5 = 0x0000000;
|
||||
int CS6 = 0x0000010;
|
||||
int CS7 = 0x0000020;
|
||||
int CS8 = 0x0000030;
|
||||
int CSTOPB = 0x0000040;
|
||||
int CREAD = 0x0000080;
|
||||
int PARENB = 0x0000100;
|
||||
int PARODD = 0x0000200;
|
||||
int HUPCL = 0x0000400;
|
||||
int CLOCAL = 0x0000800;
|
||||
|
||||
int ISIG = 0x0000001;
|
||||
int ICANON = 0x0000002;
|
||||
int XCASE = 0x0000004;
|
||||
int ECHO = 0x0000008;
|
||||
int ECHOE = 0x0000010;
|
||||
int ECHOK = 0x0000020;
|
||||
int ECHONL = 0x0000040;
|
||||
int NOFLSH = 0x0000080;
|
||||
int TOSTOP = 0x0000100;
|
||||
int ECHOCTL = 0x0000200;
|
||||
int ECHOPRT = 0x0000400;
|
||||
int ECHOKE = 0x0000800;
|
||||
int FLUSHO = 0x0001000;
|
||||
int PENDIN = 0x0002000;
|
||||
int IEXTEN = 0x0008000;
|
||||
int EXTPROC = 0x0010000;
|
||||
|
||||
int TCSANOW = 0x0;
|
||||
int TCSADRAIN = 0x1;
|
||||
int TCSAFLUSH = 0x2;
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.linux;
|
||||
|
||||
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, int 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, int 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;
|
||||
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2020, the original author or authors.
|
||||
*
|
||||
* 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.linux;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
|
||||
//import com.sun.jna.LastErrorException;
|
||||
//import com.sun.jna.Native;
|
||||
//import com.sun.jna.Platform;
|
||||
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.impl.jna.LastErrorException;
|
||||
import jdk.internal.org.jline.terminal.spi.TerminalProvider;
|
||||
|
||||
import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.TCSADRAIN;
|
||||
import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.TIOCGWINSZ;
|
||||
import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.TIOCSWINSZ;
|
||||
import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.termios;
|
||||
import static jdk.internal.org.jline.terminal.impl.jna.linux.CLibrary.winsize;
|
||||
|
||||
public class LinuxNativePty 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 interface UtilLibrary {// extends com.sun.jna.Library {
|
||||
|
||||
void openpty(int[] master, int[] slave, byte[] name, CLibrary.termios t, CLibrary.winsize s) throws LastErrorException;
|
||||
|
||||
// UtilLibrary INSTANCE = Native.load("util", UtilLibrary.class);
|
||||
UtilLibrary INSTANCE = new UtilLibraryImpl();
|
||||
}
|
||||
|
||||
public static LinuxNativePty current(TerminalProvider.Stream consoleStream) throws IOException {
|
||||
switch (consoleStream) {
|
||||
case Output:
|
||||
return new LinuxNativePty(-1, null, 0, FileDescriptor.in, 1, FileDescriptor.out, ttyname(0));
|
||||
case Error:
|
||||
return new LinuxNativePty(-1, null, 0, FileDescriptor.in, 2, FileDescriptor.err, ttyname(0));
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream);
|
||||
}
|
||||
}
|
||||
|
||||
public static LinuxNativePty open(Attributes attr, Size size) throws IOException {
|
||||
int[] master = new int[1];
|
||||
int[] slave = new int[1];
|
||||
byte[] buf = new byte[64];
|
||||
UtilLibrary.INSTANCE.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 LinuxNativePty(master[0], newDescriptor(master[0]), slave[0], newDescriptor(slave[0]), name);
|
||||
}
|
||||
|
||||
public LinuxNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, String name) {
|
||||
super(master, masterFD, slave, slaveFD, name);
|
||||
}
|
||||
|
||||
public LinuxNativePty(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);
|
||||
termios org = new termios();
|
||||
C_LIBRARY.tcgetattr(getSlave(), org);
|
||||
org.c_iflag = termios.c_iflag;
|
||||
org.c_oflag = termios.c_oflag;
|
||||
org.c_lflag = termios.c_lflag;
|
||||
System.arraycopy(termios.c_cc, 0, org.c_cc, 0, termios.c_cc.length);
|
||||
C_LIBRARY.tcsetattr(getSlave(), TCSADRAIN, org);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.linux;
|
||||
|
||||
import jdk.internal.org.jline.terminal.impl.jna.LastErrorException;
|
||||
import jdk.internal.org.jline.terminal.impl.jna.linux.LinuxNativePty.UtilLibrary;
|
||||
|
||||
public final class UtilLibraryImpl implements UtilLibrary {
|
||||
|
||||
@Override
|
||||
public void openpty(int[] master, int[] slave, byte[] name, CLibrary.termios t, CLibrary.winsize s) throws LastErrorException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
206
src/jdk.internal.le/linux/native/lible/CLibrary.cpp
Normal file
206
src/jdk.internal.le/linux/native/lible/CLibrary.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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_linux_CLibraryImpl.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
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_line;
|
||||
static jfieldID c_cc;
|
||||
static jfieldID c_ispeed;
|
||||
static jfieldID c_ospeed;
|
||||
|
||||
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_linux_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, "<init>", "(J)V");
|
||||
CHECK_NULL(lastErrorExceptionConstructor);
|
||||
|
||||
cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/linux/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_line = env->GetFieldID(termios_j, "c_line", "B");
|
||||
CHECK_NULL(c_line);
|
||||
c_cc = env->GetFieldID(termios_j, "c_cc", "[B");
|
||||
CHECK_NULL(c_cc);
|
||||
c_ispeed = env->GetFieldID(termios_j, "c_ispeed", "I");
|
||||
CHECK_NULL(c_ispeed);
|
||||
c_ospeed = env->GetFieldID(termios_j, "c_ospeed", "I");
|
||||
CHECK_NULL(c_ospeed);
|
||||
|
||||
cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/linux/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_linux_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);
|
||||
env->SetIntField(result, c_line, data.c_line);
|
||||
jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(result, c_cc);
|
||||
env->SetByteArrayRegion(c_ccValue, 0, NCCS, (signed char *) data.c_cc);//TODO: cast?
|
||||
env->SetIntField(result, c_ispeed, data.c_ispeed);
|
||||
env->SetIntField(result, c_ospeed, data.c_ospeed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl
|
||||
* Method: tcsetattr
|
||||
* Signature: (IILjdk/internal/org/jline/terminal/impl/jna/linux/CLibrary/termios;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_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);
|
||||
data.c_line = env->GetIntField(input, c_line);
|
||||
jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(input, c_cc);
|
||||
env->GetByteArrayRegion(c_ccValue, 0, NCCS, (jbyte *) data.c_cc);
|
||||
data.c_ispeed = env->GetIntField(input, c_ispeed);
|
||||
data.c_ospeed = env->GetIntField(input, c_ospeed);
|
||||
|
||||
if (tcsetattr(fd, cmd, &data) != 0) {
|
||||
throw_errno(env);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl
|
||||
* Method: ioctl0
|
||||
* Signature: (IILjdk/internal/org/jline/terminal/impl/jna/linux/CLibrary/winsize;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl_ioctl0
|
||||
(JNIEnv *env, jobject, jint fd, jint 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_linux_CLibraryImpl
|
||||
* Method: isatty
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl_isatty
|
||||
(JNIEnv *, jobject, jint fd) {
|
||||
return isatty(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: jdk_internal_org_jline_terminal_impl_jna_linux_CLibraryImpl
|
||||
* Method: ttyname_r
|
||||
* Signature: (I[BI)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_linux_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);
|
||||
}
|
@ -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.osx.OsXNativePty;
|
||||
import jdk.internal.org.jline.terminal.spi.TerminalProvider;
|
||||
|
||||
class JDKNativePty {
|
||||
|
||||
static JnaNativePty current(TerminalProvider.Stream console) throws IOException {
|
||||
return OsXNativePty.current(console);
|
||||
}
|
||||
|
||||
static JnaNativePty open(Attributes attr, Size size) throws IOException {
|
||||
return OsXNativePty.open(attr, size);
|
||||
}
|
||||
|
||||
static int isatty(int fd) {
|
||||
return OsXNativePty.isatty(fd);
|
||||
}
|
||||
|
||||
static String ttyname(int fd) {
|
||||
return OsXNativePty.ttyname(fd);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,394 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2020, the original author or authors.
|
||||
*
|
||||
* 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.osx;
|
||||
|
||||
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.NativeLong;
|
||||
//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, NativeLong 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<String> getFieldOrder() {
|
||||
// return Arrays.asList(//
|
||||
// "ws_row",//
|
||||
// "ws_col",//
|
||||
// "ws_xpixel",//
|
||||
// "ws_ypixel"//
|
||||
// );
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
class termios { //extends Structure {
|
||||
|
||||
public NativeLong c_iflag;
|
||||
public NativeLong c_oflag;
|
||||
public NativeLong c_cflag;
|
||||
public NativeLong c_lflag;
|
||||
public byte[] c_cc = new byte[20];
|
||||
public NativeLong c_ispeed;
|
||||
public NativeLong c_ospeed;
|
||||
|
||||
// @Override
|
||||
// protected List<String> getFieldOrder() {
|
||||
// return Arrays.asList(//
|
||||
// "c_iflag",//
|
||||
// "c_oflag",//
|
||||
// "c_cflag",//
|
||||
// "c_lflag",//
|
||||
// "c_cc",//
|
||||
// "c_ispeed",//
|
||||
// "c_ospeed"//
|
||||
// );
|
||||
// }
|
||||
|
||||
{
|
||||
c_iflag = new NativeLong(0);
|
||||
c_oflag = new NativeLong(0);
|
||||
c_cflag = new NativeLong(0);
|
||||
c_lflag = new NativeLong(0);
|
||||
c_ispeed = new NativeLong(0);
|
||||
c_ospeed = new NativeLong(0);
|
||||
}
|
||||
|
||||
public termios() {
|
||||
}
|
||||
|
||||
public termios(Attributes t) {
|
||||
// Input flags
|
||||
setFlag(t.getInputFlag(InputFlag.IGNBRK), IGNBRK, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.BRKINT), BRKINT, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.IGNPAR), IGNPAR, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.PARMRK), PARMRK, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.INPCK), INPCK, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.ISTRIP), ISTRIP, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.INLCR), INLCR, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.IGNCR), IGNCR, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.ICRNL), ICRNL, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.IXON), IXON, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.IXOFF), IXOFF, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.IXANY), IXANY, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.IMAXBEL), IMAXBEL, c_iflag);
|
||||
setFlag(t.getInputFlag(InputFlag.IUTF8), IUTF8, c_iflag);
|
||||
// Output flags
|
||||
setFlag(t.getOutputFlag(OutputFlag.OPOST), OPOST, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.ONLCR), ONLCR, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.OXTABS), OXTABS, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.ONOEOT), ONOEOT, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.OCRNL), OCRNL, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.ONOCR), ONOCR, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.ONLRET), ONLRET, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.OFILL), OFILL, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.NLDLY), NLDLY, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.TABDLY), TABDLY, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.CRDLY), CRDLY, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.FFDLY), FFDLY, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.BSDLY), BSDLY, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.VTDLY), VTDLY, c_oflag);
|
||||
setFlag(t.getOutputFlag(OutputFlag.OFDEL), OFDEL, c_oflag);
|
||||
// Control flags
|
||||
setFlag(t.getControlFlag(ControlFlag.CIGNORE), CIGNORE, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CS5), CS5, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CS6), CS6, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CS7), CS7, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CS8), CS8, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CSTOPB), CSTOPB, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CREAD), CREAD, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.PARENB), PARENB, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.PARODD), PARODD, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.HUPCL), HUPCL, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CLOCAL), CLOCAL, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CCTS_OFLOW), CCTS_OFLOW, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CRTS_IFLOW), CRTS_IFLOW, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CDTR_IFLOW), CDTR_IFLOW, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CDSR_OFLOW), CDSR_OFLOW, c_cflag);
|
||||
setFlag(t.getControlFlag(ControlFlag.CCAR_OFLOW), CCAR_OFLOW, c_cflag);
|
||||
// Local flags
|
||||
setFlag(t.getLocalFlag(LocalFlag.ECHOKE), ECHOKE, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.ECHOE), ECHOE, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.ECHOK), ECHOK, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.ECHO), ECHO, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.ECHONL), ECHONL, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.ECHOPRT), ECHOPRT, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.ECHOCTL), ECHOCTL, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.ISIG), ISIG, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.ICANON), ICANON, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.ALTWERASE), ALTWERASE, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.IEXTEN), IEXTEN, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.EXTPROC), EXTPROC, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.TOSTOP), TOSTOP, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.FLUSHO), FLUSHO, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.NOKERNINFO), NOKERNINFO, c_lflag);
|
||||
setFlag(t.getLocalFlag(LocalFlag.PENDIN), PENDIN, 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[VDSUSP] = (byte) t.getControlChar(ControlChar.VDSUSP);
|
||||
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);
|
||||
c_cc[VSTATUS] = (byte) t.getControlChar(ControlChar.VSTATUS);
|
||||
}
|
||||
|
||||
private void setFlag(boolean flag, long value, NativeLong org) {
|
||||
org.setValue(flag ? org.longValue() | value : org.longValue());
|
||||
}
|
||||
|
||||
public Attributes toAttributes() {
|
||||
Attributes attr = new Attributes();
|
||||
// Input flags
|
||||
EnumSet<InputFlag> iflag = attr.getInputFlags();
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.IGNBRK, IGNBRK);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.IGNBRK, IGNBRK);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.BRKINT, BRKINT);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.IGNPAR, IGNPAR);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.PARMRK, PARMRK);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.INPCK, INPCK);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.ISTRIP, ISTRIP);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.INLCR, INLCR);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.IGNCR, IGNCR);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.ICRNL, ICRNL);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.IXON, IXON);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.IXOFF, IXOFF);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.IXANY, IXANY);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.IMAXBEL, IMAXBEL);
|
||||
addFlag(c_iflag.longValue(), iflag, InputFlag.IUTF8, IUTF8);
|
||||
// Output flags
|
||||
EnumSet<OutputFlag> oflag = attr.getOutputFlags();
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.OPOST, OPOST);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.ONLCR, ONLCR);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.OXTABS, OXTABS);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.ONOEOT, ONOEOT);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.OCRNL, OCRNL);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.ONOCR, ONOCR);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.ONLRET, ONLRET);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.OFILL, OFILL);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.NLDLY, NLDLY);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.TABDLY, TABDLY);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.CRDLY, CRDLY);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.FFDLY, FFDLY);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.BSDLY, BSDLY);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.VTDLY, VTDLY);
|
||||
addFlag(c_oflag.longValue(), oflag, OutputFlag.OFDEL, OFDEL);
|
||||
// Control flags
|
||||
EnumSet<ControlFlag> cflag = attr.getControlFlags();
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CIGNORE, CIGNORE);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CS5, CS5);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CS6, CS6);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CS7, CS7);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CS8, CS8);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CSTOPB, CSTOPB);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CREAD, CREAD);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.PARENB, PARENB);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.PARODD, PARODD);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.HUPCL, HUPCL);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CLOCAL, CLOCAL);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CCTS_OFLOW, CCTS_OFLOW);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CRTS_IFLOW, CRTS_IFLOW);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CDSR_OFLOW, CDSR_OFLOW);
|
||||
addFlag(c_cflag.longValue(), cflag, ControlFlag.CCAR_OFLOW, CCAR_OFLOW);
|
||||
// Local flags
|
||||
EnumSet<LocalFlag> lflag = attr.getLocalFlags();
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOKE, ECHOKE);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOE, ECHOE);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOK, ECHOK);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHO, ECHO);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHONL, ECHONL);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOPRT, ECHOPRT);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ECHOCTL, ECHOCTL);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ISIG, ISIG);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ICANON, ICANON);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.ALTWERASE, ALTWERASE);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.IEXTEN, IEXTEN);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.EXTPROC, EXTPROC);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.TOSTOP, TOSTOP);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.FLUSHO, FLUSHO);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.NOKERNINFO, NOKERNINFO);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.PENDIN, PENDIN);
|
||||
addFlag(c_lflag.longValue(), lflag, LocalFlag.NOFLSH, NOFLSH);
|
||||
// Control chars
|
||||
EnumMap<ControlChar, Integer> 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.VDSUSP, (int) c_cc[VDSUSP]);
|
||||
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]);
|
||||
cc.put(ControlChar.VSTATUS, (int) c_cc[VSTATUS]);
|
||||
// Return
|
||||
return attr;
|
||||
}
|
||||
|
||||
private <T extends Enum<T>> void addFlag(long value, EnumSet<T> flags, T flag, int v) {
|
||||
if ((value & v) != 0) {
|
||||
flags.add(flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CONSTANTS
|
||||
|
||||
long TIOCGWINSZ = 0x40087468L;
|
||||
long TIOCSWINSZ = 0x80087467L;
|
||||
|
||||
int TCSANOW = 0x00000000;
|
||||
|
||||
int VEOF = 0;
|
||||
int VEOL = 1;
|
||||
int VEOL2 = 2;
|
||||
int VERASE = 3;
|
||||
int VWERASE = 4;
|
||||
int VKILL = 5;
|
||||
int VREPRINT = 6;
|
||||
int VINTR = 8;
|
||||
int VQUIT = 9;
|
||||
int VSUSP = 10;
|
||||
int VDSUSP = 11;
|
||||
int VSTART = 12;
|
||||
int VSTOP = 13;
|
||||
int VLNEXT = 14;
|
||||
int VDISCARD = 15;
|
||||
int VMIN = 16;
|
||||
int VTIME = 17;
|
||||
int VSTATUS = 18;
|
||||
|
||||
int IGNBRK = 0x00000001;
|
||||
int BRKINT = 0x00000002;
|
||||
int IGNPAR = 0x00000004;
|
||||
int PARMRK = 0x00000008;
|
||||
int INPCK = 0x00000010;
|
||||
int ISTRIP = 0x00000020;
|
||||
int INLCR = 0x00000040;
|
||||
int IGNCR = 0x00000080;
|
||||
int ICRNL = 0x00000100;
|
||||
int IXON = 0x00000200;
|
||||
int IXOFF = 0x00000400;
|
||||
int IXANY = 0x00000800;
|
||||
int IMAXBEL = 0x00002000;
|
||||
int IUTF8 = 0x00004000;
|
||||
|
||||
int OPOST = 0x00000001;
|
||||
int ONLCR = 0x00000002;
|
||||
int OXTABS = 0x00000004;
|
||||
int ONOEOT = 0x00000008;
|
||||
int OCRNL = 0x00000010;
|
||||
int ONOCR = 0x00000020;
|
||||
int ONLRET = 0x00000040;
|
||||
int OFILL = 0x00000080;
|
||||
int NLDLY = 0x00000300;
|
||||
int TABDLY = 0x00000c04;
|
||||
int CRDLY = 0x00003000;
|
||||
int FFDLY = 0x00004000;
|
||||
int BSDLY = 0x00008000;
|
||||
int VTDLY = 0x00010000;
|
||||
int OFDEL = 0x00020000;
|
||||
|
||||
int CIGNORE = 0x00000001;
|
||||
int CS5 = 0x00000000;
|
||||
int CS6 = 0x00000100;
|
||||
int CS7 = 0x00000200;
|
||||
int CS8 = 0x00000300;
|
||||
int CSTOPB = 0x00000400;
|
||||
int CREAD = 0x00000800;
|
||||
int PARENB = 0x00001000;
|
||||
int PARODD = 0x00002000;
|
||||
int HUPCL = 0x00004000;
|
||||
int CLOCAL = 0x00008000;
|
||||
int CCTS_OFLOW = 0x00010000;
|
||||
int CRTS_IFLOW = 0x00020000;
|
||||
int CDTR_IFLOW = 0x00040000;
|
||||
int CDSR_OFLOW = 0x00080000;
|
||||
int CCAR_OFLOW = 0x00100000;
|
||||
|
||||
int ECHOKE = 0x00000001;
|
||||
int ECHOE = 0x00000002;
|
||||
int ECHOK = 0x00000004;
|
||||
int ECHO = 0x00000008;
|
||||
int ECHONL = 0x00000010;
|
||||
int ECHOPRT = 0x00000020;
|
||||
int ECHOCTL = 0x00000040;
|
||||
int ISIG = 0x00000080;
|
||||
int ICANON = 0x00000100;
|
||||
int ALTWERASE = 0x00000200;
|
||||
int IEXTEN = 0x00000400;
|
||||
int EXTPROC = 0x00000800;
|
||||
int TOSTOP = 0x00400000;
|
||||
int FLUSHO = 0x00800000;
|
||||
int NOKERNINFO = 0x02000000;
|
||||
int PENDIN = 0x20000000;
|
||||
int NOFLSH = 0x80000000;
|
||||
|
||||
}
|
@ -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.osx;
|
||||
|
||||
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, NativeLong cmd, winsize data) throws LastErrorException {
|
||||
if (cmd.longValue() == CLibrary.TIOCGWINSZ || cmd.longValue() == CLibrary.TIOCSWINSZ) {
|
||||
ioctl0(fd, cmd.longValue(), 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, termios t, winsize s) throws LastErrorException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.osx;
|
||||
|
||||
class NativeLong {
|
||||
|
||||
public long value;
|
||||
|
||||
public NativeLong(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void setValue(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2020, the original author or authors.
|
||||
*
|
||||
* 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.osx;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
|
||||
//import com.sun.jna.Native;
|
||||
//import com.sun.jna.NativeLong;
|
||||
//import com.sun.jna.Platform;
|
||||
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 static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.TCSANOW;
|
||||
import static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.TIOCGWINSZ;
|
||||
import static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.TIOCSWINSZ;
|
||||
import static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.termios;
|
||||
import static jdk.internal.org.jline.terminal.impl.jna.osx.CLibrary.winsize;
|
||||
|
||||
public class OsXNativePty extends JnaNativePty {
|
||||
|
||||
// private static final CLibrary C_LIBRARY = Native.load(Platform.C_LIBRARY_NAME, CLibrary.class);
|
||||
private static final CLibrary C_LIBRARY = new CLibraryImpl();//Native.load(Platform.C_LIBRARY_NAME, CLibrary.class);
|
||||
|
||||
public static OsXNativePty current(TerminalProvider.Stream consoleStream) throws IOException {
|
||||
switch (consoleStream) {
|
||||
case Output:
|
||||
return new OsXNativePty(-1, null, 0, FileDescriptor.in, 1, FileDescriptor.out, ttyname(0));
|
||||
case Error:
|
||||
return new OsXNativePty(-1, null, 0, FileDescriptor.in, 2, FileDescriptor.err, ttyname(0));
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream);
|
||||
}
|
||||
}
|
||||
|
||||
public static OsXNativePty 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 OsXNativePty(master[0], newDescriptor(master[0]), slave[0], newDescriptor(slave[0]), name);
|
||||
}
|
||||
|
||||
public OsXNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, String name) {
|
||||
super(master, masterFD, slave, slaveFD, name);
|
||||
}
|
||||
|
||||
public OsXNativePty(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(), new NativeLong(TIOCGWINSZ), sz);
|
||||
return sz.toSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(Size size) throws IOException {
|
||||
winsize sz = new winsize(size);
|
||||
C_LIBRARY.ioctl(getSlave(), new NativeLong(TIOCSWINSZ), sz);
|
||||
}
|
||||
|
||||
public static int isatty(int fd) {
|
||||
return C_LIBRARY.isatty(fd);
|
||||
}
|
||||
|
||||
public static String ttyname(int fd) {
|
||||
byte[] buf = new byte[64];
|
||||
C_LIBRARY.ttyname_r(fd, buf, buf.length);
|
||||
int len = 0;
|
||||
while (buf[len] != 0) {
|
||||
len++;
|
||||
}
|
||||
return new String(buf, 0, len);
|
||||
}
|
||||
}
|
210
src/jdk.internal.le/macosx/native/lible/CLibrary.cpp
Normal file
210
src/jdk.internal.le/macosx/native/lible/CLibrary.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* 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_osx_CLibraryImpl.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
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 jfieldID c_ispeed;
|
||||
static jfieldID c_ospeed;
|
||||
|
||||
static jclass winsize_j;
|
||||
static jfieldID ws_row;
|
||||
static jfieldID ws_col;
|
||||
static jfieldID ws_xpixel;
|
||||
static jfieldID ws_ypixel;
|
||||
|
||||
static jclass nativelong_j;
|
||||
static jfieldID nativelong_value;
|
||||
|
||||
static void throw_errno(JNIEnv *env);
|
||||
|
||||
JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_initIDs
|
||||
(JNIEnv *env, jclass) {
|
||||
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, "<init>", "(J)V");
|
||||
CHECK_NULL(lastErrorExceptionConstructor);
|
||||
|
||||
cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/osx/CLibrary$termios");
|
||||
CHECK_NULL(cls);
|
||||
termios_j = (jclass) env->NewGlobalRef(cls);
|
||||
CHECK_NULL(termios_j);
|
||||
c_iflag = env->GetFieldID(termios_j, "c_iflag", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;");
|
||||
CHECK_NULL(c_iflag);
|
||||
c_oflag = env->GetFieldID(termios_j, "c_oflag", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;");
|
||||
CHECK_NULL(c_oflag);
|
||||
c_cflag = env->GetFieldID(termios_j, "c_cflag", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;");
|
||||
CHECK_NULL(c_cflag);
|
||||
c_lflag = env->GetFieldID(termios_j, "c_lflag", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;");
|
||||
CHECK_NULL(c_lflag);
|
||||
c_cc = env->GetFieldID(termios_j, "c_cc", "[B");
|
||||
CHECK_NULL(c_cc);
|
||||
c_ispeed = env->GetFieldID(termios_j, "c_ispeed", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;");
|
||||
CHECK_NULL(c_ispeed);
|
||||
c_ospeed = env->GetFieldID(termios_j, "c_ospeed", "Ljdk/internal/org/jline/terminal/impl/jna/osx/NativeLong;");
|
||||
CHECK_NULL(c_ospeed);
|
||||
|
||||
cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/osx/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);
|
||||
|
||||
nativelong_j = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/osx/NativeLong");
|
||||
CHECK_NULL(nativelong_j);
|
||||
nativelong_value = env->GetFieldID(nativelong_j, "value", "J");
|
||||
CHECK_NULL(nativelong_value);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_tcgetattr
|
||||
(JNIEnv *env, jobject, jint fd, jobject result) {
|
||||
termios data;
|
||||
|
||||
if (tcgetattr(fd, &data) != 0) {
|
||||
throw_errno(env);
|
||||
return ;
|
||||
}
|
||||
|
||||
env->SetLongField(env->GetObjectField(result, c_iflag), nativelong_value, data.c_iflag);
|
||||
env->SetLongField(env->GetObjectField(result, c_oflag), nativelong_value, data.c_oflag);
|
||||
env->SetLongField(env->GetObjectField(result, c_cflag), nativelong_value, data.c_cflag);
|
||||
env->SetLongField(env->GetObjectField(result, c_lflag), nativelong_value, data.c_lflag);
|
||||
jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(result, c_cc);
|
||||
env->SetByteArrayRegion(c_ccValue, 0, NCCS, (signed char *) data.c_cc);
|
||||
env->SetLongField(env->GetObjectField(result, c_ispeed), nativelong_value, data.c_ispeed);
|
||||
env->SetLongField(env->GetObjectField(result, c_ospeed), nativelong_value, data.c_ospeed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl
|
||||
* Method: tcsetattr
|
||||
* Signature: (IILjdk/internal/org/jline/terminal/impl/jna/osx/CLibrary/termios;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_tcsetattr
|
||||
(JNIEnv *env, jobject, jint fd, jint cmd, jobject input) {
|
||||
termios data;
|
||||
|
||||
data.c_iflag = env->GetLongField(env->GetObjectField(input, c_iflag), nativelong_value);
|
||||
data.c_oflag = env->GetLongField(env->GetObjectField(input, c_oflag), nativelong_value);
|
||||
data.c_cflag = env->GetLongField(env->GetObjectField(input, c_cflag), nativelong_value);
|
||||
data.c_lflag = env->GetLongField(env->GetObjectField(input, c_lflag), nativelong_value);
|
||||
jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(input, c_cc);
|
||||
env->GetByteArrayRegion(c_ccValue, 0, NCCS, (jbyte *) data.c_cc);
|
||||
data.c_ispeed = env->GetLongField(env->GetObjectField(input, c_ispeed), nativelong_value);
|
||||
data.c_ospeed = env->GetLongField(env->GetObjectField(input, c_ospeed), nativelong_value);
|
||||
|
||||
if (tcsetattr(fd, cmd, &data) != 0) {
|
||||
throw_errno(env);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl
|
||||
* Method: ioctl0
|
||||
* Signature: (IILjdk/internal/org/jline/terminal/impl/jna/osx/CLibrary/winsize;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_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_osx_CLibraryImpl
|
||||
* Method: isatty
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl_isatty
|
||||
(JNIEnv *, jobject, jint fd) {
|
||||
return isatty(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: jdk_internal_org_jline_terminal_impl_jna_osx_CLibraryImpl
|
||||
* Method: ttyname_r
|
||||
* Signature: (I[BI)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_osx_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);
|
||||
}
|
@ -49,7 +49,17 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
||||
*/
|
||||
@Override
|
||||
public JdkConsole console(boolean isTTY, Charset charset) {
|
||||
return new JdkConsoleImpl(charset);
|
||||
try {
|
||||
Terminal terminal = TerminalBuilder.builder().encoding(charset)
|
||||
.exec(false).build();
|
||||
return new JdkConsoleImpl(terminal);
|
||||
} catch (IllegalStateException ise) {
|
||||
//cannot create a non-dumb, non-exec terminal,
|
||||
//use the standard Console:
|
||||
return null;
|
||||
} catch (IOException ioe) {
|
||||
throw new UncheckedIOException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,13 +129,9 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
||||
private final LineReader jline;
|
||||
private final Terminal terminal;
|
||||
|
||||
public JdkConsoleImpl(Charset charset) {
|
||||
try {
|
||||
terminal = TerminalBuilder.builder().encoding(charset).build();
|
||||
jline = LineReaderBuilder.builder().terminal(terminal).build();
|
||||
} catch (IOException ioe) {
|
||||
throw new UncheckedIOException(ioe);
|
||||
}
|
||||
public JdkConsoleImpl(Terminal terminal) {
|
||||
this.terminal = terminal;
|
||||
this.jline = LineReaderBuilder.builder().terminal(terminal).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
@ -22,10 +22,10 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl.jna.win;
|
||||
package jdk.internal.org.jline.terminal.impl.jna;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class LastErrorException extends RuntimeException{
|
||||
public class LastErrorException extends RuntimeException{
|
||||
|
||||
public final long lastError;
|
||||
|
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2020, the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
//import com.sun.jna.Platform;
|
||||
import jdk.internal.org.jline.terminal.Attributes;
|
||||
import jdk.internal.org.jline.terminal.Size;
|
||||
import jdk.internal.org.jline.terminal.impl.AbstractPty;
|
||||
import jdk.internal.org.jline.terminal.spi.TerminalProvider;
|
||||
import jdk.internal.org.jline.terminal.spi.Pty;
|
||||
//import jdk.internal.org.jline.terminal.impl.jna.freebsd.FreeBsdNativePty;
|
||||
//import jdk.internal.org.jline.terminal.impl.jna.linux.LinuxNativePty;
|
||||
//import jdk.internal.org.jline.terminal.impl.jna.osx.OsXNativePty;
|
||||
//import jdk.internal.org.jline.terminal.impl.jna.solaris.SolarisNativePty;
|
||||
|
||||
public abstract class JnaNativePty extends AbstractPty implements Pty {
|
||||
|
||||
private final int master;
|
||||
private final int slave;
|
||||
private final int slaveOut;
|
||||
private final String name;
|
||||
private final FileDescriptor masterFD;
|
||||
private final FileDescriptor slaveFD;
|
||||
private final FileDescriptor slaveOutFD;
|
||||
|
||||
public static JnaNativePty current(TerminalProvider.Stream console) throws IOException {
|
||||
// if (Platform.isMac()) {
|
||||
// if (Platform.is64Bit() && Platform.isARM()) {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
// return OsXNativePty.current(console);
|
||||
// } else if (Platform.isLinux()) {
|
||||
// return LinuxNativePty.current(console);
|
||||
// } else if (Platform.isSolaris()) {
|
||||
// return SolarisNativePty.current(console);
|
||||
// } else if (Platform.isFreeBSD()) {
|
||||
// return FreeBsdNativePty.current(console);
|
||||
// } else {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
return JDKNativePty.current(console);
|
||||
}
|
||||
|
||||
public static JnaNativePty open(Attributes attr, Size size) throws IOException {
|
||||
// if (Platform.isMac()) {
|
||||
// return OsXNativePty.open(attr, size);
|
||||
// } else if (Platform.isLinux()) {
|
||||
// return LinuxNativePty.open(attr, size);
|
||||
// } else if (Platform.isSolaris()) {
|
||||
// return SolarisNativePty.open(attr, size);
|
||||
// } else if (Platform.isFreeBSD()) {
|
||||
// return FreeBsdNativePty.open(attr, size);
|
||||
// } else {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
return JDKNativePty.open(attr, size);
|
||||
}
|
||||
|
||||
protected JnaNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, String name) {
|
||||
this(master, masterFD, slave, slaveFD, slave, slaveFD, name);
|
||||
}
|
||||
|
||||
protected JnaNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, int slaveOut, FileDescriptor slaveOutFD, String name) {
|
||||
this.master = master;
|
||||
this.slave = slave;
|
||||
this.slaveOut = slaveOut;
|
||||
this.name = name;
|
||||
this.masterFD = masterFD;
|
||||
this.slaveFD = slaveFD;
|
||||
this.slaveOutFD = slaveOutFD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (master > 0) {
|
||||
getMasterInput().close();
|
||||
}
|
||||
if (slave > 0) {
|
||||
getSlaveInput().close();
|
||||
}
|
||||
}
|
||||
|
||||
public int getMaster() {
|
||||
return master;
|
||||
}
|
||||
|
||||
public int getSlave() {
|
||||
return slave;
|
||||
}
|
||||
|
||||
public int getSlaveOut() {
|
||||
return slaveOut;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public FileDescriptor getMasterFD() {
|
||||
return masterFD;
|
||||
}
|
||||
|
||||
public FileDescriptor getSlaveFD() {
|
||||
return slaveFD;
|
||||
}
|
||||
|
||||
public FileDescriptor getSlaveOutFD() {
|
||||
return slaveOutFD;
|
||||
}
|
||||
|
||||
public InputStream getMasterInput() {
|
||||
return new FileInputStream(getMasterFD());
|
||||
}
|
||||
|
||||
public OutputStream getMasterOutput() {
|
||||
return new FileOutputStream(getMasterFD());
|
||||
}
|
||||
|
||||
protected InputStream doGetSlaveInput() {
|
||||
return new FileInputStream(getSlaveFD());
|
||||
}
|
||||
|
||||
public OutputStream getSlaveOutput() {
|
||||
return new FileOutputStream(getSlaveOutFD());
|
||||
}
|
||||
|
||||
protected static FileDescriptor newDescriptor(int fd) {
|
||||
try {
|
||||
Constructor<FileDescriptor> cns = FileDescriptor.class.getDeclaredConstructor(int.class);
|
||||
cns.setAccessible(true);
|
||||
return cns.newInstance(fd);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException("Unable to create FileDescriptor", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JnaNativePty[" + getName() + "]";
|
||||
}
|
||||
|
||||
public static boolean isPosixSystemStream(TerminalProvider.Stream stream) {
|
||||
switch (stream) {
|
||||
case Input: return isatty(0);
|
||||
case Output: return isatty(1);
|
||||
case Error: return isatty(2);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String posixSystemStreamName(TerminalProvider.Stream stream) {
|
||||
switch (stream) {
|
||||
case Input: return ttyname(0);
|
||||
case Output: return ttyname(1);
|
||||
case Error: return ttyname(2);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isatty(int fd) {
|
||||
// if (Platform.isMac()) {
|
||||
// return OsXNativePty.isatty(fd) == 1;
|
||||
// } else if (Platform.isLinux()) {
|
||||
// return LinuxNativePty.isatty(fd) == 1;
|
||||
// } else if (Platform.isSolaris()) {
|
||||
// return SolarisNativePty.isatty(fd) == 1;
|
||||
// } else if (Platform.isFreeBSD()) {
|
||||
// return FreeBsdNativePty.isatty(fd) == 1;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
return JDKNativePty.isatty(fd) == 1;
|
||||
}
|
||||
|
||||
private static String ttyname(int fd) {
|
||||
// if (Platform.isMac()) {
|
||||
// return OsXNativePty.ttyname(fd);
|
||||
// } else if (Platform.isLinux()) {
|
||||
// return LinuxNativePty.ttyname(fd);
|
||||
// } else if (Platform.isSolaris()) {
|
||||
// return SolarisNativePty.ttyname(fd);
|
||||
// } else if (Platform.isFreeBSD()) {
|
||||
// return FreeBsdNativePty.ttyname(fd);
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
return JDKNativePty.ttyname(fd);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2020, the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import jdk.internal.org.jline.terminal.Attributes;
|
||||
import jdk.internal.org.jline.terminal.Size;
|
||||
import jdk.internal.org.jline.terminal.Terminal;
|
||||
import jdk.internal.org.jline.terminal.impl.PosixPtyTerminal;
|
||||
import jdk.internal.org.jline.terminal.impl.PosixSysTerminal;
|
||||
//import jdk.internal.org.jline.terminal.impl.jna.win.JnaWinSysTerminal;
|
||||
import jdk.internal.org.jline.terminal.spi.TerminalProvider;
|
||||
import jdk.internal.org.jline.terminal.spi.Pty;
|
||||
import jdk.internal.org.jline.utils.OSUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class JnaTerminalProvider implements TerminalProvider
|
||||
{
|
||||
@Override
|
||||
public String name() {
|
||||
return "jna";
|
||||
}
|
||||
|
||||
public Pty current(TerminalProvider.Stream console) throws IOException {
|
||||
return JnaNativePty.current(console);
|
||||
}
|
||||
|
||||
public Pty open(Attributes attributes, Size size) throws IOException {
|
||||
return JnaNativePty.open(attributes, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Terminal sysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
|
||||
boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
|
||||
Stream consoleStream, Function<InputStream, InputStream> inputStreamWrapper) throws IOException {
|
||||
// if (OSUtils.IS_WINDOWS) {
|
||||
// return winSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream );
|
||||
// } else {
|
||||
return posixSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper );
|
||||
// }
|
||||
}
|
||||
|
||||
// public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
|
||||
// boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
|
||||
// Stream console, Function<InputStream, InputStream> inputStreamWrapper) throws IOException {
|
||||
// return JnaWinSysTerminal.createTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, console);
|
||||
// }
|
||||
//
|
||||
public Terminal posixSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
|
||||
boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
|
||||
Stream consoleStream, Function<InputStream, InputStream> inputStreamWrapper) throws IOException {
|
||||
// Pty pty = jdk.internal.org.jline.terminal.impl.ExecPty.current(consoleStream);
|
||||
Pty pty = current(consoleStream);
|
||||
return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler, inputStreamWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Terminal newTerminal(String name, String type, InputStream in, OutputStream out,
|
||||
Charset encoding, Terminal.SignalHandler signalHandler, boolean paused,
|
||||
Attributes attributes, Size size) throws IOException
|
||||
{
|
||||
Pty pty = open(attributes, size);
|
||||
return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler, paused);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSystemStream(Stream stream) {
|
||||
try {
|
||||
// if (OSUtils.IS_WINDOWS) {
|
||||
// return isWindowsSystemStream(stream);
|
||||
// } else {
|
||||
return isPosixSystemStream(stream);
|
||||
// }
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// public boolean isWindowsSystemStream(Stream stream) {
|
||||
// return JnaWinSysTerminal.isWindowsSystemStream(stream);
|
||||
// }
|
||||
|
||||
public boolean isPosixSystemStream(Stream stream) {
|
||||
return JnaNativePty.isPosixSystemStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String systemStreamName(Stream stream) {
|
||||
if (OSUtils.IS_WINDOWS) {
|
||||
return null;
|
||||
} else {
|
||||
return JnaNativePty.posixSystemStreamName(stream);
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ package jdk.internal.org.jline.terminal.impl.jna.win;
|
||||
//import com.sun.jna.Pointer;
|
||||
//import com.sun.jna.ptr.IntByReference;
|
||||
import jdk.internal.org.jline.terminal.impl.AbstractWindowsConsoleWriter;
|
||||
import jdk.internal.org.jline.terminal.impl.jna.LastErrorException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -22,6 +22,7 @@ import java.util.function.IntConsumer;
|
||||
import jdk.internal.org.jline.terminal.Cursor;
|
||||
import jdk.internal.org.jline.terminal.Size;
|
||||
import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal;
|
||||
import jdk.internal.org.jline.terminal.impl.jna.LastErrorException;
|
||||
import jdk.internal.org.jline.terminal.spi.TerminalProvider;
|
||||
import jdk.internal.org.jline.utils.InfoCmp;
|
||||
import jdk.internal.org.jline.utils.OSUtils;
|
||||
|
@ -22,6 +22,7 @@ package jdk.internal.org.jline.terminal.impl.jna.win;
|
||||
//import com.sun.jna.ptr.IntByReference;
|
||||
//import com.sun.jna.win32.StdCallLibrary;
|
||||
//import com.sun.jna.win32.W32APIOptions;
|
||||
import jdk.internal.org.jline.terminal.impl.jna.LastErrorException;
|
||||
|
||||
interface Kernel32 {//extends StdCallLibrary {
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl.jna.win;
|
||||
|
||||
import jdk.internal.org.jline.terminal.impl.jna.LastErrorException;
|
||||
import jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CHAR_INFO;
|
||||
import jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.CONSOLE_SCREEN_BUFFER_INFO;
|
||||
import jdk.internal.org.jline.terminal.impl.jna.win.Kernel32.COORD;
|
||||
|
@ -141,7 +141,7 @@ JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_win_Kernel3
|
||||
pointerValue = env->GetFieldID(cls, "value", "J");
|
||||
CHECK_NULL(pointerValue);
|
||||
|
||||
cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/win/LastErrorException");
|
||||
cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/LastErrorException");
|
||||
CHECK_NULL(cls);
|
||||
lastErrorExceptionClass = (jclass) env->NewGlobalRef(cls);
|
||||
lastErrorExceptionConstructor = env->GetMethodID(cls, "<init>", "(J)V");
|
||||
|
Loading…
Reference in New Issue
Block a user