logwrap: Change semantics of NULL status in android_fork_execvp

When passing a NULL status to android_fork_execvp the return
status will now be the return value of the child if it exited
properly, otherwise a non-0 value will be returned.

Change-Id: I13309c61b37b6b3f9d5507f7d6484e7b6baaf8d0
diff --git a/logwrapper/include/logwrap/logwrap.h b/logwrapper/include/logwrap/logwrap.h
index 44523e3..2be8736 100644
--- a/logwrapper/include/logwrap/logwrap.h
+++ b/logwrapper/include/logwrap/logwrap.h
@@ -37,7 +37,8 @@
  *           arguments as separate strings. argv does not need to be
  *           NULL-terminated
  *   status: the equivalent child status as populated by wait(status). This
- *           value is only valid when logwrap successfully completes
+ *           value is only valid when logwrap successfully completes. If NULL
+ *           the return value of the child will be the function's return value.
  *   ignore_int_quit: set to true if you want to completely ignore SIGINT and
  *           SIGQUIT while logwrap is running. This may force the end-user to
  *           send a signal twice to signal the caller (once for the child, and
@@ -47,6 +48,8 @@
  * Return value:
  *   0 when logwrap successfully run the child process and captured its status
  *   -1 when an internal error occurred
+ *   -ECHILD if status is NULL and the child didn't exit properly
+ *   the return value of the child if it exited properly and status is NULL
  *
  */
 int android_fork_execvp(int argc, char* argv[], int *status, bool ignore_int_quit,
diff --git a/logwrapper/logwrap.c b/logwrapper/logwrap.c
index a04097d..a756eb3 100644
--- a/logwrapper/logwrap.c
+++ b/logwrapper/logwrap.c
@@ -155,12 +155,17 @@
         if (WEXITSTATUS(status))
             ALOG(LOG_INFO, "logwrapper", "%s terminated by exit(%d)", btag,
                     WEXITSTATUS(status));
-    } else if (WIFSIGNALED(status)) {
-        ALOG(LOG_INFO, "logwrapper", "%s terminated by signal %d", btag,
-                WTERMSIG(status));
-    } else if (WIFSTOPPED(status)) {
-        ALOG(LOG_INFO, "logwrapper", "%s stopped by signal %d", btag,
-                WSTOPSIG(status));
+        if (chld_sts == NULL)
+            rc = WEXITSTATUS(status);
+    } else {
+        if (chld_sts == NULL)
+            rc = -ECHILD;
+        if (WIFSIGNALED(status))
+            ALOG(LOG_INFO, "logwrapper", "%s terminated by signal %d", btag,
+                    WTERMSIG(status));
+        else if (WIFSTOPPED(status))
+            ALOG(LOG_INFO, "logwrapper", "%s stopped by signal %d", btag,
+                    WSTOPSIG(status));
     }
     if (chld_sts != NULL)
         *chld_sts = status;