mirror of https://github.com/termux/termux-app
Wait for terminal size before starting process
This fixes https://github.com/termux/termux-widget/issues/2, which was caused by the terminal launching the terminal session process before the terminal size was known. Also remove the built JNI libraries from source control.
This commit is contained in:
parent
1b6919bb23
commit
6405180cb8
|
@ -20,7 +20,7 @@ Released under [the GPLv3 license](https://www.gnu.org/licenses/gpl.html). Conta
|
|||
|
||||
Building JNI libraries
|
||||
======================
|
||||
For ease of use, the JNI libraries are checked into version control. Execute the `build-jnilibs.sh` script to rebuild them.
|
||||
Execute the `build-jnilibs.sh` script to build the required JNI libraries.
|
||||
|
||||
Terminal resources
|
||||
==================
|
||||
|
|
|
@ -28,7 +28,7 @@ final class JNI {
|
|||
* @return the file descriptor resulting from opening /dev/ptmx master device. The sub process will have opened the
|
||||
* slave device counterpart (/dev/pts/$N) and have it as stdint, stdout and stderr.
|
||||
*/
|
||||
public static native int createSubprocess(String cmd, String cwd, String[] args, String[] envVars, int[] processId);
|
||||
public static native int createSubprocess(String cmd, String cwd, String[] args, String[] envVars, int[] processId, int rows, int columns);
|
||||
|
||||
/** Set the window size for a given pty, which allows connected programs to learn how large their screen is. */
|
||||
public static native void setPtyWindowSize(int fd, int rows, int cols);
|
||||
|
|
|
@ -82,14 +82,17 @@ public final class TerminalSession extends TerminalOutput {
|
|||
/** Callback which gets notified when a session finishes or changes title. */
|
||||
final SessionChangedCallback mChangeCallback;
|
||||
|
||||
/** The pid of the shell process or -1 if not running. */
|
||||
/** The pid of the shell process. 0 if not started and -1 if finished running. */
|
||||
int mShellPid;
|
||||
int mShellExitStatus = -1;
|
||||
|
||||
/** The exit status of the shell process. Only valid if ${@link #mShellPid} is -1. */
|
||||
int mShellExitStatus;
|
||||
|
||||
/**
|
||||
* The file descriptor referencing the master half of a pseudo-terminal pair, resulting from calling
|
||||
* {@link JNI#createSubprocess(String, String, String[], String[], int[])}.
|
||||
*/
|
||||
final int mTerminalFileDescriptor;
|
||||
private int mTerminalFileDescriptor;
|
||||
|
||||
/** Set by the application for user identification of session, not by terminal. */
|
||||
public String mSessionName;
|
||||
|
@ -128,20 +131,26 @@ public final class TerminalSession extends TerminalOutput {
|
|||
}
|
||||
};
|
||||
|
||||
private final String mShellPath;
|
||||
private final String mCwd;
|
||||
private final String[] mArgs;
|
||||
private final String[] mEnv;
|
||||
|
||||
public TerminalSession(String shellPath, String cwd, String[] args, String[] env, SessionChangedCallback changeCallback) {
|
||||
mChangeCallback = changeCallback;
|
||||
|
||||
int[] processId = new int[1];
|
||||
mTerminalFileDescriptor = JNI.createSubprocess(shellPath, cwd, args, env, processId);
|
||||
mShellPid = processId[0];
|
||||
this.mShellPath = shellPath;
|
||||
this.mCwd = cwd;
|
||||
this.mArgs = args;
|
||||
this.mEnv = env;
|
||||
}
|
||||
|
||||
/** Inform the attached pty of the new size and reflow or initialize the emulator. */
|
||||
public void updateSize(int columns, int rows) {
|
||||
JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns);
|
||||
if (mEmulator == null) {
|
||||
initializeEmulator(columns, rows);
|
||||
} else {
|
||||
JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns);
|
||||
mEmulator.resize(columns, rows);
|
||||
}
|
||||
}
|
||||
|
@ -161,6 +170,11 @@ public final class TerminalSession extends TerminalOutput {
|
|||
*/
|
||||
public void initializeEmulator(int columns, int rows) {
|
||||
mEmulator = new TerminalEmulator(this, columns, rows, /* transcript= */5000);
|
||||
|
||||
int[] processId = new int[1];
|
||||
mTerminalFileDescriptor = JNI.createSubprocess(mShellPath, mCwd, mArgs, mEnv, processId, rows, columns);
|
||||
mShellPid = processId[0];
|
||||
|
||||
final FileDescriptor terminalFileDescriptorWrapped = wrapFileDescriptor(mTerminalFileDescriptor);
|
||||
|
||||
new Thread("TermSessionInputReader[pid=" + mShellPid + "]") {
|
||||
|
@ -204,7 +218,7 @@ public final class TerminalSession extends TerminalOutput {
|
|||
/** Write data to the shell process. */
|
||||
@Override
|
||||
public void write(byte[] data, int offset, int count) {
|
||||
mTerminalToProcessIOQueue.write(data, offset, count);
|
||||
if (mShellPid > 0) mTerminalToProcessIOQueue.write(data, offset, count);
|
||||
}
|
||||
|
||||
/** Write the Unicode code point to the terminal encoded in UTF-8. */
|
||||
|
|
|
@ -22,7 +22,14 @@ static int throw_runtime_exception(JNIEnv* env, char const* message)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int create_subprocess(JNIEnv* env, char const* cmd, char const* cwd, char* const argv[], char** envp, int* pProcessId)
|
||||
static int create_subprocess(JNIEnv* env,
|
||||
char const* cmd,
|
||||
char const* cwd,
|
||||
char* const argv[],
|
||||
char** envp,
|
||||
int* pProcessId,
|
||||
jint rows,
|
||||
jint columns)
|
||||
{
|
||||
int ptm = open("/dev/ptmx", O_RDWR | O_CLOEXEC);
|
||||
if (ptm < 0) return throw_runtime_exception(env, "Cannot open /dev/ptmx");
|
||||
|
@ -49,8 +56,8 @@ static int create_subprocess(JNIEnv* env, char const* cmd, char const* cwd, char
|
|||
tios.c_iflag &= ~(IXON | IXOFF);
|
||||
tcsetattr(ptm, TCSANOW, &tios);
|
||||
|
||||
/** Set initial winsize (better too small than too large). */
|
||||
struct winsize sz = { .ws_row = 20, .ws_col = 20 };
|
||||
/** Set initial winsize. */
|
||||
struct winsize sz = { .ws_row = rows, .ws_col = columns };
|
||||
ioctl(ptm, TIOCSWINSZ, &sz);
|
||||
|
||||
pid_t pid = fork();
|
||||
|
@ -105,7 +112,16 @@ static int create_subprocess(JNIEnv* env, char const* cmd, char const* cwd, char
|
|||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_termux_terminal_JNI_createSubprocess(JNIEnv* env, jclass TERMUX_UNUSED(clazz), jstring cmd, jstring cwd, jobjectArray args, jobjectArray envVars, jintArray processIdArray)
|
||||
JNIEXPORT jint JNICALL Java_com_termux_terminal_JNI_createSubprocess(
|
||||
JNIEnv* env,
|
||||
jclass TERMUX_UNUSED(clazz),
|
||||
jstring cmd,
|
||||
jstring cwd,
|
||||
jobjectArray args,
|
||||
jobjectArray envVars,
|
||||
jintArray processIdArray,
|
||||
jint rows,
|
||||
jint columns)
|
||||
{
|
||||
jsize size = args ? (*env)->GetArrayLength(env, args) : 0;
|
||||
char** argv = NULL;
|
||||
|
@ -140,7 +156,7 @@ JNIEXPORT jint JNICALL Java_com_termux_terminal_JNI_createSubprocess(JNIEnv* env
|
|||
int procId = 0;
|
||||
char const* cmd_cwd = (*env)->GetStringUTFChars(env, cwd, NULL);
|
||||
char const* cmd_utf8 = (*env)->GetStringUTFChars(env, cmd, NULL);
|
||||
int ptm = create_subprocess(env, cmd_utf8, cmd_cwd, argv, envp, &procId);
|
||||
int ptm = create_subprocess(env, cmd_utf8, cmd_cwd, argv, envp, &procId, rows, columns);
|
||||
(*env)->ReleaseStringUTFChars(env, cmd, cmd_utf8);
|
||||
(*env)->ReleaseStringUTFChars(env, cmd, cmd_cwd);
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue