Fix execvpe ENOEXEC behavior.

The special case for absolute paths wasn't handling ENOEXEC.

Also add more extensive tests for execvpe.

Also switch to manually doing the fork in ExecTestHelper::Run because
ASSERT_EXIT doesn't actually return, meaning we were only running the
first part of each test.

Bug: http://b/31073104
Change-Id: I7a4640afc6d290c51ba2e66fc1b9bb6b0fc174f7
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index c1e73a5..354f931 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -95,15 +95,15 @@
   return execvpe(name, argv, environ);
 }
 
-static int __exec_as_script(char* buf, char* const* argv, char* const* envp) {
-  size_t arg_count = 0;
+static int __exec_as_script(const char* buf, char* const* argv, char* const* envp) {
+  size_t arg_count = 1;
   while (argv[arg_count] != nullptr) ++arg_count;
 
-  char* script_argv[arg_count + 2];
-  script_argv[0] = const_cast<char*>("sh");
+  const char* script_argv[arg_count + 2];
+  script_argv[0] = "sh";
   script_argv[1] = buf;
-  bcopy(argv + 1, script_argv + 2, arg_count * sizeof(char*));
-  return execve(_PATH_BSHELL, script_argv, envp);
+  memcpy(script_argv + 2, argv + 1, arg_count * sizeof(char*));
+  return execve(_PATH_BSHELL, const_cast<char**>(script_argv), envp);
 }
 
 int execvpe(const char* name, char* const* argv, char* const* envp) {
@@ -114,7 +114,9 @@
   }
 
   // If it's an absolute or relative path name, it's easy.
-  if (strchr(name, '/')) return execve(name, argv, envp);
+  if (strchr(name, '/') && execve(name, argv, envp) == -1) {
+    return __exec_as_script(name, argv, envp);
+  }
 
   // Get the path we're searching.
   const char* path = getenv("PATH");