Implement susped, resume and cancel for the Postinstall action.

This patch sends SIGSTOP/SIGCONT to the running postinstall program to
suspend/resume the child process, and SIGKILL when cancelling it.

Bug: 27272144
TEST=Added unittest to check the signal being sent.

Change-Id: Iebe9bd34448ad1d0a5340c82e1fd839ff8c69dd2
diff --git a/common/subprocess.cc b/common/subprocess.cc
index f43aaac..61f2d54 100644
--- a/common/subprocess.cc
+++ b/common/subprocess.cc
@@ -207,7 +207,12 @@
   if (pid_record == subprocess_records_.end())
     return;
   pid_record->second->callback.Reset();
-  kill(pid, SIGTERM);
+  if (kill(pid, SIGTERM) != 0) {
+    PLOG(WARNING) << "Error sending SIGTERM to " << pid;
+  }
+  // Release the pid now so we don't try to kill it if Subprocess is destroyed
+  // before the corresponding ChildExitedCallback() is called.
+  pid_record->second->proc.Release();
 }
 
 bool Subprocess::SynchronousExec(const vector<string>& cmd,
diff --git a/common/test_utils.cc b/common/test_utils.cc
index 0e7a8ef..4ab1663 100644
--- a/common/test_utils.cc
+++ b/common/test_utils.cc
@@ -103,6 +103,15 @@
   0xbe, 0x9f, 0xa3, 0x5d,
 };
 
+string Readlink(const string& path) {
+  vector<char> buf(PATH_MAX + 1);
+  ssize_t r = readlink(path.c_str(), buf.data(), buf.size());
+  if (r < 0)
+    return "";
+  CHECK_LT(r, static_cast<ssize_t>(buf.size()));
+  return string(buf.begin(), buf.begin() + r);
+}
+
 bool IsXAttrSupported(const base::FilePath& dir_path) {
   char *path = strdup(dir_path.Append("xattr_test_XXXXXX").value().c_str());
 
diff --git a/common/test_utils.h b/common/test_utils.h
index 2c8a6de..60ec90e 100644
--- a/common/test_utils.h
+++ b/common/test_utils.h
@@ -90,6 +90,9 @@
   return chdir(path.c_str());
 }
 
+// Reads a symlink from disk. Returns empty string on failure.
+std::string Readlink(const std::string& path);
+
 // Checks if xattr is supported in the directory specified by
 // |dir_path| which must be writable. Returns true if the feature is
 // supported, false if not or if an error occurred.