system/corennnnn
修訂 | 2bcdda8e5dfdb33409fce062fdfd9d0735432ef8 (tree) |
---|---|
時間 | 2016-07-14 09:58:27 |
作者 | Christopher Tate <ctate@goog...> |
Commiter | Christopher Tate |
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
@@ -370,19 +370,7 @@ static void read_status_line(int fd, char* buf, size_t count) | ||
370 | 370 | *buf = '\0'; |
371 | 371 | } |
372 | 372 | |
373 | -static void copy_to_file(int inFd, int outFd) { | |
374 | - const size_t BUFSIZE = 32 * 1024; | |
375 | - char* buf = (char*) malloc(BUFSIZE); | |
376 | - if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file"); | |
377 | - int len; | |
378 | - long total = 0; | |
379 | -#ifdef _WIN32 | |
380 | - int old_stdin_mode = -1; | |
381 | - int old_stdout_mode = -1; | |
382 | -#endif | |
383 | - | |
384 | - D("copy_to_file(%d -> %d)", inFd, outFd); | |
385 | - | |
373 | +static void stdinout_raw_prologue(int inFd, int outFd, int& old_stdin_mode, int& old_stdout_mode) { | |
386 | 374 | if (inFd == STDIN_FILENO) { |
387 | 375 | stdin_raw_init(); |
388 | 376 | #ifdef _WIN32 |
@@ -401,6 +389,39 @@ static void copy_to_file(int inFd, int outFd) { | ||
401 | 389 | } |
402 | 390 | } |
403 | 391 | #endif |
392 | +} | |
393 | + | |
394 | +static void stdinout_raw_epilogue(int inFd, int outFd, int old_stdin_mode, int old_stdout_mode) { | |
395 | + if (inFd == STDIN_FILENO) { | |
396 | + stdin_raw_restore(); | |
397 | +#ifdef _WIN32 | |
398 | + if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) { | |
399 | + fatal_errno("could not restore stdin mode"); | |
400 | + } | |
401 | +#endif | |
402 | + } | |
403 | + | |
404 | +#ifdef _WIN32 | |
405 | + if (outFd == STDOUT_FILENO) { | |
406 | + if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) { | |
407 | + fatal_errno("could not restore stdout mode"); | |
408 | + } | |
409 | + } | |
410 | +#endif | |
411 | +} | |
412 | + | |
413 | +static void copy_to_file(int inFd, int outFd) { | |
414 | + const size_t BUFSIZE = 32 * 1024; | |
415 | + char* buf = (char*) malloc(BUFSIZE); | |
416 | + if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file"); | |
417 | + int len; | |
418 | + long total = 0; | |
419 | + int old_stdin_mode = -1; | |
420 | + int old_stdout_mode = -1; | |
421 | + | |
422 | + D("copy_to_file(%d -> %d)", inFd, outFd); | |
423 | + | |
424 | + stdinout_raw_prologue(inFd, outFd, old_stdin_mode, old_stdout_mode); | |
404 | 425 | |
405 | 426 | while (true) { |
406 | 427 | if (inFd == STDIN_FILENO) { |
@@ -425,22 +446,7 @@ static void copy_to_file(int inFd, int outFd) { | ||
425 | 446 | total += len; |
426 | 447 | } |
427 | 448 | |
428 | - if (inFd == STDIN_FILENO) { | |
429 | - stdin_raw_restore(); | |
430 | -#ifdef _WIN32 | |
431 | - if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) { | |
432 | - fatal_errno("could not restore stdin mode"); | |
433 | - } | |
434 | -#endif | |
435 | - } | |
436 | - | |
437 | -#ifdef _WIN32 | |
438 | - if (outFd == STDOUT_FILENO) { | |
439 | - if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) { | |
440 | - fatal_errno("could not restore stdout mode"); | |
441 | - } | |
442 | - } | |
443 | -#endif | |
449 | + stdinout_raw_epilogue(inFd, outFd, old_stdin_mode, old_stdout_mode); | |
444 | 450 | |
445 | 451 | D("copy_to_file() finished after %lu bytes", total); |
446 | 452 | free(buf); |
@@ -1234,6 +1240,29 @@ static int logcat(TransportType transport, const char* serial, int argc, const c | ||
1234 | 1240 | return send_shell_command(transport, serial, cmd, true); |
1235 | 1241 | } |
1236 | 1242 | |
1243 | +static void write_zeros(int bytes, int fd) { | |
1244 | + int old_stdin_mode = -1; | |
1245 | + int old_stdout_mode = -1; | |
1246 | + char* buf = (char*) calloc(1, bytes); | |
1247 | + if (buf == nullptr) fatal("couldn't allocate buffer for write_zeros"); | |
1248 | + | |
1249 | + D("write_zeros(%d) -> %d", bytes, fd); | |
1250 | + | |
1251 | + stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode); | |
1252 | + | |
1253 | + if (fd == STDOUT_FILENO) { | |
1254 | + fwrite(buf, 1, bytes, stdout); | |
1255 | + fflush(stdout); | |
1256 | + } else { | |
1257 | + adb_write(fd, buf, bytes); | |
1258 | + } | |
1259 | + | |
1260 | + stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode); | |
1261 | + | |
1262 | + D("write_zeros() finished"); | |
1263 | + free(buf); | |
1264 | +} | |
1265 | + | |
1237 | 1266 | static int backup(int argc, const char** argv) { |
1238 | 1267 | const char* filename = "backup.ab"; |
1239 | 1268 |
@@ -1314,6 +1343,9 @@ static int restore(int argc, const char** argv) { | ||
1314 | 1343 | printf("Now unlock your device and confirm the restore operation.\n"); |
1315 | 1344 | copy_to_file(tarFd, fd); |
1316 | 1345 | |
1346 | + // Provide an in-band EOD marker in case the archive file is malformed | |
1347 | + write_zeros(512*2, fd); | |
1348 | + | |
1317 | 1349 | // Wait until the other side finishes, or it'll get sent SIGHUP. |
1318 | 1350 | copy_to_file(fd, STDOUT_FILENO); |
1319 | 1351 |