LinuxCore 0.4.10

dotnet add package LinuxCore --version 0.4.10
                    
NuGet\Install-Package LinuxCore -Version 0.4.10
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="LinuxCore" Version="0.4.10" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LinuxCore" Version="0.4.10" />
                    
Directory.Packages.props
<PackageReference Include="LinuxCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add LinuxCore --version 0.4.10
                    
#r "nuget: LinuxCore, 0.4.10"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package LinuxCore@0.4.10
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=LinuxCore&version=0.4.10
                    
Install as a Cake Addin
#tool nuget:?package=LinuxCore&version=0.4.10
                    
Install as a Cake Tool

LinuxCore

A thin, AOT-compatible .NET wrapper around Linux libc APIs and raw kernel interfaces. Provides ergonomic, low-allocation C# abstractions for files, sockets, events, polling, scheduling, and more.

LinuxCore release LinuxCore download count

Features

  • File I/OLinuxFile for open/read/write/seek/statx with Span<byte> support
  • Memory FilesLinuxMemoryFile for memfd_create and memfd seals via fcntl
  • Memory MapsLinuxMemoryMap/LinuxReadOnlyMemoryMap for mmap/munmap with Span<byte>/Memory<byte> access
  • Events & SemaphoresLinuxEvent and LinuxSemaphore backed by eventfd
  • PollingLinuxPoll for poll()-based readiness notification
  • ClocksLinuxClock for nanosecond-precision monotonic, boottime, CPU-time, and wall-clock (CLOCK_REALTIME) timestamps and high-precision sleeps
  • SchedulingLinuxScheduler for sched_setscheduler/sched_getscheduler (FIFO, RR, etc.)
  • Resource LimitsLinuxResourceLimit for getrlimit/setrlimit
  • CancellationLinuxCancellationToken bridges CancellationToken to native poll
  • SocketsUnixSocket for AF_UNIX sockets and LinuxSocketBase for shared raw socket operations
  • System ConfigurationSystemConfiguration for sysconf() queries (page size, max open files, etc.)
  • Users & GroupsLinuxUser and LinuxGroup for passwd/group lookups by name or ID
  • ProcessesLinuxProcess for posix_spawnp, environment and standard-stream redirection, and cancellable pidfd waiting

Requirements

  • Linux (the library is annotated with [SupportedOSPlatform("linux")])
  • .NET 10+
  • Linux 4.11+ for LinuxFile metadata via statx
  • glibc 2.28+ (2.34+ on 32-bit architectures) or musl 1.2.5+ for the remaining libc and time64 entry points
  • Linux 5.3+ for LinuxProcess pidfd waiting

Architecture

The library has two layers:

  • LinuxCore.Interop — internal native bindings. Most files map to libc subsystems through source-generated [LibraryImport]; file operations, memory-map operations, memfd_create, and eventfd2 use libc syscall() with numbers from SystemCallTable. Numbers that are stable across supported architectures are exposed as static members. Numbers that vary but are available everywhere are abstract members implemented by each architecture table; calls available only on an architecture subset may use virtual members that throw elsewhere. Callers should use SystemCallTable.Current.
  • LinuxCore — public API types wrapping the interop layer with safe-ish, idiomatic C# APIs.

File-descriptor-owning types follow this hierarchy:

NativeObject (IDisposable + Finalizer)
  └─ FileObject (FileDescriptor, shared I/O and descriptor-control helpers)
       ├─ LinuxEventBase → LinuxEvent, LinuxSemaphore
       ├─ LinuxSocketBase → UnixSocket
       └─ LinuxFile → LinuxMemoryFile

LinuxSecurityObject (Id + Name)
  ├─ LinuxUser
  └─ LinuxGroup

