summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Wright <michaelwr@google.com>2013-02-20 20:22:41 -0800
committerMichael Wright <michaelwr@google.com>2013-02-20 21:13:07 -0800
commita36312d9912f701dd1dbf0b3d35b198bb5f4ab2f (patch)
tree90b0c2461afb3495ad55495bfd89034f161c1a58
parent410e0da343fd581f3112037deb475db9fb0da850 (diff)
downloadandroid_packages_apps_Terminal-a36312d9912f701dd1dbf0b3d35b198bb5f4ab2f.tar.gz
android_packages_apps_Terminal-a36312d9912f701dd1dbf0b3d35b198bb5f4ab2f.tar.bz2
android_packages_apps_Terminal-a36312d9912f701dd1dbf0b3d35b198bb5f4ab2f.zip
Add forkpty function
Change-Id: I2eaac8c2c5c50f870a5a56806d0fd19dc5f386a1
-rw-r--r--jni/Android.mk3
-rw-r--r--jni/forkpty.cpp83
-rw-r--r--jni/forkpty.h21
3 files changed, 106 insertions, 1 deletions
diff --git a/jni/Android.mk b/jni/Android.mk
index 3c8e5f3..808b4c4 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -4,7 +4,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
jni_init.cpp \
- com_android_terminal_Terminal.cpp
+ com_android_terminal_Terminal.cpp \
+ forkpty.cpp
LOCAL_C_INCLUDES += \
external/libvterm/include \
diff --git a/jni/forkpty.cpp b/jni/forkpty.cpp
new file mode 100644
index 0000000..7feb307
--- /dev/null
+++ b/jni/forkpty.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "forkpty"
+
+#include <utils/Log.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "forkpty.h"
+
+pid_t forkpty(int *master, int *slave, const struct termios *termp,
+ const struct winsize *winp) {
+ int ptm = open("/dev/ptmx", O_RDWR);
+ if (ptm < 0) {
+ ALOGE("cannot open /dev/ptmx - %s", strerror(errno));
+ return -1;
+ }
+ fcntl(ptm, F_SETFD, FD_CLOEXEC);
+
+ char *devname;
+ if (grantpt(ptm) || unlockpt(ptm) || ((devname = (char *) ptsname(ptm)) == 0)) {
+ ALOGE("error opening pty - %s", strerror(errno));
+ return -1;
+ }
+
+ int pts = open(devname, O_RDWR);
+ if (pts < 0) {
+ ALOGE("unable to open slave pty - %s", strerror(errno));
+ return -1;
+ }
+
+ if (termp) {
+ tcsetattr(pts, TCSAFLUSH, termp);
+ }
+
+ if (winp) {
+ ioctl(pts, TIOCSWINSZ, winp);
+ }
+
+ pid_t pid = fork();
+
+ if (pid < 0) {
+ ALOGE("fork failed - %s", strerror(errno));
+ return -1;
+ }
+
+ if (pid == 0) {
+ setsid();
+ if (ioctl(pts, TIOCSCTTY, (char *)NULL) == -1) exit(-1);
+ dup2(pts, STDIN_FILENO);
+ dup2(pts, STDOUT_FILENO);
+ dup2(pts, STDERR_FILENO);
+ if (pts > 2) {
+ close(pts);
+ }
+ } else {
+ *master = ptm;
+ if (slave) {
+ *slave = pts;
+ }
+ }
+ return pid;
+}
+
diff --git a/jni/forkpty.h b/jni/forkpty.h
new file mode 100644
index 0000000..6b4da38
--- /dev/null
+++ b/jni/forkpty.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <termios.h>
+#include <unistd.h>
+
+pid_t forkpty(int *master, int *slave, const struct termios *termp,
+ const struct winsize *winp);