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*/ thread_id BTeamDebugger::_LoadProgram(const char* const* args, int32 argCount, bool traceLoading) { // clone the argument vector so that we can change it const char** mutableArgs = new const char*[argCount]; for (int i = 0; i < argCount; i++) mutableArgs[i] = args[i]; // resolve the program path BPath programPath; status_t error = _FindProgram(args[0], programPath); if (error != B_OK) { delete[] mutableArgs; return error; } mutableArgs[0] = programPath.Path(); // count environment variables int32 envCount = 0; while (environ[envCount] != NULL) envCount++; // flatten the program args and environment char** flatArgs = NULL; size_t flatArgsSize; error = __flatten_process_args(mutableArgs, argCount, environ, &envCount, mutableArgs[0], &flatArgs, &flatArgsSize); // load the program thread_id thread; if (error == B_OK) { thread = _kern_load_image(flatArgs, flatArgsSize, argCount, envCount, B_NORMAL_PRIORITY, (traceLoading ? 0 : B_WAIT_TILL_LOADED), -1, 0); free(flatArgs); } else thread = error; delete[] mutableArgs; 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; }