blob: 3bc481f4afaa53a3e5a9ae4b35a562d2cf19a73b [file] [log] [blame]
/*
* 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->GetShortField(data, ws_row);
ws.ws_col = env->GetShortField(data, ws_col);
ws.ws_xpixel = env->GetShortField(data, ws_xpixel);
ws.ws_ypixel = env->GetShortField(data, ws_ypixel);
if (ioctl(fd, cmd, &ws) != 0) {
throw_errno(env);
return ;
}
env->SetShortField(data, ws_row, ws.ws_row);
env->SetShortField(data, ws_col, ws.ws_col);
env->SetShortField(data, ws_xpixel, ws.ws_xpixel);
env->SetShortField(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) {
delete[] data;
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);
}