Skip to content
CryoCryo home
Stdlibsys

syscall

import std::sys::syscall; · source

Two surfaces, gated by target

// Linux x86-64
type enum Syscall : i64 {
    read      = 0;
    write     = 1;
    open      = 2;
    close     = 3;
    stat      = 4;
    // ... the full <asm/unistd_64.h> table
}

![target(linux)] function sys_call0(num: Syscall) -> i64;
![target(linux)] function sys_call1(num: Syscall, a: i64) -> i64;
// ... through
![target(linux)] function sys_call6(num: Syscall, a: i64, b: i64, c: i64, d: i64, e: i64, f: i64) -> i64;

![target(linux)] function sys_read(fd: i32, buf: u8*, count: u64) -> i64;
![target(linux)] function sys_write(fd: i32, buf: u8*, count: u64) -> i64;
![target(linux)] function sys_open(path: u8*, flags: i32, mode: u32) -> i32;
![target(linux)] function sys_close(fd: i32) -> i32;
![target(linux)] function sys_mmap(addr: u8*, length: u64, prot: i32, flags: i32, fd: i32, offset: i64) -> u8*;
![target(linux)] function sys_fork() -> i32;
![target(linux)] function sys_execve(path: u8*, argv: u8**, envp: u8**) -> i32;
![target(linux)] function sys_gettid() -> i32;
![target(linux)] function sys_pidfd_open(pid: i32, flags: u32) -> i32;
![target(linux)] function sys_clone3(args: u8*, size: u64) -> i64;
![target(linux)] function sys_io_uring_setup(entries: u32, params: u8*) -> i32;
// ... ~120 typed wrappers

// Windows x86-64
type struct FILETIME { ... }
type struct SYSTEMTIME { ... }
type struct SECURITY_ATTRIBUTES { ... }
type struct OVERLAPPED { ... }
type struct STARTUPINFOA { ... }
type struct PROCESS_INFORMATION { ... }
type struct LARGE_INTEGER { ... }

![target(windows)] ![link("kernel32")]
extern "C" {
    function GetLastError() -> u32;
    function CreateFileA(...) -> void*;
    function VirtualAlloc(...) -> void*;
    // ... kernel32, user32, advapi32, ws2_32, ntdll
}

Two distinct surfaces live here, each gated by target so the other platform's symbols never reach the linker.

Linux x86-64 gets the full syscall number table as the Syscall enum, typed wrappers for the common cases (sys_read, sys_clone3, sys_io_uring_setup, and so on), and the generic sys_call0 through sys_call6 entry points that issue the raw syscall instruction via inline assembly. The typed wrappers return whatever the kernel returns — -errno on failure — with no normalisation beyond the cast to the natural return type.

Windows x86-64 gets the Win32 system surface — kernel32, user32, advapi32, ws2_32 — plus a small NT API surface from ntdll for programs that want to skip Win32. The handful of structs the calls need (FILETIME, STARTUPINFOA, PROCESS_INFORMATION, ...) are declared with their real layouts; the ![link(...)] attribute names the import library each block resolves against.

Constants have no link-time presence, so the syscall numbers and the Win32 constants are declared unconditionally. Only the extern "C" blocks and the typed wrappers that call into them carry ![target(...)] gates.

When to reach for this instead of ffi::libc

Reach for ffi::libc first. Its functions go through glibc's well-tested wrappers and are portable across Unix variants. Drop down to sys::syscall only when:

  • You need a syscall libc doesn't expose — gettid, pidfd_open, io_uring_setup, bpf, userfaultfd, clone3, the Landlock family.
  • You are writing a stub libc and want to avoid recursion.
  • You need bit-exact control over which syscall a code path issues: kernel fuzzing, eBPF tracers, sandbox enforcement.
  • You are on Windows and want the Win32 surface directly rather than through a libc personality.

ABI notes

The Linux numbers are the x86-64 ABI from <asm/unistd_64.h>. arm64, i386, and riscv64 use different numbers; a future per-arch split will gate that block.

The Windows bindings target the x64 ABI (the Microsoft x64 calling convention). x86 stdcall is not supported.

Constants

