Make pty raw in adb shell when non-interactive.
The main goal here is fixing the line ending translation from \n to \r\n, but we probably don't want any translation to happen. Bug: http://b/19735063 Change-Id: I1d6d6c6b57cc741b046c2432cd864b344ce1f28a
This commit is contained in:
parent
4e0008123d
commit
569a130196
|
@ -24,6 +24,11 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !ADB_HOST
|
||||
#include <pty.h>
|
||||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -238,30 +243,14 @@ static void init_subproc_child()
|
|||
}
|
||||
}
|
||||
|
||||
static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
|
||||
{
|
||||
#if !ADB_HOST
|
||||
static int create_subproc_pty(const char* cmd, const char* arg0,
|
||||
const char* arg1, pid_t* pid) {
|
||||
D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
|
||||
#if defined(_WIN32)
|
||||
fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
|
||||
return -1;
|
||||
#else
|
||||
char pts_name[PATH_MAX];
|
||||
int ptm;
|
||||
|
||||
ptm = unix_open("/dev/ptmx", O_RDWR | O_CLOEXEC); // | O_NOCTTY);
|
||||
if(ptm < 0){
|
||||
printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
char devname[64];
|
||||
if(grantpt(ptm) || unlockpt(ptm) || ptsname_r(ptm, devname, sizeof(devname)) != 0) {
|
||||
printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
|
||||
adb_close(ptm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pid = fork();
|
||||
if(*pid < 0) {
|
||||
*pid = forkpty(&ptm, pts_name, nullptr, nullptr);
|
||||
if (*pid == -1) {
|
||||
printf("- fork failed: %s -\n", strerror(errno));
|
||||
adb_close(ptm);
|
||||
return -1;
|
||||
|
@ -270,12 +259,33 @@ static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg
|
|||
if (*pid == 0) {
|
||||
init_subproc_child();
|
||||
|
||||
int pts = unix_open(devname, O_RDWR | O_CLOEXEC);
|
||||
if (pts < 0) {
|
||||
fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname);
|
||||
int pts = unix_open(pts_name, O_RDWR | O_CLOEXEC);
|
||||
if (pts == -1) {
|
||||
fprintf(stderr, "child failed to open pseudo-term slave %s: %s\n",
|
||||
pts_name, strerror(errno));
|
||||
adb_close(ptm);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// arg0 is "-c" in batch mode and "-" in interactive mode.
|
||||
if (strcmp(arg0, "-c") == 0) {
|
||||
termios tattr;
|
||||
if (tcgetattr(pts, &tattr) == -1) {
|
||||
fprintf(stderr, "tcgetattr failed: %s\n", strerror(errno));
|
||||
adb_close(pts);
|
||||
adb_close(ptm);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cfmakeraw(&tattr);
|
||||
if (tcsetattr(pts, TCSADRAIN, &tattr) == -1) {
|
||||
fprintf(stderr, "tcsetattr failed: %s\n", strerror(errno));
|
||||
adb_close(pts);
|
||||
adb_close(ptm);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
dup2(pts, STDIN_FILENO);
|
||||
dup2(pts, STDOUT_FILENO);
|
||||
dup2(pts, STDERR_FILENO);
|
||||
|
@ -283,15 +293,15 @@ static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg
|
|||
adb_close(pts);
|
||||
adb_close(ptm);
|
||||
|
||||
execl(cmd, cmd, arg0, arg1, NULL);
|
||||
execl(cmd, cmd, arg0, arg1, nullptr);
|
||||
fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
|
||||
cmd, strerror(errno), errno);
|
||||
exit(-1);
|
||||
} else {
|
||||
return ptm;
|
||||
}
|
||||
#endif /* !defined(_WIN32) */
|
||||
}
|
||||
#endif // !ADB_HOST
|
||||
|
||||
static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
|
||||
{
|
||||
|
|
|
@ -164,7 +164,8 @@ class AdbWrapper(object):
|
|||
return call_combined(self.adb_cmd + "shell " + cmd)
|
||||
|
||||
def install(self, filename):
|
||||
return call_checked(self.adb_cmd + "install {}".format(pipes.quote(filename)))
|
||||
return call_checked(
|
||||
self.adb_cmd + "install {}".format(pipes.quote(filename)))
|
||||
|
||||
def push(self, local, remote):
|
||||
return call_checked(self.adb_cmd + "push {} {}".format(local, remote))
|
||||
|
@ -283,7 +284,7 @@ class AdbBasic(unittest.TestCase):
|
|||
result = adb.shell("sh -c 'echo hello; echo world'").splitlines()
|
||||
self.assertEqual(["", "world"], result)
|
||||
# If you really wanted "hello" and "world", here's what you'd do:
|
||||
result = adb.shell("echo hello\;echo world").splitlines()
|
||||
result = adb.shell(r"echo hello\;echo world").splitlines()
|
||||
self.assertEqual(["hello", "world"], result)
|
||||
|
||||
# http://b/15479704
|
||||
|
@ -292,7 +293,7 @@ class AdbBasic(unittest.TestCase):
|
|||
|
||||
# http://b/20564385
|
||||
self.assertEqual('t', adb.shell("FOO=a BAR=b echo t").strip())
|
||||
self.assertEqual('123Linux', adb.shell("echo -n 123\;uname").strip())
|
||||
self.assertEqual('123Linux', adb.shell(r"echo -n 123\;uname").strip())
|
||||
|
||||
def test_install_argument_escaping(self):
|
||||
"""Make sure that install argument escaping works."""
|
||||
|
@ -306,6 +307,13 @@ class AdbBasic(unittest.TestCase):
|
|||
tf = tempfile.NamedTemporaryFile("w", suffix="-Live Hold'em.apk")
|
||||
self.assertIn("-Live Hold'em.apk", adb.install(tf.name))
|
||||
|
||||
def test_line_endings(self):
|
||||
"""Ensure that line ending translation is not happening in the pty.
|
||||
|
||||
Bug: http://b/19735063
|
||||
"""
|
||||
self.assertFalse(AdbWrapper().shell("uname").endswith("\r\n"))
|
||||
|
||||
|
||||
class AdbFile(unittest.TestCase):
|
||||
SCRATCH_DIR = "/data/local/tmp"
|
||||
|
|
Loading…
Reference in New Issue