Fix WSLC exec hang on fast runc failure (e.g. invalid user/group) (#40550)
WSLCContainerImpl::Exec polls Docker's exec inspect endpoint after StartExec to learn whether the user process is running or has already failed. The Running branch was guarded by `state.Pid.has_value()`, which is meaningless because Docker's wire schema declares Pid as a non-nullable Go int that is 0 until runc forks the user process - so the JSON always contains `"Pid": 0` and nlohmann always deserializes that as `optional<int>(0)` with `has_value() == true`. When runc fails before forking (e.g. `-u root:badgid`), Docker briefly reports `{Running: true, Pid: 0, ExitCode: null}` in the window between logging the error and running its deferred cleanup that sets `Running=false, ExitCode=126`. The polling loop accepted Pid=0 as a valid PID, called SetPid(0), broke out, and returned the process to wslc. wslc then waited on the exit event forever, because Docker never emits an `exec_die` event when the user process never spawned. Change InspectExec.Pid from `std::optional<int>` to `int` to match the wire format, and check `state.Pid > 0` at the call site. With this change the loop continues polling on Pid=0; on the next iteration Docker has settled state and the existing ExitCode branch fires with the correct exit code (126). Verified against the failing test WSLCE2EContainerExecTests::WSLCE2E_Container_Exec_UserOption_InvalidGroup_Fails, which is the regression test for this bug. Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>