Skip to content

Implement SafeProcessHandle APIs for Linux and other Unixes#124979

Draft
Copilot wants to merge 4 commits intocopilot/implement-safeprocesshandle-apisfrom
copilot/implement-safeprocesshandle-apis-again
Draft

Implement SafeProcessHandle APIs for Linux and other Unixes#124979
Copilot wants to merge 4 commits intocopilot/implement-safeprocesshandle-apisfrom
copilot/implement-safeprocesshandle-apis-again

Conversation

Copy link
Contributor

Copilot AI commented Feb 27, 2026

  • Update src/native/libs/configure.cmake with new feature detection checks for Linux (clone3, pidfd_send_signal, close_range, pdeathsig, sys_tgkill)
  • Update src/native/libs/Common/pal_config.h.in with new #cmakedefine01 entries for the new features
  • Update src/native/libs/System.Native/pal_process.c:
    • Add necessary includes for sys/syscall.h, linux/sched.h, sys/prctl.h
    • Define HAVE_PIDFD when HAVE_CLONE3 is available
    • Replace the #else (ENOTSUP) branch in SystemNative_SpawnProcess with fork/exec path using clone3/fork/vfork
    • Update SystemNative_SendSignal to use pidfd_send_signal when available
    • Add pidfd-based map_wait_status_pidfd using siginfo_t for pidfd path
    • Update SystemNative_TryGetExitCode to use waitid(P_PIDFD) when pidfd available
    • Update SystemNative_WaitForExitAndReap to use waitid(P_PIDFD) when pidfd available
    • Update SystemNative_TryWaitForExitCancellable to use poll with pidfd when available
    • Update SystemNative_TryWaitForExit to use poll with pidfd when available
    • Update SystemNative_OpenProcess to use waitid verification and pidfd_open when available
  • Update test files:
    • Change SafeProcessHandleTests.Unix.cs from [PlatformSpecific(TestPlatforms.OSX)] to [PlatformSpecific(TestPlatforms.AnyUnix)]
    • Change SafeProcessHandleTests.cs from [PlatformSpecific(TestPlatforms.OSX | TestPlatforms.Windows)] to [PlatformSpecific(TestPlatforms.AnyUnix | TestPlatforms.Windows)]
  • Native code compiles successfully
  • All 395 tests pass (0 failures), including all 23 SafeProcessHandle tests
  • Address review feedback: consolidate sys/syscall.h includes

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copy link
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot So far I've found only one nit.

Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement SafeProcessHandle APIs for other Unixes Implement SafeProcessHandle APIs for Linux and other Unixes Feb 27, 2026
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
@tmds
Copy link
Member

tmds commented Mar 4, 2026

We configure the terminal for Console. For child processes, this caused issues in the past because they assume the terminal to be in the "default" state (for example: echoing).

Process class (on Unix) calls ConfigureTerminalForChildProcesses to give child processes a terminal in the "default" state, and when there are no more children that use the terminal, the function is called to set the terminal back to the "Console" state.

SafeProcessHandle isn't doing this yet.

For more info, see dotnet/corefx#35621.

@tmds
Copy link
Member

tmds commented Mar 4, 2026

Some other Process behavior to be aware of:

  • When Process.Unix gets SIGCHLD but doesn't know the child it does this:

else
{
// unlikely: This is not a managed Process, so we are not responsible for reaping.
// Fall back to checking all Processes.
checkAll = true;
break;
}

Exit of SafeProcessHandle managed children will trigger this behavior.

  • Different Process instances for the same child process share information of the exit code. SafeProcessHandle doesn't implement this. I assume this is intentional for performance reasons.

@tmds
Copy link
Member

tmds commented Mar 4, 2026

The SafeProcessHandle itself doesn't ensure kernel resources are released.

Consider:

using handle = SafeChildProcessHandle.Start(...);
...
if (!handle.TryWaitForExit(TimeSpan.FromSeconds(1), out _)
   handle.Kill();

If we're in the case where the child process is killed nothing calls waitpid on the killed child. Its kernel resources won't be returned until the .NET process itself terminates.

We added the SIGCHLD handling to deal with this issue for Process (dotnet/corefx#26291).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants