Kill the child process before dying.

We kill the child process if we fail to send the Minijail
configuration over, but we were not killing the child process when
failing to write a pid file, failing to set up cgroups, or failing
to set up uid/gid maps. Kill the child in those cases too.

Use this opportunity to refactor libminijail.c a bit more, extracting
common functions that don't require knowledge of struct minijail to
util.c.

Bug: 30708487

Change-Id: Ie22be97093c4f53e5a57585bfe88ae7b55567fbd
diff --git a/util.c b/util.c
index b77de37..b82e308 100644
--- a/util.c
+++ b/util.c
@@ -4,9 +4,13 @@
  */
 
 #include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/utsname.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #include "util.h"
 
@@ -209,6 +213,62 @@
 	return path;
 }
 
+int write_proc_file(pid_t pid, const char *content, const char *basename)
+{
+	int fd, ret;
+	size_t sz, len;
+	ssize_t written;
+	char filename[32];
+
+	sz = sizeof(filename);
+	ret = snprintf(filename, sz, "/proc/%d/%s", pid, basename);
+	if (ret < 0 || (size_t)ret >= sz) {
+		warn("failed to generate %s filename", basename);
+		return -1;
+	}
+
+	fd = open(filename, O_WRONLY | O_CLOEXEC);
+	if (fd < 0) {
+		pwarn("failed to open '%s'", filename);
+		return -errno;
+	}
+
+	len = strlen(content);
+	written = write(fd, content, len);
+	if (written < 0) {
+		pwarn("failed to write '%s'", filename);
+		return -1;
+	}
+
+	if ((size_t)written < len) {
+		warn("failed to write %zu bytes to '%s'", len, filename);
+		return -1;
+	}
+	close(fd);
+	return 0;
+}
+
+int write_pid_to_path(pid_t pid, const char *path)
+{
+	FILE *fp = fopen(path, "w");
+
+	if (!fp) {
+		pwarn("failed to open '%s'", path);
+		return -errno;
+	}
+	if (fprintf(fp, "%d\n", (int)pid) < 0) {
+		/* fprintf(3) does not set errno on failure. */
+		warn("fprintf(%s) failed", path);
+		return -1;
+	}
+	if (fclose(fp)) {
+		pwarn("fclose(%s) failed", path);
+		return -errno;
+	}
+
+	return 0;
+}
+
 void *consumebytes(size_t length, char **buf, size_t *buflength)
 {
 	char *p = *buf;