AU: Catch terminate signals and block exit if necessary.

Adds a global Terminator class to manage signals and exit blocking.

BUG=7392
TEST=unit tests, gmerged on device, initctl stop update-engine

Change-Id: I2291d4eb55240a6662b18ff834af161d957bce2f

Review URL: http://codereview.chromium.org/3608015
diff --git a/delta_performer.cc b/delta_performer.cc
index f807665..10031eb 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -23,6 +23,7 @@
 #include "update_engine/payload_signer.h"
 #include "update_engine/prefs_interface.h"
 #include "update_engine/subprocess.h"
+#include "update_engine/terminator.h"
 
 using std::min;
 using std::string;
@@ -209,6 +210,8 @@
             next_operation_num_ - manifest_.install_operations_size());
     if (!CanPerformInstallOperation(op))
       break;
+    ScopedTerminatorExitUnblocker exit_unblocker =
+        ScopedTerminatorExitUnblocker();  // Avoids a compiler unused var bug.
     // Log every thousandth operation, and also the first and last ones
     if ((next_operation_num_ % 1000 == 0) ||
         (next_operation_num_ + 1 == total_operations)) {
@@ -221,6 +224,7 @@
     // that if the operation gets interrupted, we don't try to resume the
     // update.
     if (!IsIdempotentOperation(op)) {
+      Terminator::set_exit_blocked(true);
       ResetUpdateProgress(prefs_);
     }
     if (op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE ||
@@ -574,9 +578,10 @@
 }
 
 bool DeltaPerformer::CheckpointUpdateProgress() {
-  // First reset the progress in case we die in the middle of the state update.
-  ResetUpdateProgress(prefs_);
+  Terminator::set_exit_blocked(true);
   if (last_updated_buffer_offset_ != buffer_offset_) {
+    // Resets the progress in case we die in the middle of the state update.
+    ResetUpdateProgress(prefs_);
     TEST_AND_RETURN_FALSE(
         prefs_->SetString(kPrefsUpdateStateSHA256Context,
                           hash_calculator_.GetContext()));