thread_id load_image(int32 argCount, const char **args, const char **environ) { char invoker[B_FILE_NAME_LENGTH]; char **newArgs = NULL; int32 envCount = 0; thread_id thread; if (argCount < 1 || environ == NULL) return B_BAD_VALUE; // test validity of executable + support for scripts { status_t status = __test_executable(args[0], invoker); if (status < B_OK) return status; if (invoker[0]) { status = __parse_invoke_line(invoker, &newArgs, (char * const **)&args, &argCount, args[0]); if (status < B_OK) return status; } } // count environment variables while (environ[envCount] != NULL) envCount++; char** flatArgs = NULL; size_t flatArgsSize; status_t status = __flatten_process_args(args, argCount, environ, envCount, &flatArgs, &flatArgsSize); if (status == B_OK) { thread = _kern_load_image(flatArgs, flatArgsSize, argCount, envCount, B_NORMAL_PRIORITY, B_WAIT_TILL_LOADED, -1, 0); free(flatArgs); } else thread = status; free(newArgs); return thread; }
static int do_exec(const char* path, char* const args[], char* const environment[], bool useDefaultInterpreter) { if (path == NULL || args == NULL) { __set_errno(B_BAD_VALUE); return -1; } // Count argument/environment list entries here, we don't want // to do this in the kernel int32 argCount = 0; while (args[argCount] != NULL) { argCount++; } int32 envCount = 0; if (environment != NULL) { while (environment[envCount] != NULL) { envCount++; } } if (argCount == 0) { // we need some more info on what to do... __set_errno(B_BAD_VALUE); return -1; } // Test validity of executable + support for scripts char invoker[B_FILE_NAME_LENGTH]; status_t status = __test_executable(path, invoker); if (status < B_OK) { if (status == B_NOT_AN_EXECUTABLE && useDefaultInterpreter) { strcpy(invoker, "/bin/sh"); status = B_OK; } else { __set_errno(status); return -1; } } char** newArgs = NULL; if (invoker[0] != '\0') { status = __parse_invoke_line(invoker, &newArgs, &args, &argCount, path); if (status < B_OK) { __set_errno(status); return -1; } path = newArgs[0]; } char** flatArgs = NULL; size_t flatArgsSize; status = __flatten_process_args(newArgs ? newArgs : args, argCount, environment, &envCount, path, &flatArgs, &flatArgsSize); if (status == B_OK) { __set_errno(_kern_exec(path, flatArgs, flatArgsSize, argCount, envCount, __gUmask)); // if this call returns, something definitely went wrong free(flatArgs); } else __set_errno(status); free(newArgs); return -1; }