Skip to content

Commit 6405180

Browse files
committed
Wait for terminal size before starting process
This fixes termux/termux-widget#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.
1 parent 1b6919b commit 6405180

File tree

6 files changed

+45
-15
lines changed

6 files changed

+45
-15
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Released under [the GPLv3 license](https://www.gnu.org/licenses/gpl.html). Conta
2020

2121
Building JNI libraries
2222
======================
23-
For ease of use, the JNI libraries are checked into version control. Execute the `build-jnilibs.sh` script to rebuild them.
23+
Execute the `build-jnilibs.sh` script to build the required JNI libraries.
2424

2525
Terminal resources
2626
==================

app/src/main/java/com/termux/terminal/JNI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ final class JNI {
2828
* @return the file descriptor resulting from opening /dev/ptmx master device. The sub process will have opened the
2929
* slave device counterpart (/dev/pts/$N) and have it as stdint, stdout and stderr.
3030
*/
31-
public static native int createSubprocess(String cmd, String cwd, String[] args, String[] envVars, int[] processId);
31+
public static native int createSubprocess(String cmd, String cwd, String[] args, String[] envVars, int[] processId, int rows, int columns);
3232

3333
/** Set the window size for a given pty, which allows connected programs to learn how large their screen is. */
3434
public static native void setPtyWindowSize(int fd, int rows, int cols);

app/src/main/java/com/termux/terminal/TerminalSession.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,17 @@ private static FileDescriptor wrapFileDescriptor(int fileDescriptor) {
8282
/** Callback which gets notified when a session finishes or changes title. */
8383
final SessionChangedCallback mChangeCallback;
8484

85-
/** The pid of the shell process or -1 if not running. */
85+
/** The pid of the shell process. 0 if not started and -1 if finished running. */
8686
int mShellPid;
87-
int mShellExitStatus = -1;
87+
88+
/** The exit status of the shell process. Only valid if ${@link #mShellPid} is -1. */
89+
int mShellExitStatus;
90+
8891
/**
8992
* The file descriptor referencing the master half of a pseudo-terminal pair, resulting from calling
9093
* {@link JNI#createSubprocess(String, String, String[], String[], int[])}.
9194
*/
92-
final int mTerminalFileDescriptor;
95+
private int mTerminalFileDescriptor;
9396

9497
/** Set by the application for user identification of session, not by terminal. */
9598
public String mSessionName;
@@ -128,20 +131,26 @@ public void handleMessage(Message msg) {
128131
}
129132
};
130133

134+
private final String mShellPath;
135+
private final String mCwd;
136+
private final String[] mArgs;
137+
private final String[] mEnv;
138+
131139
public TerminalSession(String shellPath, String cwd, String[] args, String[] env, SessionChangedCallback changeCallback) {
132140
mChangeCallback = changeCallback;
133141

134-
int[] processId = new int[1];
135-
mTerminalFileDescriptor = JNI.createSubprocess(shellPath, cwd, args, env, processId);
136-
mShellPid = processId[0];
142+
this.mShellPath = shellPath;
143+
this.mCwd = cwd;
144+
this.mArgs = args;
145+
this.mEnv = env;
137146
}
138147

139148
/** Inform the attached pty of the new size and reflow or initialize the emulator. */
140149
public void updateSize(int columns, int rows) {
141-
JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns);
142150
if (mEmulator == null) {
143151
initializeEmulator(columns, rows);
144152
} else {
153+
JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns);
145154
mEmulator.resize(columns, rows);
146155
}
147156
}
@@ -161,6 +170,11 @@ public String getTitle() {
161170
*/
162171
public void initializeEmulator(int columns, int rows) {
163172
mEmulator = new TerminalEmulator(this, columns, rows, /* transcript= */5000);
173+
174+
int[] processId = new int[1];
175+
mTerminalFileDescriptor = JNI.createSubprocess(mShellPath, mCwd, mArgs, mEnv, processId, rows, columns);
176+
mShellPid = processId[0];
177+
164178
final FileDescriptor terminalFileDescriptorWrapped = wrapFileDescriptor(mTerminalFileDescriptor);
165179

166180
new Thread("TermSessionInputReader[pid=" + mShellPid + "]") {
@@ -204,7 +218,7 @@ public void run() {
204218
/** Write data to the shell process. */
205219
@Override
206220
public void write(byte[] data, int offset, int count) {
207-
mTerminalToProcessIOQueue.write(data, offset, count);
221+
if (mShellPid > 0) mTerminalToProcessIOQueue.write(data, offset, count);
208222
}
209223

210224
/** Write the Unicode code point to the terminal encoded in UTF-8. */

app/src/main/jni/termux.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,14 @@ static int throw_runtime_exception(JNIEnv* env, char const* message)
2222
return -1;
2323
}
2424

25-
static int create_subprocess(JNIEnv* env, char const* cmd, char const* cwd, char* const argv[], char** envp, int* pProcessId)
25+
static int create_subprocess(JNIEnv* env,
26+
char const* cmd,
27+
char const* cwd,
28+
char* const argv[],
29+
char** envp,
30+
int* pProcessId,
31+
jint rows,
32+
jint columns)
2633
{
2734
int ptm = open("/dev/ptmx", O_RDWR | O_CLOEXEC);
2835
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
4956
tios.c_iflag &= ~(IXON | IXOFF);
5057
tcsetattr(ptm, TCSANOW, &tios);
5158

52-
/** Set initial winsize (better too small than too large). */
53-
struct winsize sz = { .ws_row = 20, .ws_col = 20 };
59+
/** Set initial winsize. */
60+
struct winsize sz = { .ws_row = rows, .ws_col = columns };
5461
ioctl(ptm, TIOCSWINSZ, &sz);
5562

5663
pid_t pid = fork();
@@ -105,7 +112,16 @@ static int create_subprocess(JNIEnv* env, char const* cmd, char const* cwd, char
105112
}
106113
}
107114

108-
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)
115+
JNIEXPORT jint JNICALL Java_com_termux_terminal_JNI_createSubprocess(
116+
JNIEnv* env,
117+
jclass TERMUX_UNUSED(clazz),
118+
jstring cmd,
119+
jstring cwd,
120+
jobjectArray args,
121+
jobjectArray envVars,
122+
jintArray processIdArray,
123+
jint rows,
124+
jint columns)
109125
{
110126
jsize size = args ? (*env)->GetArrayLength(env, args) : 0;
111127
char** argv = NULL;
@@ -140,7 +156,7 @@ JNIEXPORT jint JNICALL Java_com_termux_terminal_JNI_createSubprocess(JNIEnv* env
140156
int procId = 0;
141157
char const* cmd_cwd = (*env)->GetStringUTFChars(env, cwd, NULL);
142158
char const* cmd_utf8 = (*env)->GetStringUTFChars(env, cmd, NULL);
143-
int ptm = create_subprocess(env, cmd_utf8, cmd_cwd, argv, envp, &procId);
159+
int ptm = create_subprocess(env, cmd_utf8, cmd_cwd, argv, envp, &procId, rows, columns);
144160
(*env)->ReleaseStringUTFChars(env, cmd, cmd_utf8);
145161
(*env)->ReleaseStringUTFChars(env, cmd, cmd_cwd);
146162

-13 KB
Binary file not shown.

app/src/main/jniLibs/x86/libtermux.so

-8.87 KB
Binary file not shown.

0 commit comments

Comments
 (0)