Allow redirecting logging to an FD

This change allows redirection of logging facilities, from syslog to a
file.

Bug: None
Test: make tests  // see logging in stderr
Change-Id: Ia45ccb87908f1d4a2f7964a01d11a74da6e9fdb7
diff --git a/minijail0.c b/minijail0.c
index db9fc40..d47aad5 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -212,7 +212,9 @@
 	       "  -Y:           Synchronize seccomp filters across thread group.\n"
 	       "  -z:           Don't forward signals to jailed process.\n"
 	       "  --ambient:    Raise ambient capabilities. Requires -c.\n"
-	       "  --uts[=name]: Enter a new UTS namespace (and set hostname).\n");
+	       "  --uts[=name]: Enter a new UTS namespace (and set hostname).\n"
+	       "  --logging=<s>:Use <s> as the logging system.\n"
+	       "                <s> must be 'syslog' (default) or 'stderr'.\n");
 	/* clang-format on */
 }
 
@@ -243,6 +245,7 @@
 	char *map;
 	size_t size;
 	const char *filter_path = NULL;
+	int log_to_stderr = 0;
 
 	const char *optstring =
 	    "+u:g:sS:c:C:P:b:B:V:f:m::M::k:a:e::R:T:vrGhHinNplLt::IUKwyYz";
@@ -251,6 +254,7 @@
 	const struct option long_options[] = {
 		{"ambient", no_argument, 0, 128},
 		{"uts", optional_argument, 0, 129},
+		{"logging", required_argument, 0, 130},
 		{0, 0, 0, 0},
 	};
 	/* clang-format on */
@@ -499,12 +503,35 @@
 			if (optarg)
 				minijail_namespace_set_hostname(j, optarg);
 			break;
+		case 130: /* Logging. */
+			if (!strcmp(optarg, "syslog"))
+				log_to_stderr = 0;
+			else if (!strcmp(optarg, "stderr")) {
+				log_to_stderr = 1;
+			} else {
+				fprintf(stderr, "--logger must be 'syslog' or "
+						"'stderr'.\n");
+				exit(1);
+			}
+			break;
 		default:
 			usage(argv[0]);
 			exit(1);
 		}
 	}
 
+	if (log_to_stderr) {
+		init_logging(LOG_TO_FD, STDERR_FILENO, LOG_INFO);
+		/*
+		 * When logging to stderr, ensure the FD survives the jailing.
+		 */
+		if (0 !=
+		    minijail_preserve_fd(j, STDERR_FILENO, STDERR_FILENO)) {
+			fprintf(stderr, "Could not preserve stderr.\n");
+			exit(1);
+		}
+	}
+
 	/* Can only set ambient caps when using regular caps. */
 	if (ambient_caps && !caps) {
 		fprintf(stderr, "Can't set ambient capabilities (--ambient) "
@@ -625,7 +652,7 @@
 	}
 
 	if (exit_immediately) {
-		info("not running init loop, exiting immediately");
+		info("not running init loop, exiting immediately\n");
 		return 0;
 	}
 	int ret = minijail_wait(j);