From b7dfb79b53c516e54a8964ba66e207a3bb4db9ee Mon Sep 17 00:00:00 2001 From: Spencer Low Date: Fri, 22 May 2015 16:48:31 -0700 Subject: [PATCH] adb: win32: fix exec-in and exec-out to use binary mode adb exec-in and exec-out are designed to read/write binary data according to the commit description at: https://android.googlesource.com/platform/system/core/+/5d9d434%5E!/ On Windows, when adb_read and adb_write are used, they are always in binary mode (because sysdeps_win32.cpp calls Windows APIs direct). But unix_read, unix_write, fread, fwrite, read, write use the text translation mode of the C Runtime file descriptor, which is by default textmode. adb exec-in and exec-out use copy_to_file() which uses unix_read() and fwrite() when reading/writing stdin and stdout, thus, copy_to_file() should switch to binary mode for those cases (it already uses binary mode for file descriptors other than stdin and stdout). copy_to_file() is also called by adb backup, adb restore, and adb install-multiple, but those do not use stdin or stdout, so those codepaths should not be affected by this change. Change-Id: I3446d9b363d20a2c2f6be2b96e55b653d99df2f9 Signed-off-by: Spencer Low --- adb/commandline.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/adb/commandline.cpp b/adb/commandline.cpp index 7fbca3155..c1375b315 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -302,13 +302,32 @@ static void copy_to_file(int inFd, int outFd) { if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file"); int len; long total = 0; +#ifdef _WIN32 + int old_stdin_mode = -1; + int old_stdout_mode = -1; +#endif D("copy_to_file(%d -> %d)\n", inFd, outFd); if (inFd == STDIN_FILENO) { stdin_raw_init(STDIN_FILENO); +#ifdef _WIN32 + old_stdin_mode = _setmode(STDIN_FILENO, _O_BINARY); + if (old_stdin_mode == -1) { + fatal_errno("could not set stdin to binary"); + } +#endif } +#ifdef _WIN32 + if (outFd == STDOUT_FILENO) { + old_stdout_mode = _setmode(STDOUT_FILENO, _O_BINARY); + if (old_stdout_mode == -1) { + fatal_errno("could not set stdout to binary"); + } + } +#endif + while (true) { if (inFd == STDIN_FILENO) { len = unix_read(inFd, buf, BUFSIZE); @@ -338,8 +357,21 @@ static void copy_to_file(int inFd, int outFd) { if (inFd == STDIN_FILENO) { stdin_raw_restore(STDIN_FILENO); +#ifdef _WIN32 + if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) { + fatal_errno("could not restore stdin mode"); + } +#endif } +#ifdef _WIN32 + if (outFd == STDOUT_FILENO) { + if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) { + fatal_errno("could not restore stdout mode"); + } + } +#endif + D("copy_to_file() finished after %lu bytes\n", total); free(buf); }