diff --git a/recovery.cpp b/recovery.cpp index 1d22b248..6deeaaae 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -1107,6 +1107,7 @@ main(int argc, char **argv) { } if (status != INSTALL_SUCCESS) { ui->Print("Installation aborted.\n"); + ui->Print("OTA failed! Please power off the device to keep it in this state and file a bug report!\n"); // If this is an eng or userdebug build, then automatically // turn the text display on if the script fails so the error diff --git a/updater/blockimg.c b/updater/blockimg.c index 30268931..6060ac28 100644 --- a/updater/blockimg.c +++ b/updater/blockimg.c @@ -687,19 +687,26 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] rss.p_remain = (tgt->pos[1] - tgt->pos[0]) * BLOCKSIZE; check_lseek(fd, (off64_t)tgt->pos[0] * BLOCKSIZE, SEEK_SET); + int ret; if (style[0] == 'i') { // imgdiff - ApplyImagePatch(buffer, src_blocks * BLOCKSIZE, - &patch_value, - &RangeSinkWrite, &rss, NULL, NULL); + ret = ApplyImagePatch(buffer, src_blocks * BLOCKSIZE, + &patch_value, + &RangeSinkWrite, &rss, NULL, NULL); } else { - ApplyBSDiffPatch(buffer, src_blocks * BLOCKSIZE, - &patch_value, 0, - &RangeSinkWrite, &rss, NULL); + ret = ApplyBSDiffPatch(buffer, src_blocks * BLOCKSIZE, + &patch_value, 0, + &RangeSinkWrite, &rss, NULL); + } + + if (ret != 0) { + ErrorAbort(state, "patch failed\n"); + goto done; } // We expect the output of the patcher to fill the tgt ranges exactly. if (rss.p_block != tgt->count || rss.p_remain != 0) { - fprintf(stderr, "range sink underrun?\n"); + ErrorAbort(state, "range sink underrun?\n"); + goto done; } blocks_so_far += tgt->size; @@ -723,7 +730,8 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] range[1] = (tgt->pos[i*2+1] - tgt->pos[i*2]) * (uint64_t)BLOCKSIZE; if (ioctl(fd, BLKDISCARD, &range) < 0) { - printf(" blkdiscard failed: %s\n", strerror(errno)); + ErrorAbort(state, " blkdiscard failed: %s\n", strerror(errno)); + goto done; } } @@ -732,8 +740,8 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] printf(" ignoring erase (not block device)\n"); } } else { - fprintf(stderr, "unknown transfer style \"%s\"\n", style); - exit(1); + ErrorAbort(state, "unknown transfer style \"%s\"\n", style); + goto done; } } @@ -744,13 +752,19 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] printf("wrote %d blocks; expected %d\n", blocks_so_far, total_blocks); printf("max alloc needed was %zu\n", buffer_alloc); - done: +done: free(transfer_list); FreeValue(blockdev_filename); FreeValue(transfer_list_value); FreeValue(new_data_fn); FreeValue(patch_data_fn); - return StringValue(success ? strdup("t") : strdup("")); + if (success) { + return StringValue(strdup("t")); + } else { + // NULL will be passed to its caller at Evaluate() and abort the OTA + // process. + return NULL; + } } Value* RangeSha1Fn(const char* name, State* state, int argc, Expr* argv[]) { @@ -793,11 +807,11 @@ Value* RangeSha1Fn(const char* name, State* state, int argc, Expr* argv[]) { digest = SHA_final(&ctx); close(fd); - done: +done: FreeValue(blockdev_filename); FreeValue(ranges); if (digest == NULL) { - return StringValue(strdup("")); + return NULL; } else { return StringValue(PrintSha1(digest)); }