DO NOT MERGE: Ensure the target sees a proper EOD marker during restore
Malformed or corrupt archives may be missing their in-band EOD
content, so make sure that the target sees one regardless rather
than continuing to block on read, expecting in-band signaling.
Bug 28056941
Change-Id: Ic39966d3448787a8c511783d39172032ed9589c3
(cherry picked from commit 2bcdda8e5d
)
This commit is contained in:
parent
87ef739dba
commit
c42f1bb3e9
|
@ -371,19 +371,7 @@ static void read_status_line(int fd, char* buf, size_t count)
|
|||
*buf = '\0';
|
||||
}
|
||||
|
||||
static void copy_to_file(int inFd, int outFd) {
|
||||
const size_t BUFSIZE = 32 * 1024;
|
||||
char* buf = (char*) malloc(BUFSIZE);
|
||||
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)", inFd, outFd);
|
||||
|
||||
static void stdinout_raw_prologue(int inFd, int outFd, int& old_stdin_mode, int& old_stdout_mode) {
|
||||
if (inFd == STDIN_FILENO) {
|
||||
stdin_raw_init();
|
||||
#ifdef _WIN32
|
||||
|
@ -402,6 +390,39 @@ static void copy_to_file(int inFd, int outFd) {
|
|||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void stdinout_raw_epilogue(int inFd, int outFd, int old_stdin_mode, int old_stdout_mode) {
|
||||
if (inFd == STDIN_FILENO) {
|
||||
stdin_raw_restore();
|
||||
#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
|
||||
}
|
||||
|
||||
static void copy_to_file(int inFd, int outFd) {
|
||||
const size_t BUFSIZE = 32 * 1024;
|
||||
char* buf = (char*) malloc(BUFSIZE);
|
||||
if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
|
||||
int len;
|
||||
long total = 0;
|
||||
int old_stdin_mode = -1;
|
||||
int old_stdout_mode = -1;
|
||||
|
||||
D("copy_to_file(%d -> %d)", inFd, outFd);
|
||||
|
||||
stdinout_raw_prologue(inFd, outFd, old_stdin_mode, old_stdout_mode);
|
||||
|
||||
while (true) {
|
||||
if (inFd == STDIN_FILENO) {
|
||||
|
@ -426,22 +447,7 @@ static void copy_to_file(int inFd, int outFd) {
|
|||
total += len;
|
||||
}
|
||||
|
||||
if (inFd == STDIN_FILENO) {
|
||||
stdin_raw_restore();
|
||||
#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
|
||||
stdinout_raw_epilogue(inFd, outFd, old_stdin_mode, old_stdout_mode);
|
||||
|
||||
D("copy_to_file() finished after %lu bytes", total);
|
||||
free(buf);
|
||||
|
@ -1222,6 +1228,29 @@ static int logcat(TransportType transport, const char* serial, int argc, const c
|
|||
return send_shell_command(transport, serial, cmd, true);
|
||||
}
|
||||
|
||||
static void write_zeros(int bytes, int fd) {
|
||||
int old_stdin_mode = -1;
|
||||
int old_stdout_mode = -1;
|
||||
char* buf = (char*) calloc(1, bytes);
|
||||
if (buf == nullptr) fatal("couldn't allocate buffer for write_zeros");
|
||||
|
||||
D("write_zeros(%d) -> %d", bytes, fd);
|
||||
|
||||
stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
|
||||
|
||||
if (fd == STDOUT_FILENO) {
|
||||
fwrite(buf, 1, bytes, stdout);
|
||||
fflush(stdout);
|
||||
} else {
|
||||
adb_write(fd, buf, bytes);
|
||||
}
|
||||
|
||||
stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
|
||||
|
||||
D("write_zeros() finished");
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static int backup(int argc, const char** argv) {
|
||||
const char* filename = "backup.ab";
|
||||
|
||||
|
@ -1302,6 +1331,9 @@ static int restore(int argc, const char** argv) {
|
|||
printf("Now unlock your device and confirm the restore operation.\n");
|
||||
copy_to_file(tarFd, fd);
|
||||
|
||||
// Provide an in-band EOD marker in case the archive file is malformed
|
||||
write_zeros(512*2, fd);
|
||||
|
||||
// Wait until the other side finishes, or it'll get sent SIGHUP.
|
||||
copy_to_file(fd, STDOUT_FILENO);
|
||||
|
||||
|
|
Loading…
Reference in New Issue