Linux v0.1.0
Installation
Add Linux to the [Dependencies] table of your package's Rux.toml:
[Dependencies]
Linux = { Namespace = "Rux", Version = "0.1.0" }
Standard packages are declared by hand: the registry does not serve them, so rux add Rux/Linux cannot add them.
Dependencies
Core0.1.0
Guide
Linux platform bindings: the raw syscall interface, with no libc in between.
What it provides
| Module | Covers |
|---|---|
Types | the kernel ABI's own types: ProcessId, FileDescriptor, FileOffset, FileMode, UserId, Timespec |
Errors | the errno numbers, and IsError / Errno for reading a raw result |
Syscall | Syscall0 through Syscall6 as inline assembly, the call numbers, and SignExtendFd |
File | Read, Write, Close, OpenAt, Lseek, Fsync, Ftruncate, UnlinkAt, MkdirAt, RenameAt, Fstat, FstatAt, Dup3, Pipe2, the open flags, and the three standard descriptors |
Memory | Mmap, Munmap, Brk, Mprotect, Madvise, QueryPageSize, and the protection, mapping and advice flags |
Clock | ClockGetTime, ClockGetResolution, Nanosleep, ClockNanosleep, and the clock identifiers |
Process | Exit and GetPid |
Entropy | GetRandom, the only source here fit for a key or a token |
Dynamic | dlopen, dlsym, dlclose, dlerror, and the RTLD_* flags |
Thread | pthread_create, pthread_join, pthread_detach, the pthread_attr_* stack-size calls, sched_yield, sysconf and SC_NPROCESSORS_ONLN, and gettid, linked from libc |
Socket | Socket, Connect, Bind, Listen, Accept4, SendTo, ReceiveFrom, Shutdown, SetSocketOption, GetSocketName and GetPeerName as system calls, with the address families, socket options and MSG_NOSIGNAL |
Resolve | getaddrinfo, freeaddrinfo and AddressInfo, linked from libc |
Futex | FutexWait and FutexWake, the private futex(2) operations every lock in Rux/Sync sleeps on |
Spawn | posix_spawnp, the posix_spawn_file_actions_* calls, waitpid, kill, fcntl and __errno_location, linked from libc |
Poll | EpollCreate1, EpollControl and EpollWait as system calls, the EPOLL* flags, the per-architecture epoll_event layout, and FcntlInt with F_GETFL, F_SETFL and O_NONBLOCK |
The module names describe where each declaration comes from; they are not part of an import path.
There is no errno here. The kernel returns the error in the result register as a small negative number, and libc is what turns that into a positive errno and a -1 return. This package calls the kernel directly, so a caller tests a raw result with IsError and reads the number with Errno. Only -4095 through -1 is an error, which is what makes Mmap workable: a mapping address may legitimately have its top bit set.
Only calls both architectures have are wrapped. AArch64 came after the directory-relative interface and never got open, stat, unlink, mkdir, rename, dup2 or pipe, so this package offers the *at forms alone and AtFdCwd is what makes an ordinary path work through them. One wrapper is then right on both.
The errno numbers and the RTLD_* flags keep the kernel's own spelling, because EINVAL is what a man page names and what a reader porting code will look for. The rest of the constants use Rux names, which is what they were published under.
QueryPageSize is the one wrapper here that is not a system call. Linux publishes the page size in the auxiliary vector the kernel hands to a new process, which libc captures at startup and answers from; this package captures nothing at startup, so it reads the same vector through /proc/self/auxv. That costs an open, a read and a close, and it reports the open's own error number when /proc is not there — which is ordinary in a container and is why the call is fallible rather than answering 4096 and hoping.
The shared POSIX contract
Nothing here is interchangeable with the other POSIX packages, but the three are spelled the same, which is a different claim and a deliberate one. An equivalent call has the same wrapper name, the same parameter names and the same parameter shapes on all three systems, so a consumer such as Rux/FileSystem or Rux/Time writes one call site instead of a when #target.os ladder around three names for one idea. Tests/Unit/PlatformBindingContractTests.cpp compares the three packages' parsed sources and fails when they drift apart.
The values are the opposite: every constant is this system's own, and the same file asserts that the ones a reader might carry across really do differ.
What is tested
Tests/Packages/Linux/Descriptors covers descriptor numbering, short reads and writes, end of file, size boundaries and the native error for each way of misusing a descriptor or a name. Tests/Packages/Linux/Mapping covers anonymous mappings, protection changes, advice, the requests the kernel refuses, and both edges of the reserved error-result window. Tests/Packages/Linux/Syscall covers the wrapper surface and the shared POSIX contract.
All of it compiles for both architectures, and none of it has ever run on a host that is not Linux. Until it does, the syscall numbers, flag values and errno constants here rest on published documentation rather than on a passing test.
Values and pointers
Kernel records such as Timespec are structural values and copy by value. Syscall wrappers deliberately retain raw pointers: the kernel receives untyped integer addresses, buffers carry separate byte counts, and optional outputs may be null. Callers must therefore pass explicit addresses such as ClockGetTime(ClockMonotonic, @time) and uphold each function's safety contract. No wrapper owns an address or descriptor; release mappings and close descriptors explicitly, or prefer the higher-level Rux/Memory and Rux/Io packages.
Platform
Linux only. Guard use behind a compile-time check, so a build for another target never resolves these declarations:
import Core::{ #target };
when #target.os == .Linux {
import Linux::{ StdOut, Write };
}
Index
Types
| Name | Summary |
|---|---|
AddressInfo | The C library's addrinfo: one result of getaddrinfo, linked to the next. |
SpawnFileActions | Room for a posix_spawn_file_actions_t, which each C library sizes its own way and none larger than this. |
PThread | A thread as the C library names it, pthread_t. |
PThreadAttributes | Room for a pthread_attr_t, which each C library sizes its own way and none larger than this. |
ProcessId | A process identifier, as getpid and its relatives report one. |
FileDescriptor | A file descriptor, as the kernel numbers one. |
FileOffset | A byte offset within a file, which the 64-bit ABI makes 64 bits everywhere. |
FileMode | A file's type and permission bits, as open and stat carry them. |
UserId | A user identifier. |
GroupId | A group identifier. |
Timespec | A duration or an instant, as seconds and nanoseconds. |
Functions
| Name | Summary |
|---|---|
ClockGetTime | Reads clockId into time. |
Nanosleep | Suspends the caller for the requested duration. |
ClockGetResolution | Reads the resolution of clockId into resolution. |
ClockNanosleep | Suspends the caller against a named clock, optionally until an absolute time. |
dlopen | Loads a shared object and returns a handle to it, or null on failure. |
dlsym | Finds a symbol in a loaded object and returns its address, or null. |
dlclose | Drops one reference to a loaded object, unloading it when the last one goes. |
dlerror | Reports the most recent loader error and clears it, or returns null when there is none. |
GetRandom | Fills up to length bytes of buffer with unpredictable bytes. |
IsError | Whether a raw system-call result is one of the kernel's reserved error values. |
Errno | The error number a raw system-call result carries, or zero when it carries none. |
Read | Reads up to count bytes from fd into buffer. |
Write | Writes up to count bytes from buffer to fd. |
Close | Closes fd and releases what the kernel held for it. |
OpenAt | Opens path relative to directoryFd and returns a descriptor, or a negative error number. |
Lseek | Moves the file offset of fd and returns where it ended up, or a negative error number. |
Getdents64 | Reads directory entries from fd into buffer, and returns the bytes filled, zero at the end, or a negative error number. |
LinkAt | Creates a hard link: newPath becomes a second name for the file oldPath names. |
SymlinkAt | Creates a symbolic link at linkPath holding target as its text. |
FstatAt | Fills statBuffer with what the kernel knows about the file path names. |
FchmodAt | Sets the permission bits of the file path names. |
UtimensAt | Sets the access and modification times of the file path names. |
Getcwd | Writes the current working directory's absolute path into buffer, NUL-terminated. |
Chdir | Makes path the process's working directory. |
ReadlinkAt | Reads the text a symbolic link holds into buffer. |
Fsync | Flushes everything written to fd through to the storage device. |
Ftruncate | Sets the length of the file behind fd to length. |
UnlinkAt | Removes the name path from its directory. |
MkdirAt | Creates a directory named path with permission bits mode. |
RenameAt | Renames oldPath to newPath, each resolved against its own directory descriptor. |
Fstat | Fills statBuffer with what the kernel knows about the file behind fd. |
Dup3 | Makes newFd a copy of oldFd, closing whatever newFd was. |
Pipe2 | Creates a pipe and writes its two descriptors into descriptors. |
FutexWait | Sleeps while *address equals expected, until a wake, a signal or the timeout. |
FutexWake | Wakes up to count threads sleeping on address. |
Mmap | Creates a mapping and returns its address, or a negative error number. |
Munmap | Releases the mapping that begins at address and spans length bytes. |
Brk | Sets the program break and returns where it ended up. |
Mprotect | Changes what may be done with the pages covering address through address + length. |
Madvise | Tells the kernel how the pages covering a range are about to be used. |
QueryPageSize | The size of a page, read out of this process's auxiliary vector. |
FcntlInt | Performs command on a descriptor with an integer argument. |
EpollCreate1 | Opens an epoll instance. |
EpollControl | Adds, changes or removes the registration of fd with an epoll instance. |
EpollWait | Waits until a registered descriptor is ready or timeout milliseconds pass, filling events with what is ready. |
Exit | Ends the calling thread's process with code. |
GetPid | The calling process's own identifier. |
getaddrinfo | Looks up the addresses of a host and service. |
freeaddrinfo | Frees the results of getaddrinfo. |
Socket | Opens a socket. |
Connect | Connects a socket to address, waiting for a stream connection to be made. |
Bind | Gives a socket its local address. |
Listen | Makes a bound stream socket accept connections. |
Accept4 | Accepts a waiting connection as a new socket. |
SendTo | Sends bytes on a socket, to address when it is not connected. |
ReceiveFrom | Receives bytes from a socket, and where they came from. |
Shutdown | Ends one or both directions of a connection. |
SetSocketOption | Sets a socket option. |
GetSocketName | Reads a socket's local address. |
GetPeerName | Reads the address of a connected socket's peer. |
posix_spawnp | Starts file, found through PATH when it has no slash, as a child process. |
posix_spawn_file_actions_init | Initializes an empty list of file actions. |
posix_spawn_file_actions_destroy | Releases what posix_spawn_file_actions_init and the actions added since set up. |
posix_spawn_file_actions_adddup2 | Adds an action duplicating fd onto newFd in the child. |
posix_spawn_file_actions_addopen | Adds an action opening path as fd in the child. |
posix_spawn_file_actions_addchdir_np | Adds an action changing the child's working directory to path. |
waitpid | Waits for a child to change state, and reports how it finished. |
kill | Sends a signal to a process. |
fcntl | Performs a control operation on a descriptor, such as setting its flags with F_SETFD. |
__errno_location | Returns the address of the calling thread's errno, where the C library calls above leave their reason. |
Syscall0 | Executes a raw Linux system call without arguments. |
Syscall6 | Executes a raw Linux system call with six arguments. |
SignExtendFd | Widens a file descriptor to the register width a system call takes it in. |
pthread_create | Starts a thread running start(argument). |
pthread_join | Waits for a thread to finish and releases it. |
pthread_detach | Lets a thread release itself when it finishes, so nothing has to join it. |
pthread_attr_init | Initializes thread attributes to the defaults. |
pthread_attr_setstacksize | Sets the stack size a thread started with these attributes gets. |
pthread_attr_destroy | Releases what pthread_attr_init set up. |
gettid | Returns the kernel's identifier for the calling thread, which is the process identifier on its first thread. |
sched_yield | Gives up the processor so another ready thread can run. |
sysconf | Reads a system configuration value. |
Constants
| Name | Summary |
|---|---|
ClockRealtime | CLOCK_REALTIME: wall-clock time, which can jump when the system clock is set. |
ClockMonotonic | CLOCK_MONOTONIC: time since an unspecified point, which never goes backwards. |
ClockProcessCpuTime | CLOCK_PROCESS_CPUTIME_ID: processor time this process has used. |
ClockThreadCpuTime | CLOCK_THREAD_CPUTIME_ID: processor time this thread has used. |
ClockMonotonicRaw | CLOCK_MONOTONIC_RAW: like ClockMonotonic, but not adjusted by time synchronization. |
TimerAbsolute | TIMER_ABSTIME: ClockNanosleep should treat its time as an absolute deadline. |
RTLD_LAZY | RTLD_LAZY: resolve a function symbol the first time it is called rather than at load. |
RTLD_NOW | RTLD_NOW: resolve every symbol before dlopen returns, so a missing one is reported there. |
RTLD_GLOBAL | RTLD_GLOBAL: make this object's symbols available to objects loaded afterwards. |
RTLD_LOCAL | RTLD_LOCAL: keep this object's symbols to itself, which is the default. |
RTLD_NODELETE | RTLD_NODELETE: do not unload the object when its last reference goes, so its storage stays valid. |
RandomNonBlocking | GRND_NONBLOCK: report EAGAIN rather than waiting for the pool to be seeded. |
RandomBlockingPool | GRND_RANDOM: draw from the blocking pool, which is almost never what a caller wants. |
EPERM | EPERM: the operation is not permitted to this caller. |
ENOENT | ENOENT: no such file or directory. |
ESRCH | ESRCH: no such process. |
EINTR | EINTR: the call was interrupted by a signal before it did anything. |
EIO | EIO: a low-level input or output error. |
ENXIO | ENXIO: no such device or address. |
EBADF | EBADF: the file descriptor is not open, or is not open for what was asked. |
EAGAIN | EAGAIN: the operation would block, and the descriptor was set not to. |
ENOMEM | ENOMEM: not enough memory to satisfy the request. |
EACCES | EACCES: permission denied. |
EFAULT | EFAULT: an address the call was given is outside the caller's address space. |
EBUSY | EBUSY: the resource is in use. |
EEXIST | EEXIST: the file already exists. |
EXDEV | EXDEV: the two paths are on different file systems. |
ENOTDIR | ENOTDIR: a path component that had to be a directory is not one. |
EISDIR | EISDIR: the target is a directory and the operation is not one a directory accepts. |
EINVAL | EINVAL: an argument is not valid. |
EMFILE | EMFILE: this process has too many descriptors open. |
ENOSPC | ENOSPC: the device has no room left. |
ESPIPE | ESPIPE: the descriptor is a pipe or socket and cannot be seeked. |
EROFS | EROFS: the file system is mounted read-only. |
EPIPE | EPIPE: the reading end of the pipe is closed. |
ENAMETOOLONG | ENAMETOOLONG: the path or a component of it is too long. |
ENOSYS | ENOSYS: the kernel does not implement this call. |
ELOOP | ELOOP: too many symbolic links were followed resolving the path. |
EOVERFLOW | EOVERFLOW: a value is too large for the type the call reports it in. |
ETIMEDOUT | ETIMEDOUT: the operation timed out. |
MaximumErrno | The largest error number the kernel's reserved range holds. |
StdIn | The descriptor a process reads its input from, unless something reassigned it. |
StdOut | The descriptor a process writes its output to. |
StdErr | The descriptor a process writes its diagnostics to, which is separate so it survives a redirected output. |
AtFdCwd | AT_FDCWD: resolve a relative path against the current directory rather than a descriptor. |
OpenReadOnly | O_RDONLY: open for reading only. |
OpenWriteOnly | O_WRONLY: open for writing only. |
OpenReadWrite | O_RDWR: open for both reading and writing. |
OpenCreate | O_CREAT: create the file when it does not exist, which is when the mode argument is read. |
OpenExclusive | O_EXCL: with OpenCreate, fail rather than open a file that already exists. |
OpenTruncate | O_TRUNC: truncate the file to nothing when opening it for writing. |
OpenAppend | O_APPEND: every write goes to the end, atomically with respect to other appenders. |
OpenNonBlocking | O_NONBLOCK: reads and writes report EAGAIN rather than waiting. |
OpenCloseOnExec | O_CLOEXEC: close this descriptor automatically when the process executes a new program. |
OpenDirectory | O_DIRECTORY: fail unless the target is a directory. |
SeekSet | SEEK_SET: measure the new offset from the start of the file. |
SeekCurrent | SEEK_CUR: measure the new offset from the current one. |
SeekEnd | SEEK_END: measure the new offset from the end of the file. |
FollowSymlinks | AT_SYMLINK_FOLLOW: make LinkAt link a symbolic link's target rather than the link. |
SymlinkNoFollow | AT_SYMLINK_NOFOLLOW: act on a symbolic link itself rather than on what it points at. |
RemoveDirectory | AT_REMOVEDIR: make UnlinkAt remove a directory rather than a file. |
FutexWaitPrivate | FUTEX_WAIT_PRIVATE: sleep while the word holds the expected value. |
FutexWakePrivate | FUTEX_WAKE_PRIVATE: wake threads sleeping on the word. |
ProtectionNone | PROT_NONE: the pages may not be touched at all. |
ProtectionRead | PROT_READ: the pages may be read. |
ProtectionWrite | PROT_WRITE: the pages may be written. |
ProtectionExecute | PROT_EXEC: the pages may be executed. |
MapShared | MAP_SHARED: writes are visible to other mappings of the same object and reach it. |
MapPrivate | MAP_PRIVATE: writes are private to this mapping and never reach the object. |
MapFixed | MAP_FIXED: place the mapping exactly at the requested address, replacing whatever was there. |
MapAnonymous | MAP_ANONYMOUS: the mapping is backed by zeroed pages rather than by a file. |
AdviseDontNeed | MADV_DONTNEED: the pages are not needed, and the kernel may discard them. |
AdviseWillNeed | MADV_WILLNEED: the pages will be read soon, so reading them ahead is worthwhile. |
AdviseRandom | MADV_RANDOM: the pages will be touched in no useful order, so reading ahead is not. |
AdviseSequential | MADV_SEQUENTIAL: the pages will be touched in order. |
AuxPageSize | AT_PAGESZ: the auxiliary-vector entry holding the page size, in bytes. |
AuxNull | AT_NULL: the entry that ends the auxiliary vector. |
EpollEventBytes | The size of one epoll_event in bytes: its four-byte event mask, padding, and eight-byte word. |
EpollEventWordOffset | Where the caller's word starts in an epoll_event. |
F_GETFL | F_GETFL: the fcntl command that reads a descriptor's status flags. |
F_SETFL | F_SETFL: the fcntl command that sets a descriptor's status flags. |
O_NONBLOCK | O_NONBLOCK: the status flag that makes a call fail with EAGAIN rather than wait. |
EPOLL_CLOEXEC | EPOLL_CLOEXEC: close the epoll descriptor when the process starts another program. |
EPOLL_CTL_ADD | EPOLL_CTL_ADD: register a descriptor. |
EPOLL_CTL_DEL | EPOLL_CTL_DEL: remove a descriptor's registration. |
EPOLL_CTL_MOD | EPOLL_CTL_MOD: change a registered descriptor's events and word. |
EPOLLIN | EPOLLIN: there is something to read, or a connection to accept. |
EPOLLOUT | EPOLLOUT: a write would not wait. |
EPOLLERR | EPOLLERR: the descriptor has an error pending; always reported. |
EPOLLHUP | EPOLLHUP: the peer has closed the connection; always reported. |
EPOLLRDHUP | EPOLLRDHUP: the peer has shut down its writing side. |
AF_INET | AF_INET: the IPv4 address family. |
AF_INET6 | AF_INET6: the IPv6 address family. |
SOCK_STREAM | SOCK_STREAM: a connected byte stream. |
SOCK_DGRAM | SOCK_DGRAM: individual datagrams. |
SOCK_CLOEXEC | SOCK_CLOEXEC: close the socket when the process starts another program. |
SOL_SOCKET | SOL_SOCKET: the level of the options every socket has. |
SO_REUSEADDR | SO_REUSEADDR: let a listening address be bound again while old connections to it wind down. |
SO_RCVTIMEO | SO_RCVTIMEO: how long a receive waits. |
SO_SNDTIMEO | SO_SNDTIMEO: how long a send waits. |
IPPROTO_TCP | IPPROTO_TCP: the level of TCP's options. |
TCP_NODELAY | TCP_NODELAY: send small writes at once rather than gathering them. |
IPPROTO_IPV6 | IPPROTO_IPV6: the level of IPv6's options. |
IPV6_V6ONLY | IPV6_V6ONLY: accept only IPv6 on an IPv6 socket. |
MSG_NOSIGNAL | MSG_NOSIGNAL: report a closed peer as an error rather than with SIGPIPE. |
F_SETFD | F_SETFD: the fcntl command that sets a descriptor's flags. |
FD_CLOEXEC | FD_CLOEXEC: close the descriptor when the process starts another program. |
WNOHANG | WNOHANG: have waitpid return at once when the child has not finished. |
SIGKILL | SIGKILL: the signal that ends a process at once and cannot be caught. |
SysMmap | mmap(2)'s system-call number. |
SysGetPid | getpid(2)'s system-call number. |
SC_NPROCESSORS_ONLN | _SC_NPROCESSORS_ONLN: the sysconf name for the number of processors currently online. |