const CLONE_VM:                           u64 = 0x00000100;
const CLONE_FS:                           u64 = 0x00000200;
const CLONE_FILES:                        u64 = 0x00000400;
const CLONE_SIGHAND:                      u64 = 0x00000800;
const CLONE_PIDFD:                        u64 = 0x00001000;
const CLONE_PTRACE:                       u64 = 0x00002000;
const CLONE_VFORK:                        u64 = 0x00004000;
const CLONE_PARENT:                       u64 = 0x00008000;
const CLONE_THREAD:                       u64 = 0x00010000;
const CLONE_NEWNS:                        u64 = 0x00020000;
const CLONE_SYSVSEM:                      u64 = 0x00040000;
const CLONE_SETTLS:                       u64 = 0x00080000;
const CLONE_PARENT_SETTID:                u64 = 0x00100000;
const CLONE_CHILD_CLEARTID:               u64 = 0x00200000;
const CLONE_DETACHED:                     u64 = 0x00400000;
const CLONE_UNTRACED:                     u64 = 0x00800000;
const CLONE_CHILD_SETTID:                 u64 = 0x01000000;
const CLONE_NEWCGROUP:                    u64 = 0x02000000;
const CLONE_NEWUTS:                       u64 = 0x04000000;
const CLONE_NEWIPC:                       u64 = 0x08000000;
const CLONE_NEWUSER:                      u64 = 0x10000000;
const CLONE_NEWPID:                       u64 = 0x20000000;
const CLONE_NEWNET:                       u64 = 0x40000000;
const CLONE_IO:                           u64 = 0x80000000;
const FUTEX_WAIT:                         i32 = 0;
const FUTEX_WAKE:                         i32 = 1;
const FUTEX_FD:                           i32 = 2;
const FUTEX_REQUEUE:                      i32 = 3;
const FUTEX_CMP_REQUEUE:                  i32 = 4;
const FUTEX_WAKE_OP:                      i32 = 5;
const FUTEX_LOCK_PI:                      i32 = 6;
const FUTEX_UNLOCK_PI:                    i32 = 7;
const FUTEX_TRYLOCK_PI:                   i32 = 8;
const FUTEX_WAIT_BITSET:                  i32 = 9;
const FUTEX_WAKE_BITSET:                  i32 = 10;
const FUTEX_WAIT_REQUEUE_PI:              i32 = 11;
const FUTEX_CMP_REQUEUE_PI:               i32 = 12;
const FUTEX_PRIVATE_FLAG:                 i32 = 128;
const FUTEX_CLOCK_REALTIME:               i32 = 256;
const GRND_NONBLOCK:                      u32 = 1;
const GRND_RANDOM:                        u32 = 2;
const GRND_INSECURE:                      u32 = 4;
const PR_SET_PDEATHSIG:                   i32 = 1;
const PR_GET_PDEATHSIG:                   i32 = 2;
const PR_SET_DUMPABLE:                    i32 = 4;
const PR_GET_DUMPABLE:                    i32 = 3;
const PR_SET_NAME:                        i32 = 15;
const PR_GET_NAME:                        i32 = 16;
const PR_SET_SECCOMP:                     i32 = 22;
const PR_GET_SECCOMP:                     i32 = 21;
const PR_SET_NO_NEW_PRIVS:                i32 = 38;
const PR_GET_NO_NEW_PRIVS:                i32 = 39;
const SECCOMP_SET_MODE_STRICT:            u32 = 0;
const SECCOMP_SET_MODE_FILTER:            u32 = 1;
const SECCOMP_GET_ACTION_AVAIL:           u32 = 2;
const SECCOMP_GET_NOTIF_SIZES:            u32 = 3;
const PIDFD_NONBLOCK:                     u32 = 2048;
const INVALID_HANDLE_VALUE:               i64 = -1;
const NULL_HANDLE:                        u64 = 0;
const STD_INPUT_HANDLE:                   u32 = 4294967286;
const STD_OUTPUT_HANDLE:                  u32 = 4294967285;
const STD_ERROR_HANDLE:                   u32 = 4294967284;
const STARTF_USESTDHANDLES:               u32 = 0x100;
const HANDLE_FLAG_INHERIT:                u32 = 0x1;
const DUPLICATE_SAME_ACCESS:              u32 = 0x2;
const GENERIC_READ:                       u32 = 0x80000000;
const GENERIC_WRITE:                      u32 = 0x40000000;
const GENERIC_EXECUTE:                    u32 = 0x20000000;
const GENERIC_ALL:                        u32 = 0x10000000;
const FILE_SHARE_READ:                    u32 = 0x00000001;
const FILE_SHARE_WRITE:                   u32 = 0x00000002;
const FILE_SHARE_DELETE:                  u32 = 0x00000004;
const CREATE_NEW:                         u32 = 1;
const CREATE_ALWAYS:                      u32 = 2;
const OPEN_EXISTING:                      u32 = 3;
const OPEN_ALWAYS:                        u32 = 4;
const TRUNCATE_EXISTING:                  u32 = 5;
const FILE_ATTRIBUTE_READONLY:            u32 = 0x1;
const FILE_ATTRIBUTE_HIDDEN:              u32 = 0x2;
const FILE_ATTRIBUTE_SYSTEM:              u32 = 0x4;
const FILE_ATTRIBUTE_DIRECTORY:           u32 = 0x10;
const FILE_ATTRIBUTE_ARCHIVE:             u32 = 0x20;
const FILE_ATTRIBUTE_NORMAL:              u32 = 0x80;
const FILE_ATTRIBUTE_TEMPORARY:           u32 = 0x100;
const FILE_ATTRIBUTE_REPARSE_POINT:       u32 = 0x400;
const FILE_FLAG_WRITE_THROUGH:            u32 = 0x80000000;
const FILE_FLAG_OVERLAPPED:               u32 = 0x40000000;
const FILE_FLAG_NO_BUFFERING:             u32 = 0x20000000;
const FILE_FLAG_RANDOM_ACCESS:            u32 = 0x10000000;
const FILE_FLAG_SEQUENTIAL_SCAN:          u32 = 0x08000000;
const FILE_FLAG_DELETE_ON_CLOSE:          u32 = 0x04000000;
const FILE_FLAG_BACKUP_SEMANTICS:         u32 = 0x02000000;
const FILE_FLAG_OPEN_REPARSE_POINT:       u32 = 0x00200000;
const GetFileExInfoStandard:              u32 = 0;
const FILE_BEGIN:                         u32 = 0;
const FILE_CURRENT:                       u32 = 1;
const FILE_END:                           u32 = 2;
const MEM_COMMIT:                         u32 = 0x1000;
const MEM_RESERVE:                        u32 = 0x2000;
const MEM_DECOMMIT:                       u32 = 0x4000;
const MEM_RELEASE:                        u32 = 0x8000;
const MEM_RESET:                          u32 = 0x80000;
const MEM_RESET_UNDO:                     u32 = 0x1000000;
const MEM_LARGE_PAGES:                    u32 = 0x20000000;
const MEM_PHYSICAL:                       u32 = 0x400000;
const MEM_TOP_DOWN:                       u32 = 0x100000;
const PAGE_NOACCESS:                      u32 = 0x01;
const PAGE_READONLY:                      u32 = 0x02;
const PAGE_READWRITE:                     u32 = 0x04;
const PAGE_WRITECOPY:                     u32 = 0x08;
const PAGE_EXECUTE:                       u32 = 0x10;
const PAGE_EXECUTE_READ:                  u32 = 0x20;
const PAGE_EXECUTE_READWRITE:             u32 = 0x40;
const PAGE_EXECUTE_WRITECOPY:             u32 = 0x80;
const PAGE_GUARD:                         u32 = 0x100;
const PAGE_NOCACHE:                       u32 = 0x200;
const WAIT_OBJECT_0:                      u32 = 0;
const WAIT_ABANDONED_0:                   u32 = 0x80;
const WAIT_TIMEOUT:                       u32 = 0x102;
const WAIT_FAILED:                        u32 = 0xFFFFFFFF;
const INFINITE:                           u32 = 0xFFFFFFFF;
const HEAP_NO_SERIALIZE:                  u32 = 0x1;
const HEAP_GROWABLE:                      u32 = 0x2;
const HEAP_GENERATE_EXCEPTIONS:           u32 = 0x4;
const HEAP_ZERO_MEMORY:                   u32 = 0x8;
const HEAP_REALLOC_IN_PLACE_ONLY:         u32 = 0x10;
const CREATE_SUSPENDED:                   u32 = 0x4;
const DETACHED_PROCESS:                   u32 = 0x8;
const CREATE_NEW_CONSOLE:                 u32 = 0x10;
const CREATE_NEW_PROCESS_GROUP:           u32 = 0x200;
const CREATE_UNICODE_ENVIRONMENT:         u32 = 0x400;
const CREATE_BREAKAWAY_FROM_JOB:          u32 = 0x1000000;
const CREATE_NO_WINDOW:                   u32 = 0x8000000;
const ERROR_SUCCESS:                      u32 = 0;
const ERROR_FILE_NOT_FOUND:               u32 = 2;
const ERROR_PATH_NOT_FOUND:               u32 = 3;
const ERROR_ACCESS_DENIED:                u32 = 5;
const ERROR_INVALID_HANDLE:               u32 = 6;
const ERROR_NOT_ENOUGH_MEMORY:            u32 = 8;
const ERROR_BAD_FORMAT:                   u32 = 11;
const ERROR_INVALID_DATA:                 u32 = 13;
const ERROR_NO_MORE_FILES:                u32 = 18;
const ERROR_SHARING_VIOLATION:            u32 = 32;
const ERROR_HANDLE_EOF:                   u32 = 38;
const ERROR_NOT_SUPPORTED:                u32 = 50;
const ERROR_FILE_EXISTS:                  u32 = 80;
const ERROR_INVALID_PARAMETER:            u32 = 87;
const ERROR_BROKEN_PIPE:                  u32 = 109;
const ERROR_DISK_FULL:                    u32 = 112;
const ERROR_INSUFFICIENT_BUFFER:          u32 = 122;
const ERROR_INVALID_NAME:                 u32 = 123;
const ERROR_ALREADY_EXISTS:               u32 = 183;
const ERROR_NO_DATA:                      u32 = 232;
const ERROR_PIPE_BUSY:                    u32 = 231;
const ERROR_MORE_DATA:                    u32 = 234;
const ERROR_NO_MORE_ITEMS:                u32 = 259;
const ERROR_DIRECTORY:                    u32 = 267;
const ERROR_OPERATION_ABORTED:            u32 = 995;
const ERROR_IO_INCOMPLETE:                u32 = 996;
const ERROR_IO_PENDING:                   u32 = 997;
const ERROR_TIMEOUT:                      u32 = 1460;
const STATUS_SUCCESS:                     u32 = 0;
const STATUS_PENDING:                     u32 = 259;
const STATUS_BUFFER_OVERFLOW:             u32 = 0x80000005;
const STATUS_NO_MORE_FILES:               u32 = 0x80000006;
const STATUS_INVALID_HANDLE:              u32 = 0xC0000008;
const STATUS_INVALID_PARAMETER:           u32 = 0xC000000D;
const STATUS_END_OF_FILE:                 u32 = 0xC0000011;
const STATUS_ACCESS_DENIED:               u32 = 0xC0000022;
const FORMAT_MESSAGE_ALLOCATE_BUFFER:     u32 = 0x100;
const FORMAT_MESSAGE_IGNORE_INSERTS:      u32 = 0x200;
const FORMAT_MESSAGE_FROM_STRING:         u32 = 0x400;
const FORMAT_MESSAGE_FROM_HMODULE:        u32 = 0x800;
const FORMAT_MESSAGE_FROM_SYSTEM:         u32 = 0x1000;
const FORMAT_MESSAGE_ARGUMENT_ARRAY:      u32 = 0x2000;
const ENABLE_PROCESSED_INPUT:             u32 = 0x1;
const ENABLE_LINE_INPUT:                  u32 = 0x2;
const ENABLE_ECHO_INPUT:                  u32 = 0x4;
const ENABLE_WINDOW_INPUT:                u32 = 0x8;
const ENABLE_MOUSE_INPUT:                 u32 = 0x10;
const ENABLE_INSERT_MODE:                 u32 = 0x20;
const ENABLE_QUICK_EDIT_MODE:             u32 = 0x40;
const ENABLE_EXTENDED_FLAGS:              u32 = 0x80;
const ENABLE_PROCESSED_OUTPUT:            u32 = 0x1;
const ENABLE_WRAP_AT_EOL_OUTPUT:          u32 = 0x2;
const ENABLE_VIRTUAL_TERMINAL_PROCESSING: u32 = 0x4;
const ENABLE_VIRTUAL_TERMINAL_INPUT:      u32 = 0x200;
const CP_ACP:                             u32 = 0;
const CP_OEMCP:                           u32 = 1;
const CP_UTF7:                            u32 = 65000;
const CP_UTF8:                            u32 = 65001;
const MB_OK:                              u32 = 0;
const MB_OKCANCEL:                        u32 = 1;
const MB_ABORTRETRYIGNORE:                u32 = 2;
const MB_YESNOCANCEL:                     u32 = 3;
const MB_YESNO:                           u32 = 4;
const MB_RETRYCANCEL:                     u32 = 5;
const MB_ICONERROR:                       u32 = 0x10;
const MB_ICONWARNING:                     u32 = 0x30;
const MB_ICONINFORMATION:                 u32 = 0x40;
const IDOK:                               i32 = 1;
const IDCANCEL:                           i32 = 2;
const IDABORT:                            i32 = 3;
const IDRETRY:                            i32 = 4;
const IDIGNORE:                           i32 = 5;
const IDYES:                              i32 = 6;
const IDNO:                               i32 = 7;
const HKEY_CLASSES_ROOT:                  u64 = 0xFFFFFFFF80000000;
const HKEY_CURRENT_USER:                  u64 = 0xFFFFFFFF80000001;
const HKEY_LOCAL_MACHINE:                 u64 = 0xFFFFFFFF80000002;
const HKEY_USERS:                         u64 = 0xFFFFFFFF80000003;
const HKEY_CURRENT_CONFIG:                u64 = 0xFFFFFFFF80000005;
const KEY_QUERY_VALUE:                    u32 = 0x1;
const KEY_SET_VALUE:                      u32 = 0x2;
const KEY_CREATE_SUB_KEY:                 u32 = 0x4;
const KEY_ENUMERATE_SUB_KEYS:             u32 = 0x8;
const KEY_NOTIFY:                         u32 = 0x10;
const KEY_READ:                           u32 = 0x20019;
const KEY_WRITE:                          u32 = 0x20006;
const KEY_ALL_ACCESS:                     u32 = 0xF003F;
const REG_NONE:                           u32 = 0;
const REG_SZ:                             u32 = 1;
const REG_EXPAND_SZ:                      u32 = 2;
const REG_BINARY:                         u32 = 3;
const REG_DWORD:                          u32 = 4;
const REG_DWORD_BIG_ENDIAN:               u32 = 5;
const REG_MULTI_SZ:                       u32 = 7;
const REG_QWORD:                          u32 = 11;
const INVALID_SOCKET:                     u64 = 18446744073709551615;
const SOCKET_ERROR:                       i32 = -1;
const WSAEINTR:                           i32 = 10004;
const WSAEWOULDBLOCK:                     i32 = 10035;
const WSAEADDRINUSE:                      i32 = 10048;
const WSAECONNRESET:                      i32 = 10054;
const WSAECONNREFUSED:                    i32 = 10061;
const WSAETIMEDOUT:                       i32 = 10060;
const WSAECONNABORTED:                    i32 = 10053;
const WSAENOTCONN:                        i32 = 10057;
const FIONBIO:                            i32 = -2147195266;
const SOL_SOCKET:                         i32 = 65535;
const SO_ERROR:                           i32 = 4103;
const SO_CONNECT_TIME:                    i32 = 28684;
const SO_CONNECT_TIME_NEVER:              u32 = 0xFFFFFFFF;
const IOCTL_AFD_POLL:                     u32 = 0x00012024;
const AFD_POLL_RECEIVE:                   u32 = 0x0001;
const AFD_POLL_RECEIVE_EXPEDITED:         u32 = 0x0002;
const AFD_POLL_SEND:                      u32 = 0x0004;
const AFD_POLL_DISCONNECT:                u32 = 0x0008;
const AFD_POLL_ABORT:                     u32 = 0x0010;
const AFD_POLL_LOCAL_CLOSE:               u32 = 0x0020;
const AFD_POLL_ACCEPT:                    u32 = 0x0080;
const AFD_POLL_CONNECT_FAIL:              u32 = 0x0100;
const SIZEOF_IO_STATUS_BLOCK:             u64 = 16;
const SIZEOF_OVERLAPPED:                  u64 = 32;
const SIZEOF_AFD_POLL_INFO:               u64 = 32;
const SIZEOF_OBJECT_ATTRIBUTES:           u64 = 48;
const SIZEOF_UNICODE_STRING:              u64 = 16;
const SIZEOF_OVERLAPPED_ENTRY:            u64 = 32;
const SYNCHRONIZE:                        u32 = 0x00100000;
const FILE_SHARE_RW:                      u32 = 3;
const FILE_OPEN:                          u32 = 1;
const SIO_BASE_HANDLE:                    u32 = 0x48000022;
const IOCP_KICK_KEY:                      u64 = 1;