Merge changes I6d73bcad,I41775eb1,I53342db7,Id8046a4f

* changes:
  gen_constants: rewrite sed to be a bit more readable
  gen_constants: combine sort|uniq
  gen_constants: simplify grep by using ERE by default
  gen_{constants,syscalls}: fix sed/grep locale issues
diff --git a/libminijail.c b/libminijail.c
index 2497115..a797823 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -869,22 +869,20 @@
  * uncommon for that to be less (if an older kernel) or more (if a newer
  * kernel).  So suck up the answer via /proc.
  */
-static int run_cap_valid(unsigned int cap)
+static int get_last_valid_cap()
 {
-	static unsigned int last_cap;
+	const char cap_file[] = "/proc/sys/kernel/cap_last_cap";
+	FILE *fp = fopen(cap_file, "re");
+	int last_valid_cap;
 
-	if (!last_cap) {
-		const char cap_file[] = "/proc/sys/kernel/cap_last_cap";
-		FILE *fp = fopen(cap_file, "re");
-		if (fscanf(fp, "%u", &last_cap) != 1)
-			pdie("fscanf(%s)", cap_file);
-		fclose(fp);
-	}
+	if (fscanf(fp, "%u", &last_valid_cap) != 1)
+		pdie("fscanf(%s)", cap_file);
+	fclose(fp);
 
-	return cap <= last_cap;
+	return last_valid_cap;
 }
 