Operational notes

  • LinuxScheduler.Set(...) and some LinuxResourceLimit.Set(...) calls may require root privileges or Linux capabilities such as CAP_SYS_NICE / CAP_SYS_RESOURCE.
  • AF_UNIX pathname sockets are subject to the kernel sockaddr_un.sun_path limit (108 bytes on Linux).
  • FileDescriptor is an allocation-free, non-owning value. Copying it or reading FileObject.Descriptor does not duplicate the descriptor or retain its lifetime; use Clone() for an independent descriptor. FileObject intentionally avoids per-operation lifetime leasing, so callers must keep the owner strongly reachable and prevent concurrent disposal or external closure while operations or raw descriptors are in use. Closed or stale descriptor values may refer to unrelated resources after Linux recycles the number.
  • File operations, memory-map operations, memfd_create, and eventfd2 dispatch through libc syscall() rather than dedicated libc symbols. They therefore use raw kernel semantics without libc cancellation points, musl close/AIO or virtual-memory synchronization, old-kernel O_CLOEXEC/fcntl fallbacks, special fcntl emulation, or 32-bit time64 ioctl translation. Dedicated-symbol interposition such as LD_PRELOAD hooks for open, read, write, mmap, munmap, msync, memfd_create, or eventfd is bypassed. Seccomp profiles must allow the architecture-specific calls, including openat, mmap on 64-bit architectures, mmap2 on 32-bit x86 and Arm, munmap, msync, memfd_create, and eventfd2, plus fcntl64/_llseek on 32-bit x86 and Arm. On s390x, the kernel mmap ABI accepts one packed argument block; glibc callers must pack it, while musl's public syscall() wrapper packs six scalar arguments internally. FileDescriptor.Close() ignores close errors and must not be retried after EINTR.
  • Generic ReceiveMessage methods return only the requested control-message type and do not close resources from nonmatching messages. On Unix sockets, use ReceiveFileDescriptors when an SCM_RIGHTS message may be present.
  • On QEMU linux-user, ReceiveFileDescriptors requires SO_PASSPIDFD and SO_PASSSEC to be disabled. Either option can cause host-side descriptors to be omitted during ancillary conversion and remain open. LinuxCore does not enable either option.
  • LinuxFileFlags and LinuxMemoryMapFlags values are stable managed tokens. LinuxCore translates architecture-dependent file flags on Arm and PowerPC, and mapping flags on PowerPC, before calling libc.
  • CI runs the full test suite on every target. Alpine x64 and arm64 plus Arm32 glibc and musl build and test inside native SDK containers; ppc64le, s390x, RISC-V64, and LoongArch64 run host-built portable test output under QEMU. All targets gate publishing. The RISC-V64 and LoongArch64 matrix entries use community runtimes because Microsoft does not publish supported .NET 10 runtimes for those architectures or support QEMU execution.
  • NativeAOT compatibility is exercised in CI on both glibc (Ubuntu) and musl (Alpine) runners via a small smoke app.
  • LinuxProcess cancellation stops only the wait; it does not terminate the child. Callers must successfully wait and reap the child before disposal. Process waits, disposal, supplied-descriptor mutation, native-environment mutation, and external child reaping must not race. A replacement child environment does not control posix_spawnp executable lookup on supported glibc and musl versions; pass a path containing / when lookup must not use the native parent PATH.

Contributing

Every new or changed constant that represents a libc or Linux kernel value must include a CScript assertion against the current platform's native headers in the corresponding subsystem test file. Include explicit mappings for enum aliases and composite values. For architecture-dependent managed tokens such as LinuxFileFlags and LinuxMemoryMapFlags, assert the translated native value instead of the managed numeric token. Use optional-symbol assertions only when supported header versions genuinely omit the symbol.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on LinuxCore:

Package Downloads
NetNsCore

Linux network namespace utilities

LibNlCore

NETLINK .NET wrappers

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.10 71 8/19/2026
0.4.9 66 8/18/2026
0.4.8 78 8/18/2026
0.4.7 68 8/17/2026
0.4.6 76 8/14/2026
0.4.5 71 8/14/2026
0.4.4 72 8/13/2026
0.4.3 71 8/11/2026
0.4.2 65 8/5/2026
0.4.1 73 8/4/2026
0.4.0 70 8/4/2026
0.3.12 76 7/16/2026
0.3.11 74 7/15/2026
0.3.10 143 6/26/2026
0.3.9 83 6/26/2026
0.3.8 78 6/26/2026
0.3.7 95 6/26/2026
0.3.6 102 6/22/2026
0.3.5 100 6/11/2026
0.3.4 85 5/25/2026
Loading failed