diff options
author | Michael Wright <michaelwr@google.com> | 2013-02-20 20:22:41 -0800 |
---|---|---|
committer | Michael Wright <michaelwr@google.com> | 2013-02-20 21:13:07 -0800 |
commit | a36312d9912f701dd1dbf0b3d35b198bb5f4ab2f (patch) | |
tree | 90b0c2461afb3495ad55495bfd89034f161c1a58 /jni | |
parent | 410e0da343fd581f3112037deb475db9fb0da850 (diff) | |
download | Terminal-a36312d9912f701dd1dbf0b3d35b198bb5f4ab2f.tar.gz |
Add forkpty function
Change-Id: I2eaac8c2c5c50f870a5a56806d0fd19dc5f386a1
Diffstat (limited to 'jni')
-rw-r--r-- | jni/Android.mk | 3 | ||||
-rw-r--r-- | jni/forkpty.cpp | 83 | ||||
-rw-r--r-- | jni/forkpty.h | 21 |
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); |