Add |opts| argument to android_fork_execvp_ext

to allow the caller to send data to the child's stdin.

Bug: 21725996
Change-Id: I818f5cf61045286c8d64a91b6d50f05740329be1
diff --git a/logwrapper/logwrap.c b/logwrapper/logwrap.c
index 777dafe..c7b4835 100644
--- a/logwrapper/logwrap.c
+++ b/logwrapper/logwrap.c
@@ -474,7 +474,8 @@
 }
 
 int android_fork_execvp_ext(int argc, char* argv[], int *status, bool ignore_int_quit,
-        int log_target, bool abbreviated, char *file_path) {
+        int log_target, bool abbreviated, char *file_path,
+        const struct AndroidForkExecvpOption* opts, size_t opts_len) {
     pid_t pid;
     int parent_ptty;
     int child_ptty;
@@ -483,6 +484,7 @@
     sigset_t blockset;
     sigset_t oldset;
     int rc = 0;
+    size_t i;
 
     rc = pthread_mutex_lock(&fd_mutex);
     if (rc) {
@@ -529,7 +531,13 @@
         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
         close(parent_ptty);
 
-        // redirect stdout and stderr
+        // redirect stdin, stdout and stderr
+        for (i = 0; i < opts_len; ++i) {
+            if (opts[i].opt_type == FORK_EXECVP_OPTION_INPUT) {
+                dup2(child_ptty, 0);
+                break;
+            }
+        }
         dup2(child_ptty, 1);
         dup2(child_ptty, 2);
         close(child_ptty);
@@ -546,6 +554,22 @@
             sigaction(SIGQUIT, &ignact, &quitact);
         }
 
+        for (i = 0; i < opts_len; ++i) {
+            if (opts[i].opt_type == FORK_EXECVP_OPTION_INPUT) {
+                size_t left = opts[i].opt_input.input_len;
+                const uint8_t* input = opts[i].opt_input.input;
+                while (left > 0) {
+                    ssize_t res =
+                        TEMP_FAILURE_RETRY(write(parent_ptty, input, left));
+                    if (res < 0) {
+                        break;
+                    }
+                    left -= res;
+                    input += res;
+                }
+            }
+        }
+
         rc = parent(argv[0], parent_ptty, pid, status, log_target,
                     abbreviated, file_path);
     }