-void drop_caps(const struct minijail *j)
+void drop_caps(const struct minijail *j, int last_valid_cap)
 {
 	cap_t caps = cap_get_proc();
 	cap_value_t flag[1];
@@ -898,7 +896,7 @@
 		die("can't clear effective caps");
 	if (cap_clear_flag(caps, CAP_PERMITTED))
 		die("can't clear permitted caps");
-	for (i = 0; i < sizeof(j->caps) * 8 && run_cap_valid(i); ++i) {
+	for (i = 0; i < sizeof(j->caps) * 8 && i <= last_valid_cap; ++i) {
 		/* Keep CAP_SETPCAP for dropping bounding set bits. */
 		if (i != CAP_SETPCAP && !(j->caps & (one << i)))
 			continue;
@@ -919,7 +917,7 @@
 	 * have been used above to raise a capability that wasn't already
 	 * present. This requires CAP_SETPCAP, so we raised/kept it above.
 	 */
-	for (i = 0; i < sizeof(j->caps) * 8 && run_cap_valid(i); ++i) {
+	for (i = 0; i < sizeof(j->caps) * 8 && i <= last_valid_cap; ++i) {
 		if (j->caps & (one << i))
 			continue;
 		if (prctl(PR_CAPBSET_DROP, i))
@@ -980,6 +978,12 @@
 
 void API minijail_enter(const struct minijail *j)
 {
+	/*
+	 * Get the last valid cap from /proc, since /proc can be unmounted
+	 * before drop_caps().
+	 */
+	int last_valid_cap = get_last_valid_cap();
+
 	if (j->flags.pids)
 		die("tried to enter a pid-namespaced jail;"
 		    " try minijail_run()?");
@@ -1044,7 +1048,7 @@
 	if (j->flags.no_new_privs) {
 		drop_ugid(j);
 		if (j->flags.caps)
-			drop_caps(j);
+			drop_caps(j, last_valid_cap);
 
 		set_seccomp_filter(j);
 	} else {
@@ -1059,7 +1063,7 @@
 
 		drop_ugid(j);
 		if (j->flags.caps)
-			drop_caps(j);
+			drop_caps(j, last_valid_cap);
 	}
 
 	/*
@@ -1236,14 +1240,6 @@
 				     NULL, NULL, true);
 }
 
-int API minijail_run_pid_pipe(struct minijail *j, const char *filename,
-			      char *const argv[], pid_t *pchild_pid,
-			      int *pstdin_fd)
-{
-	return minijail_run_internal(j, filename, argv, pchild_pid, pstdin_fd,
-				     NULL, NULL, true);
-}
-
 int API minijail_run_pid_pipes(struct minijail *j, const char *filename,
 			       char *const argv[], pid_t *pchild_pid,
 			       int *pstdin_fd, int *pstdout_fd, int *pstderr_fd)
@@ -1259,6 +1255,14 @@
 				     false);
 }
 
+int API minijail_run_pid_pipes_no_preload(struct minijail *j,
+					  const char *filename, char *const argv[],
+					  pid_t *pchild_pid,
+					  int *pstdin_fd, int *pstdout_fd, int *pstderr_fd) {
+	return minijail_run_internal(j, filename, argv, pchild_pid,
+				     pstdin_fd, pstdout_fd, pstderr_fd, false);
+}
+
 int minijail_run_internal(struct minijail *j, const char *filename,
 			  char *const argv[], pid_t *pchild_pid,
 			  int *pstdin_fd, int *pstdout_fd, int *pstderr_fd,
diff --git a/libminijail.h b/libminijail.h
index d6c3c42..62e4007 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -149,10 +149,14 @@
  * Update |*pchild_pid| with the pid of the child.
  * Update |*pstdin_fd| with a fd that allows writing to the child's
  * standard input.
+ * Update |*pstdout_fd| with a fd that allows reading from the child's
+ * standard output.
+ * Update |*pstderr_fd| with a fd that allows reading from the child's
+ * standard error.
  */
-int minijail_run_pid_pipe(struct minijail *j, const char *filename,
-			  char *const argv[], pid_t *pchild_pid,
-			  int *pstdin_fd);
+int minijail_run_pid_pipes(struct minijail *j, const char *filename,
+			   char *const argv[], pid_t *pchild_pid,
+			   int *pstdin_fd, int *pstdout_fd, int *pstderr_fd);
 
 /* Run the specified command in the given minijail, execve(2)-style.
  * Update |*pchild_pid| with the pid of the child.
@@ -162,10 +166,11 @@
  * standard output.
  * Update |*pstderr_fd| with a fd that allows reading from the child's
  * standard error.
+ * Used with static binaries, or on systems without support for LD_PRELOAD.
  */
-int minijail_run_pid_pipes(struct minijail *j, const char *filename,
-			   char *const argv[], pid_t *pchild_pid,
-			   int *pstdin_fd, int *pstdout_fd, int *pstderr_fd);
+int minijail_run_pid_pipes_no_preload(struct minijail *j, const char *filename,
+				      char *const argv[], pid_t *pchild_pid,
+				      int *pstdin_fd, int *pstdout_fd, int *pstderr_fd);
 
 /* Kill the specified minijail. The minijail must have been created with pid
  * namespacing; if it was, all processes inside it are atomically killed.
diff --git a/libminijail_unittest.c b/libminijail_unittest.c
index 011ce85..1a98741 100644
--- a/libminijail_unittest.c
+++ b/libminijail_unittest.c
@@ -145,30 +145,6 @@
 
 /*
  * TODO(jorgelo): rewrite these tests to not depend on libminijailpreload.so.
-TEST(test_minijail_run_pid_pipe) {
-  pid_t pid;
-  int child_stdin;
-  int mj_run_ret;
-  ssize_t write_ret;
-  int status;
-  char filename[] = "test/read_stdin";
-  char *argv[2];
-  argv[0] = filename;
-  argv[1] = NULL;
-
-  struct minijail *j = minijail_new();
-  mj_run_ret = minijail_run_pid_pipe(j, argv[0], argv, &pid, &child_stdin);
-  EXPECT_EQ(mj_run_ret, 0);
-  write_ret = write(child_stdin, "test\n", strlen("test\n"));
-  EXPECT_GT(write_ret, -1);
-
-  waitpid(pid, &status, 0);
-  ASSERT_TRUE(WIFEXITED(status));
-  EXPECT_EQ(WEXITSTATUS(status), 0);
-
-  minijail_destroy(j);
-}
-
 TEST(test_minijail_run_pid_pipes) {
   pid_t pid;
   int child_stdin, child_stdout, child_stderr;