Merge "Revert "adb/base: fix adb push of Unicode filenames on Win32""
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 6970a18..6e4c4e8 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -112,11 +112,12 @@
" (-a preserves file timestamp and mode)\n"
" adb sync [ <directory> ] - copy host->device only if changed\n"
" (-l means list but don't copy)\n"
- " adb shell [-Ttx] - run remote shell interactively\n"
- " adb shell [-Ttx] <command> - run remote shell command\n"
- " (-T disables PTY allocation)\n"
- " (-t forces PTY allocation)\n"
- " (-x disables remote exit codes and stdout/stderr separation)\n"
+ " adb shell [-e escape] [-Tt] [-x] [command]\n"
+ " - run remote shell command (interactive shell if no command given)\n"
+ " (-e: choose escape character, or \"none\"; default '~')\n"
+ " (-T: disable PTY allocation)\n"
+ " (-t: force PTY allocation)\n"
+ " (-x: disable remote exit codes and stdout/stderr separation)\n"
" adb emu <command> - run emulator console command\n"
" adb logcat [ <filter-spec> ] - View device log\n"
" adb forward --list - list all forward socket connections.\n"
@@ -467,6 +468,7 @@
int stdin_fd, write_fd;
bool raw_stdin;
std::unique_ptr<ShellProtocol> protocol;
+ char escape_char;
};
// Loops to read from stdin and push the data to the given FD.
@@ -474,7 +476,6 @@
// will take ownership of the object and delete it when finished.
static void* stdin_read_thread_loop(void* x) {
std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));
- int state = 0;
#if !defined(_WIN32)
// Mask SIGTTIN in case we're in a backgrounded process.
@@ -496,7 +497,7 @@
// Set up the initial window size.
send_window_size_change(args->stdin_fd, args->protocol);
- char raw_buffer[1024];
+ char raw_buffer[BUFSIZ];
char* buffer_ptr = raw_buffer;
size_t buffer_size = sizeof(raw_buffer);
if (args->protocol != nullptr) {
@@ -504,6 +505,14 @@
buffer_size = args->protocol->data_capacity();
}
+ // If we need to parse escape sequences, make life easy.
+ if (args->raw_stdin && args->escape_char != '\0') {
+ buffer_size = 1;
+ }
+
+ enum EscapeState { kMidFlow, kStartOfLine, kInEscape };
+ EscapeState state = kStartOfLine;
+
while (true) {
// Use unix_read() rather than adb_read() for stdin.
D("stdin_read_thread_loop(): pre unix_read(fdi=%d,...)", args->stdin_fd);
@@ -529,36 +538,36 @@
}
break;
}
- // If we made stdin raw, check input for the "~." escape sequence. In
+ // If we made stdin raw, check input for escape sequences. In
// this situation signals like Ctrl+C are sent remotely rather than
// interpreted locally so this provides an emergency out if the remote
// process starts ignoring the signal. SSH also does this, see the
// "escape characters" section on the ssh man page for more info.
- if (args->raw_stdin) {
- for (int n = 0; n < r; n++) {
- switch (buffer_ptr[n]) {
- case '\n':
- state = 1;
- break;
- case '\r':
- state = 1;
- break;
- case '~':
- if (state == 1) {
- state++;
- } else {
- state = 0;
- }
- break;
- case '.':
- if (state == 2) {
- fprintf(stderr,"\r\n* disconnect *\r\n");
+ if (args->raw_stdin && args->escape_char != '\0') {
+ char ch = buffer_ptr[0];
+ if (ch == args->escape_char) {
+ if (state == kStartOfLine) {
+ state = kInEscape;
+ // Swallow the escape character.
+ continue;
+ } else {
+ state = kMidFlow;
+ }
+ } else {
+ if (state == kInEscape) {
+ if (ch == '.') {
+ fprintf(stderr,"\r\n[ disconnected ]\r\n");
stdin_raw_restore();
exit(0);
+ } else {
+ // We swallowed an escape character that wasn't part of
+ // a valid escape sequence; time to cough it up.
+ buffer_ptr[0] = args->escape_char;
+ buffer_ptr[1] = ch;
+ ++r;
}
- default:
- state = 0;
}
+ state = (ch == '\n' || ch == '\r') ? kStartOfLine : kMidFlow;
}
}
if (args->protocol) {
@@ -603,6 +612,7 @@
// On success returns the remote exit code if |use_shell_protocol| is true,
// 0 otherwise. On failure returns 1.
static int RemoteShell(bool use_shell_protocol, const std::string& type_arg,
+ char escape_char,
const std::string& command) {
std::string service_string = ShellServiceString(use_shell_protocol,
type_arg, command);
@@ -628,6 +638,7 @@
args->stdin_fd = STDIN_FILENO;
args->write_fd = fd;
args->raw_stdin = raw_stdin;
+ args->escape_char = escape_char;
if (use_shell_protocol) {
args->protocol.reset(new ShellProtocol(args->write_fd));
}
@@ -689,8 +700,17 @@
--argc;
++argv;
int t_arg_count = 0;
+ char escape_char = '~';
while (argc) {
- if (!strcmp(argv[0], "-T") || !strcmp(argv[0], "-t")) {
+ if (!strcmp(argv[0], "-e")) {
+ if (argc < 2 || !(strlen(argv[1]) == 1 || strcmp(argv[1], "none") == 0)) {
+ fprintf(stderr, "error: -e requires a single-character argument or 'none'\n");
+ return 1;
+ }
+ escape_char = (strcmp(argv[1], "none") == 0) ? 0 : argv[1][0];
+ argc -= 2;
+ argv += 2;
+ } else if (!strcmp(argv[0], "-T") || !strcmp(argv[0], "-t")) {
if (!CanUseFeature(features, kFeatureShell2)) {
fprintf(stderr, "error: target doesn't support PTY args -Tt\n");
return 1;
@@ -746,7 +766,7 @@
command = android::base::Join(std::vector<const char*>(argv, argv + argc), ' ');
}
- return RemoteShell(use_shell_protocol, shell_type_arg, command);
+ return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, command);
}
static int adb_download_buffer(const char *service, const char *fn, const void* data, unsigned sz,
diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp
index 268a11f..3322763 100644
--- a/adb/file_sync_client.cpp
+++ b/adb/file_sync_client.cpp
@@ -209,6 +209,17 @@
line_printer_.Print(s, LinePrinter::FULL);
}
+ void Warning(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) {
+ std::string s = "adb: warning: ";
+
+ va_list ap;
+ va_start(ap, fmt);
+ android::base::StringAppendV(&s, fmt, ap);
+ va_end(ap);
+
+ line_printer_.Print(s, LinePrinter::FULL);
+ }
+
uint64_t total_bytes;
// TODO: add a char[max] buffer here, to replace syncsendbuf...
@@ -533,7 +544,7 @@
dirlist.push_back(ci);
} else {
if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
- sc.Error("skipping special file '%s'", lpath.c_str());
+ sc.Warning("skipping special file '%s'", lpath.c_str());
} else {
ci.time = st.st_mtime;
ci.size = st.st_size;
@@ -554,7 +565,7 @@
if (empty_dir) {
// TODO(b/25566053): Make pushing empty directories work.
// TODO(b/25457350): We don't preserve permissions on directories.
- sc.Error("skipping empty directory '%s'", lpath.c_str());
+ sc.Warning("skipping empty directory '%s'", lpath.c_str());
copyinfo ci = mkcopyinfo(adb_dirname(lpath), adb_dirname(rpath),
adb_basename(lpath), S_IFDIR);
ci.skip = true;
@@ -709,8 +720,7 @@
ci.size = size;
filelist->push_back(ci);
} else {
- sc.Print(android::base::StringPrintf("skipping special file '%s'\n",
- name));
+ sc.Warning("skipping special file '%s'\n", name);
}
};
@@ -852,7 +862,8 @@
continue;
}
- if (S_ISREG(mode) || S_ISLNK(mode) || S_ISCHR(mode) || S_ISBLK(mode)) {
+ if (S_ISREG(mode) || S_ISLNK(mode)) {
+ // TODO(b/25601283): symlinks shouldn't be handled as files.
std::string path_holder;
struct stat st;
if (stat(dst_path, &st) == 0) {
diff --git a/include/utils/Errors.h b/include/utils/Errors.h
index 08ddcd2..16e1fa2 100644
--- a/include/utils/Errors.h
+++ b/include/utils/Errors.h
@@ -72,6 +72,7 @@
UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6),
#endif
FDS_NOT_ALLOWED = (UNKNOWN_ERROR + 7),
+ UNEXPECTED_NULL = (UNKNOWN_ERROR + 8),
};
// Restore define; enumeration is in "android" namespace, so the value defined
diff --git a/libpixelflinger/codeflinger/MIPS64Assembler.h b/libpixelflinger/codeflinger/MIPS64Assembler.h
index 3da291a..b43e5da 100644
--- a/libpixelflinger/codeflinger/MIPS64Assembler.h
+++ b/libpixelflinger/codeflinger/MIPS64Assembler.h
@@ -303,32 +303,7 @@
protected:
- // void string_detab(char *s);
- // void string_pad(char *s, int padded_len);
-
ArmToMips64Assembler *mParent;
- sp<Assembly> mAssembly;
- uint32_t* mBase;
- uint32_t* mPC;
- uint32_t* mPrologPC;
- int64_t mDuration;
-#if defined(WITH_LIB_HARDWARE)
- bool mQemuTracing;
-#endif
-
- struct branch_target_t {
- inline branch_target_t() : label(0), pc(0) { }
- inline branch_target_t(const char* l, uint32_t* p)
- : label(l), pc(p) { }
- const char* label;
- uint32_t* pc;
- };
-
- Vector<branch_target_t> mBranchTargets;
- KeyedVector< const char*, uint32_t* > mLabels;
- KeyedVector< uint32_t*, const char* > mLabelsInverseMapping;
- KeyedVector< uint32_t*, const char* > mComments;
-
// opcode field of all instructions
enum opcode_field {