Migrate libpsl-native to managed/libc P/Invoke#27668
Draft
adityapatwardhan wants to merge 5 commits into
Draft
Conversation
Replace the low-risk libpsl-native functions (those not requiring
stat/passwd struct marshalling) with pure managed code and direct
LibraryImport("libc") calls, following the engine/Interop/Windows
convention with a parallel engine/Interop/Unix folder.
Migrated:
- GetErrorCategory -> managed errno->ErrorCategory table
- CreateSymLink/CreateHardLink -> libc symlink/link
- IsExecutable -> libc access(path, X_OK)
- KillProcess -> libc kill(pid, SIGKILL)
- WaitPid -> libc waitpid
- GetCurrentThreadId -> libc gettid (Linux) / pthread_threadid_np (macOS)
- SetDate -> libc settimeofday (via DateTimeOffset; drops UnixTm struct)
- Syslog Open/SysLog/Close -> libc openlog/syslog/closelog
Interop.Unix is compiled only on non-Windows (per csproj), so the
consuming bodies in CorePsPlatform are guarded with #if UNIX. The
remaining libpsl-native imports (stat, passwd/group, GetUserFromPid,
ForkAndExecProcess) are deferred to later phases.
Verified: Windows build and cross-compiled linux-x64 build both pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
… managed libc Replace remaining libpsl-native P/Invokes with direct libc calls: - Stat.cs: architecture-independent Linux statx(2) and macOS 64-bit-inode stat/lstat, exposed as a normalized StatInfo. Wires GetCommonStat, GetCommonLStat, GetLinkCount, GetInodeData, IsSameFileSystemItem. - UserGroup.cs: getpwuid_r/getgrgid_r name resolution (GetPwUid, GetGrGid). - Process.cs: macOS proc_pidinfo helpers for GetPPid and GetUserFromPid. - CorePsPlatform.cs: all remaining psLib imports removed; migrated methods guarded with #if UNIX and #else PlatformNotSupportedException stubs so the Windows build (which excludes engine/Interop/Unix) still compiles. Compile-verified on Windows and cross-compiled linux-x64. Runtime testing on Linux/macOS still required (struct offsets, macOS symbol dispatch). Only ForkAndExecProcess (Phase 3) still uses libpsl-native. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Phase 1 syslog migration used POSIX syslog() on all Unix platforms per the
migration plan's simplicity recommendation. On macOS this broke Logging.Tests:
POSIX syslog() does not set the os_log subsystem/category, so 'log show' entries
never match the test's "category -eq $logId" filter and no items are returned.
Restore the native (libpsl-native nativesyslog.cpp) behavior on macOS by logging
through the unified logging system:
- os_log_create("com.microsoft.powershell", ident) sets subsystem + category.
- _os_log_impl(...) is invoked with a hand-built argument buffer equivalent to
what the os_log compiler macro emits for a single "%{public}s" argument.
- Severity is mapped to os_log_type_t (fault/error/debug/default) matching the
native switch. Linux continues to use POSIX syslog().
NOTE: os_log is normally a compiler-macro API; the _os_log_impl + DSO/format-string
path is compile-verified only (host is Windows). macOS CI (Logging.Tests.ps1) must
confirm 'log show' renders the eventMessage.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…uture phase
POSIX syslog() is not a valid substitute for os_log on macOS: Host/Logging.Tests.ps1
reads entries via 'log show --style json' and filters on the os_log category (= logId)
and messageType "Default". syslog() sets no category, so no entries match.
A pure-managed os_log (os_log_create + hand-rolled _os_log_impl) compiles and sets the
category correctly, but 'log show' renders a compose failure because os_log requires the
format string to be a compile-time constant located in a Mach-O __TEXT,__os_log section;
a runtime/heap format string is not resolvable by logd. This is why mature FFI bindings
ship a small C shim.
Interim resolution:
- Linux: managed libc syslog (unchanged).
- macOS: route OpenLog/SysLog/CloseLog back to libpsl-native
Native_OpenLog/Native_SysLog/Native_CloseLog.
A dedicated macOS os_log shim (compiled during the macOS build with a literal
"%{public}s" format) is documented as a future migration phase; it will let the
libpsl-native logging dependency be removed on macOS as well.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Phase 3)
Replace the libpsl-native ForkAndExecProcess P/Invoke used by SSH based
remoting with a pure-managed implementation over libc posix_spawn(3).
- Add engine/Interop/Unix/Spawn.cs: Interop.Unix.SpawnProcess sets up
close-on-exec pipes for the requested stdin/stdout/stderr redirections,
builds posix_spawn file actions (adddup2, addchdir_np) and attributes,
and spawns the child. posix_spawn is used instead of a hand-rolled
fork/execve because running managed code between fork and exec is unsafe.
- Preserve SUPPRESS_PROCESS_SIGINT semantics via POSIX_SPAWN_SETSID so the
SSH child runs in its own session and terminal Ctrl+C (SIGINT) does not
propagate to it (flag value differs per OS: Linux 0x0080, macOS 0x0400).
- RunspaceConnectionInfo.StartSSHProcess now calls Interop.Unix.SpawnProcess;
remove the now-dead CreateProcess, ForkAndExecProcess DllImport,
AllocNullTerminatedArray, FreeArray and the SUPPRESS_PROCESS_SIGINT const.
This removes the last real [DllImport("libpsl-native")] P/Invoke; only the
macOS os_log syslog path remains (deferred to a future phase).
Compile-verified on Windows and cross-compiled linux-x64. Not runtime-tested;
SSH remoting startup, stream redirection, and Ctrl+C isolation should be
validated on Linux and macOS.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
iSazonov
reviewed
Jul 14, 2026
| private static partial int Close(int fd); | ||
|
|
||
| [LibraryImport("libc", EntryPoint = "posix_spawn", StringMarshalling = StringMarshalling.Utf8)] | ||
| private static unsafe partial int PosixSpawn(out int pid, string path, IntPtr fileActions, IntPtr attr, byte** argv, byte** envp); |
Collaborator
There was a problem hiding this comment.
Now in .Net 11 we have StartDetached
Implementation is used PosixSpawn
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replace the low-risk libpsl-native functions (those not requiring stat/passwd struct marshalling) with pure managed code and direct LibraryImport("libc") calls, following the engine/Interop/Windows convention with a parallel engine/Interop/Unix folder.
Migrated:
Interop.Unix is compiled only on non-Windows (per csproj), so the consuming bodies in CorePsPlatform are guarded with #if UNIX. The remaining libpsl-native imports (stat, passwd/group, GetUserFromPid, ForkAndExecProcess) are deferred to later phases.
Verified: Windows build and cross-compiled linux-x64 build both pass.
PR Summary
PR Context
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright header