### Rustix Pipe Operations Example Source: https://context7.com/bytecodealliance/rustix/llms.txt Shows basic pipe creation, writing, reading, and non-blocking pipe setup using `rustix::pipe`. Includes Linux-specific pipe buffer size querying and setting. ```rust use rustix::io::{self, retry_on_intr}; use rustix::pipe::{pipe, pipe_with, PipeFlags}; fn main() -> io::Result<()> { // Basic pipe let (reader, writer) = pipe()?; rustix::io::write(&writer, b"data through pipe")?; drop(writer); // close write end so reader sees EOF let mut buf = [0u8; 64]; let n = rustix::io::read(&reader, &mut buf)?; println!("read {} bytes: {:?}", n, &buf[..n]); // Non-blocking pipe (O_NONBLOCK | O_CLOEXEC) let (_r2, _w2) = pipe_with(PipeFlags::NONBLOCK | PipeFlags::CLOEXEC)?; // Linux only: query and resize pipe buffer #[cfg(target_os = "linux")] { use rustix::pipe::{fcntl_getpipe_size, fcntl_setpipe_size}; let sz = fcntl_getpipe_size(&_w2)?; println!("default pipe buffer: {sz}"); let new_sz = fcntl_setpipe_size(&_w2, 65536)?; println!("new pipe buffer: {new_sz}"); } Ok(()) } // Expected output: // read 17 bytes: [100, 97, 116, 97, ...] // default pipe buffer: 65536 // new pipe buffer: 65536 ``` -------------------------------- ### Rustix Filesystem Operations Example Source: https://context7.com/bytecodealliance/rustix/llms.txt Demonstrates opening, writing, statting, truncating, and removing files, as well as iterating directory entries using `rustix::fs`. ```rust use rustix::fs:: openat, fstat, ftruncate, readdir, unlinkat, AtFlags, Mode, OFlags, CWD, }; use rustix::io; fn main() -> io::Result<()> { // Open a file relative to CWD (AT_FDCWD) let fd = openat( CWD, "example.txt", OFlags::CREATE | OFlags::WRONLY | OFlags::TRUNC, Mode::RUSR | Mode::WUSR | Mode::RGRP | Mode::ROTH, // 0o644 )?; // Write some data (using rustix::io) rustix::io::write(&fd, b"hello rustix fs\n")?; // Query file metadata – always 64-bit even on 32-bit targets let st = fstat(&fd)?; println!("size: {} bytes, inode: {}", st.st_size, st.st_ino); // Truncate to 5 bytes ftruncate(&fd, 5)?; drop(fd); // OwnedFd closes automatically // Iterate a directory let dir_fd = openat(CWD, ".", OFlags::RDONLY | OFlags::DIRECTORY, Mode::empty())?; let mut dir = readdir(dir_fd)?; while let Some(entry) = dir.next() { let entry = entry?; println!(" {:?}", entry.file_name()); } // Remove the test file unlinkat(CWD, "example.txt", AtFlags::empty())?; Ok(()) } // Example output: // size: 16 bytes, inode: 1234567 // . // .. // example.txt ``` -------------------------------- ### Rustix Setup with Cargo.toml Source: https://context7.com/bytecodealliance/rustix/llms.txt Configure Rustix dependencies and features in Cargo.toml. Enable specific modules or all APIs as needed. Use the 'use-libc' feature to force the libc backend. ```toml # Cargo.toml – enable only the modules you need [dependencies] rustix = { version = "1.1.4", features = ["fs", "net", "pipe", "process", "stdio", "time", "mm", "rand", "termios", "system"] } # To force the libc backend (e.g., for portability or Miri): # rustix = { version = "1.1.4", features = ["use-libc", "fs"] } # Enable all APIs (useful for exploration / rustix developers): # rustix = { version = "1.1.4", features = ["all-apis"] } ``` -------------------------------- ### rustix::process Source: https://context7.com/bytecodealliance/rustix/llms.txt Exposes process-related syscalls such as getpid, getppid, getuid, getgid, and more. Includes examples for retrieving process information and resource limits. ```APIDOC ## `rustix::process` — Process and Resource Operations `rustix::process` exposes process-related syscalls: `getpid`, `getppid`, `getpgrp`, `getpgid`, `setpgid`, `getuid`, `getgid`, `geteuid`, `getegid`, `getcwd`, `chdir`, `umask`, `getrlimit`, `setrlimit`, `getpriority_process`, `setpriority_process`, `kill`, `waitpid`, and more. ```rust use rustix::process::{ getcwd, getgid, getpid, getppid, getuid, getrlimit, Resource, }; use rustix::io; fn main() -> io::Result<()> { let pid = getpid(); let ppid = getppid(); let uid = getuid(); let gid = getgid(); println!("PID: {:?}", pid.as_raw_nonzero()); println!("PPID: {:?}", ppid.map(|p| p.as_raw_nonzero().get()).unwrap_or(0)); println!("UID: {:?}", uid.as_raw()); println!("GID: {:?}", gid.as_raw()); println!("root?: {:?}", uid.is_root()); // Current working directory let cwd = getcwd(Vec::new())?; println!("CWD: {:?}", cwd.to_string_lossy()); // Query resource limits (struct always uses u64, no 32-bit truncation) let rl = getrlimit(Resource::Nofile); println!("NOFILE soft={:?} hard={:?}", rl.current, rl.maximum); Ok(()) } // Example output: // PID: 12345 // PPID: 12344 // UID: 1000 // GID: 1000 // root?: false // CWD: /home/user/project // NOFILE soft=Some(1024) hard=Some(1048576) ``` ``` -------------------------------- ### Rustix Network Socket Operations Example Source: https://context7.com/bytecodealliance/rustix/llms.txt Illustrates creating, binding, listening, connecting, accepting, sending, and receiving data using `rustix::net` for TCP sockets. ```rust use rustix::net:: accept, bind, connect, listen, recv, send, socket, AddressFamily, RecvFlags, SendFlags, SocketFlags, SocketType, }; use rustix::net::SocketAddrV4; use std::net::Ipv4Addr; use rustix::io; fn main() -> io::Result<()> { // --- Server side --- let server = socket(AddressFamily::INET, SocketType::STREAM, None)?; let addr = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0); // OS picks port bind(&server, &addr)?; listen(&server, 1)?; // --- Client side --- let client = socket(AddressFamily::INET, SocketType::STREAM, None)?; // Retrieve the port the OS assigned let local = rustix::net::getsockname(&server)?; connect(&client, &local)?; // Accept the connection let (conn, peer_addr) = accept(&server)?; println!("peer: {:?}", peer_addr); // Send and receive send(&client, b"ping", SendFlags::empty())?; let mut buf = [0u8; 16]; let n = recv(&conn, &mut buf, RecvFlags::empty())?; println!("received: {:?}", &buf[..n]); // b"ping" Ok(()) } // Expected output: // peer: Some(V4(127.0.0.1:NNNNN)) // received: [112, 105, 110, 103] ``` -------------------------------- ### Get Process Information with rustix::process Source: https://context7.com/bytecodealliance/rustix/llms.txt Retrieves and prints process ID, parent process ID, user ID, group ID, and resource limits. Ensure necessary imports are included. ```rust use rustix::process::{ getcwd, getgid, getpid, getppid, getuid, getrlimit, Resource, }; use rustix::io; fn main() -> io::Result<()> { let pid = getpid(); let ppid = getppid(); let uid = getuid(); let gid = getgid(); println!("PID: {}", pid.as_raw_nonzero()); println!("PPID: {}", ppid.map(|p| p.as_raw_nonzero().get()).unwrap_or(0)); println!("UID: {}", uid.as_raw()); println!("GID: {}", gid.as_raw()); println!("root?: {}", uid.is_root()); // Current working directory let cwd = getcwd(Vec::new())?; println!("CWD: {}", cwd.to_string_lossy()); // Query resource limits (struct always uses u64, no 32-bit truncation) let rl = getrlimit(Resource::Nofile); println!("NOFILE soft={:?} hard={:?}", rl.current, rl.maximum); Ok(()) } ``` -------------------------------- ### Poll File Descriptors with rustix::event Source: https://context7.com/bytecodealliance/rustix/llms.txt Shows how to use rustix::event::poll to wait for events on file descriptors, such as data becoming available for reading. This example uses a pipe and demonstrates checking for read readiness and then reading the data. ```rust use rustix::event::{poll, PollFd, PollFlags}; use rustix::io; use rustix::pipe::pipe; fn main() -> io::Result<()> { let (reader, writer) = pipe()?; // Write data so the reader is ready immediately rustix::io::write(&writer, b"event data")?; let mut fds = [PollFd::new(&reader, PollFlags::IN)]; // Timeout of 100 ms; returns number of ready fds let ready = poll(&mut fds, 100)?; println!("{ready} fd(s) ready"); if fds[0].revents().contains(PollFlags::IN) { let mut buf = [0u8; 64]; let n = rustix::io::read(&reader, &mut buf)?; println!("read: {:?}", &buf[..n]); } Ok(()) } // Expected output: // 1 fd(s) ready // read: [101, 118, 101, 110, 116, 32, 100, 97, 116, 97] ``` -------------------------------- ### Get Time Information with rustix::time Source: https://context7.com/bytecodealliance/rustix/llms.txt Fetches monotonic and real-time timestamps, and demonstrates sleeping for a duration. Supports Linux-specific coarse and raw clocks when compiled for Linux. ```rust use rustix::time::{clock_gettime, clock_nanosleep, ClockId, ClockNanosleepFlags, Timespec}; use rustix::io; fn main() -> io::Result<()> { let t0 = clock_gettime(ClockId::Monotonic); println!("monotonic : {}.{:09}s", t0.tv_sec, t0.tv_nsec); let wall = clock_gettime(ClockId::Realtime); println!("realtime : {}.{:09}s (unix epoch)", wall.tv_sec, wall.tv_nsec); #[cfg(target_os = "linux")] { let coarse = clock_gettime(ClockId::MonotonicCoarse); let raw = clock_gettime(ClockId::MonotonicRaw); println!("coarse : {}.{:09}s", coarse.tv_sec, coarse.tv_nsec); println!("raw : {}.{:09}s", raw.tv_sec, raw.tv_nsec); } // Sleep for 1 millisecond using CLOCK_MONOTONIC clock_nanosleep( ClockId::Monotonic, ClockNanosleepFlags::empty(), &Timespec { tv_sec: 0, tv_nsec: 1_000_000 }, )?; let t1 = clock_gettime(ClockId::Monotonic); let elapsed_ns = (t1.tv_sec - t0.tv_sec) * 1_000_000_000 + (t1.tv_nsec - t0.tv_nsec); println!("elapsed : {}ns", elapsed_ns); Ok(()) } ``` -------------------------------- ### rustix::termios Source: https://context7.com/bytecodealliance/rustix/llms.txt Provides functions for terminal I/O operations, including getting and setting terminal attributes, checking if a file descriptor is a TTY, and managing terminal window size. ```APIDOC ## `rustix::termios` ### Description Provides `tcgetattr`, `tcsetattr`, `isatty`, `ttyname`, `tcgetpgrp`, `tcsetpgrp`, `tcgetwinsize`, `tcsetwinsize`, `tcflush`, `tcdrain`, and `tcsendbreak`. `Termios` has a `make_raw()` method for enabling raw (character-at-a-time) input and exposes structured `InputModes`, `OutputModes`, `ControlModes`, and `LocalModes` bitflags fields. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use rustix::termios::{isatty, tcgetattr, tcsetattr, OptionalActions, Termios}; use rustix::stdio::stdin; use rustix::io; fn main() -> io::Result<()> { let tty = stdin(); if !isatty(tty) { println!("stdin is not a tty"); return Ok(()) } let termios: Termios = tcgetattr(tty)?; println!("input speed: {} baud", termios.input_speed()); println!("output speed: {} baud", termios.output_speed()); let mut raw = termios.clone(); raw.make_raw(); tcsetattr(tty, OptionalActions::Flush, &raw)?; // … read single keystrokes here … tcsetattr(tty, OptionalActions::Flush, &termios)?; println!("restored terminal settings"); Ok(()) } ``` ### Response #### Success Response (200) - `Ok(())` on successful terminal attribute operations. #### Response Example ```json // Example output (when run in a terminal): // input speed: 38400 baud // output speed: 38400 baud // restored terminal settings ``` ``` -------------------------------- ### Run tests with libc backend on Linux Source: https://github.com/bytecodealliance/rustix/blob/main/CONTRIBUTING.md To specifically test the libc backend on Linux, enable both the `all-apis` and `use-libc` features. This isolates testing to the libc implementation. ```console cargo test --features=all-apis,use-libc ``` -------------------------------- ### rustix::system::uname Source: https://context7.com/bytecodealliance/rustix/llms.txt Retrieves system information, including the operating system name, nodename, release, version, and machine architecture. ```APIDOC ## `rustix::system::uname` ### Description Provides `uname()` which returns a `Uname` struct with fields `sysname`, `nodename`, `release`, `version`, and `machine` as `&CStr`. On Linux it also provides `sysinfo()` returning load averages, uptime, memory stats, and process counts. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use rustix::system::uname; fn main() { let info = uname(); println!("sysname: {}", info.sysname().to_string_lossy()); println!("nodename: {}", info.nodename().to_string_lossy()); println!("release: {}", info.release().to_string_lossy()); println!("version: {}", info.version().to_string_lossy()); println!("machine: {}", info.machine().to_string_lossy()); #[cfg(target_os = "linux")] { use rustix::system::sysinfo; let si = sysinfo(); println!("uptime: {}s", si.uptime); println!("total RAM: {} KB", si.totalram * si.mem_unit as u64 / 1024); println!("free RAM: {} KB", si.freeram * si.mem_unit as u64 / 1024); println!("procs running: {}", si.procs); } } ``` ### Response #### Success Response (200) - `Uname` struct containing system information (`sysname`, `nodename`, `release`, `version`, `machine`). On Linux, `sysinfo()` provides additional details. #### Response Example ```json // Example output: // sysname: Linux // nodename: myhost // release: 6.1.0-28-amd64 // version: #1 SMP PREEMPT_DYNAMIC Debian 6.1.119-1 // machine: x86_64 // uptime: 3600s // total RAM: 16384000 KB // free RAM: 8192000 KB // procs running: 142 ``` ``` -------------------------------- ### Core I/O Operations with Rustix Source: https://context7.com/bytecodealliance/rustix/llms.txt Demonstrates fundamental I/O primitives like read, write, and ioctl_fionread using Rustix. Errors are handled as Results, and file descriptors are managed safely. Includes automatic EINTR retry via a helper function. ```rust use rustix::io::{self, retry_on_intr, Errno}; use rustix::stdio::stdout; fn write_all(fd: impl rustix::fd::AsFd, mut data: &[u8]) -> io::Result<()> { while !data.is_empty() { match rustix::io::write(&fd, data) { Ok(n) => data = &data[n..], // partial write: continue Err(Errno::INTR) => {} // interrupted: retry Err(e) => return Err(e), } } Ok(()) } fn main() -> io::Result<()> { // Write to stdout with automatic EINTR retry via helper let stdout = stdout(); retry_on_intr(|| rustix::io::write(stdout, b"Hello, rustix!\n"))?; // Query how many bytes are available to read without blocking let available = rustix::io::ioctl_fionread(stdout)?; println!("bytes ready: {available}"); // Duplicate a file descriptor let dup_fd = rustix::io::dup(stdout)?; write_all(&dup_fd, b"Written via dup'd fd\n")?; // dup_fd is automatically closed when dropped (OwnedFd) Ok(()) } // Expected output: // Hello, rustix! // bytes ready: 0 // Written via dup'd fd ``` -------------------------------- ### Run all tests with all features enabled Source: https://github.com/bytecodealliance/rustix/blob/main/CONTRIBUTING.md Use this command to run all tests, enabling all rustix APIs for comprehensive testing. This is useful for ensuring broad compatibility. ```console cargo test --features=all-apis ``` -------------------------------- ### Create and Use POSIX Shared Memory with rustix::shm Source: https://context7.com/bytecodealliance/rustix/llms.txt Demonstrates creating, sizing, mapping, writing to, and unlinking a POSIX shared memory object using rustix::shm, rustix::mm::mmap, and rustix::fs::ftruncate. Ensure the shared memory object name is unique to avoid conflicts. ```rust use rustix::fs::{ftruncate, Mode}; use rustix::mm::{mmap, munmap, MapFlags, ProtFlags}; use rustix::shm; use rustix::io; use std::mem::size_of; use std::ptr::null_mut; #[repr(C)] struct SharedData { counter: u64 } fn main() -> io::Result<()> { let name = "/rustix-example-shm"; let size = size_of::(); // Create and size the shared memory object let fd = shm::open( name, shm::OFlags::CREATE | shm::OFlags::EXCL | shm::OFlags::RDWR, Mode::RUSR | Mode::WUSR, )?; ftruncate(&fd, size as u64)?; // Map it into the process address space let ptr = unsafe { mmap(null_mut(), size, ProtFlags::READ | ProtFlags::WRITE, MapFlags::SHARED, &fd, 0)? }; // Write to shared memory let shared = ptr.cast::(); unsafe { (*shared).counter = 42 }; println!("counter = {}", unsafe { (*shared).counter }); // Clean up unsafe { munmap(ptr, size)? }; shm::unlink(name)?; Ok(()) } // Expected output: // counter = 42 ``` -------------------------------- ### Memory Mapping Operations with rustix::mm Source: https://context7.com/bytecodealliance/rustix/llms.txt Demonstrates creating anonymous and file-backed memory mappings, changing protection flags, and unmapping memory regions. Requires careful use of unsafe blocks for pointer operations. ```rust use rustix::fs::{openat, OFlags, Mode, CWD}; use rustix::mm::{mmap, mmap_anonymous, mprotect, munmap, msync, MapFlags, MsyncFlags, ProtFlags}; use rustix::io; use std::ptr::null_mut; fn main() -> io::Result<()> { let page = 4096usize; // Anonymous read-write mapping let ptr = unsafe { mmap_anonymous(null_mut(), page, ProtFlags::READ | ProtFlags::WRITE, MapFlags::PRIVATE)? }; println!("anon map @ {:p}", ptr); // Write data and sync unsafe { std::ptr::write_bytes(ptr.cast::(), 0xAB, page) }; // Downgrade to read-only unsafe { mprotect(ptr, page, ProtFlags::READ)? }; // File-backed mapping let fd = openat(CWD, "example.txt", OFlags::CREATE | OFlags::RDWR | OFlags::TRUNC, Mode::RUSR | Mode::WUSR)?; rustix::io::write(&fd, &[0u8; page])?; let fptr = unsafe { mmap(null_mut(), page, ProtFlags::READ | ProtFlags::WRITE, MapFlags::SHARED, &fd, 0)? }; unsafe { msync(fptr, page, MsyncFlags::SYNC)? }; // Unmap both regions unsafe { munmap(ptr, page)? }; unsafe { munmap(fptr, page)? }; Ok(()) } ``` -------------------------------- ### rustix::fs — Filesystem Operations Source: https://context7.com/bytecodealliance/rustix/llms.txt Exposes filesystem syscalls such as openat, readdir, stat, and more. Paths can be specified using types implementing rustix::path::Arg. ```APIDOC ## `rustix::fs` — Filesystem Operations `rustix::fs` exposes filesystem syscalls: `openat`, `readdir`, `stat`, `fstat`, `fstatat`, `ftruncate`, `linkat`, `unlinkat`, `renameat`, `mkdirat`, `symlinkat`, `readlinkat`, `chownat`, `chmodat`, `access`, `fsync`, `fdatasync`, `flock`, `fcntl_getfl`, `fcntl_setfl`, `inotify`, and more. Paths accept any type implementing `rustix::path::Arg` (including `&str`, `&Path`, `CStr`, etc.). ```rust use rustix::fs::{ openat, fstat, ftruncate, readdir, unlinkat, AtFlags, Mode, OFlags, CWD, }; use rustix::io; fn main() -> io::Result<()> { // Open a file relative to CWD (AT_FDCWD) let fd = openat( CWD, "example.txt", OFlags::CREATE | OFlags::WRONLY | OFlags::TRUNC, Mode::RUSR | Mode::WUSR | Mode::RGRP | Mode::ROTH, // 0o644 )?; // Write some data (using rustix::io) rustix::io::write(&fd, b"hello rustix fs\n")?; // Query file metadata – always 64-bit even on 32-bit targets let st = fstat(&fd)?; println!("size: {} bytes, inode: {}", st.st_size, st.st_ino); // Truncate to 5 bytes ftruncate(&fd, 5)?; drop(fd); // OwnedFd closes automatically // Iterate a directory let dir_fd = openat(CWD, ".", OFlags::RDONLY | OFlags::DIRECTORY, Mode::empty())?; let mut dir = readdir(dir_fd)?; while let Some(entry) = dir.next() { let entry = entry?; println!(" {:?}", entry.file_name()); } // Remove the test file unlinkat(CWD, "example.txt", AtFlags::empty())?; Ok(()) } // Example output: // size: 16 bytes, inode: 1234567 // . // .. // example.txt ``` ``` -------------------------------- ### Standard I/O File Descriptors and Redirection Source: https://context7.com/bytecodealliance/rustix/llms.txt Provides safe access to standard input, output, and error file descriptors using Rustix. Demonstrates how to redirect these streams using dup2_stdin and dup2_stdout helpers. ```rust use rustix::pipe::pipe; use rustix::stdio::{dup2_stdin, dup2_stdout, stderr, stdin, stdout}; fn main() -> std::io::Result<()> { // Access stdio descriptors as I/O-safe BorrowedFd let _in = stdin(); // BorrowedFd for fd 0 let _out = stdout(); // BorrowedFd for fd 1 let _err = stderr(); // BorrowedFd for fd 2 // Redirect stdin/stdout through a pipe let (reader, writer) = pipe()?; dup2_stdin(&reader)?; dup2_stdout(&writer)?; drop(reader); drop(writer); println!("hello from redirected stdout"); let mut s = String::new(); std::io::stdin().read_line(&mut s)?; assert_eq!(s, "hello from redirected stdout\n"); Ok(()) } ``` -------------------------------- ### Retrieve System Information with rustix::system Source: https://context7.com/bytecodealliance/rustix/llms.txt Obtain system details using `uname()` which provides kernel and machine information. On Linux, `sysinfo()` additionally returns load averages, memory statistics, and process counts. ```Rust use rustix::system::uname; fn main() { let info = uname(); println!("sysname: {}", info.sysname().to_string_lossy()); println!("nodename: {}", info.nodename().to_string_lossy()); println!("release: {}", info.release().to_string_lossy()); println!("version: {}", info.version().to_string_lossy()); println!("machine: {}", info.machine().to_string_lossy()); #[cfg(target_os = "linux")] { use rustix::system::sysinfo; let si = sysinfo(); println!("uptime: {}s", si.uptime); println!("total RAM: {} KB", si.totalram * si.mem_unit as u64 / 1024); println!("free RAM: {} KB", si.freeram * si.mem_unit as u64 / 1024); println!("procs running: {}", si.procs); } } ``` -------------------------------- ### rustix::io - Core I/O Operations Source: https://context7.com/bytecodealliance/rustix/llms.txt Provides fundamental I/O primitives like read, write, close, dup, and ioctl_fionread. It uses `AsFd` for file descriptor types and `Errno` for error handling. ```APIDOC ## `rustix::io` — Core I/O Operations The `rustix::io` module provides fundamental I/O primitives: `read`, `write`, `close`, `dup`, `ioctl_fionread`, `retry_on_intr`, and the `Errno` type. All functions accept any type implementing `AsFd`, eliminating raw file descriptor integers. `Errno` carries the exact kernel error code and can be matched exhaustively against named constants. ```rust use rustix::io::{self, retry_on_intr, Errno}; use rustix::stdio::stdout; fn write_all(fd: impl rustix::fd::AsFd, mut data: &[u8]) -> io::Result<()> { while !data.is_empty() { match rustix::io::write(&fd, data) { Ok(n) => data = &data[n..], // partial write: continue Err(Errno::INTR) => {} // interrupted: retry Err(e) => return Err(e), } } Ok(()) } fn main() -> io::Result<()> { // Write to stdout with automatic EINTR retry via helper let stdout = stdout(); retry_on_intr(|| rustix::io::write(stdout, b"Hello, rustix!\n"))?; // Query how many bytes are available to read without blocking let available = rustix::io::ioctl_fionread(stdout)?; println!("bytes ready: {available}"); // Duplicate a file descriptor let dup_fd = rustix::io::dup(stdout)?; write_all(&dup_fd, b"Written via dup\'d fd\n")?; // dup_fd is automatically closed when dropped (OwnedFd) Ok(()) } // Expected output: // Hello, rustix! // bytes ready: 0 // Written via dup'd fd ``` ``` -------------------------------- ### rustix::stdio - Standard I/O File Descriptors Source: https://context7.com/bytecodealliance/rustix/llms.txt Provides safe access to the process's standard input, output, and error file descriptors. Includes helpers for redirecting standard streams. ```APIDOC ## `rustix::stdio` — Standard I/O File Descriptors `rustix::stdio` provides safe access to the process's standard input, output, and error file descriptors as `BorrowedFd<'static>` values (in `std`-enabled builds). It also exposes `dup2_stdin`, `dup2_stdout`, and `dup2_stderr` helpers for safely redirecting the standard streams. ```rust use rustix::pipe::pipe; use rustix::stdio::{dup2_stdin, dup2_stdout, stderr, stdin, stdout}; fn main() -> std::io::Result<()> { // Access stdio descriptors as I/O-safe BorrowedFd let _in = stdin(); // BorrowedFd for fd 0 let _out = stdout(); // BorrowedFd for fd 1 let _err = stderr(); // BorrowedFd for fd 2 // Redirect stdin/stdout through a pipe let (reader, writer) = pipe()?; dup2_stdin(&reader)?; dup2_stdout(&writer)?; drop(reader); drop(writer); println!("hello from redirected stdout"); let mut s = String::new(); std::io::stdin().read_line(&mut s)?; assert_eq!(s, "hello from redirected stdout\n"); Ok(()) } ``` ``` -------------------------------- ### rustix::mm Source: https://context7.com/bytecodealliance/rustix/llms.txt Provides memory mapping operations such as mmap, mmap_anonymous, mprotect, munmap, msync, madvise, mlock, munlock, mlockall, munlockall, and on Linux mremap and userfaultfd. ```APIDOC ## `rustix::mm` — Memory Mapping Operations `rustix::mm` provides `mmap`, `mmap_anonymous`, `mprotect`, `munmap`, `msync`, `madvise`, `mlock`, `munlock`, `mlockall`, `munlockall`, and on Linux `mremap` and `userfaultfd`. All accept typed `ProtFlags`, `MapFlags`, `MsyncFlags`, and `Advice` enums rather than bare integers. ```rust use rustix::fs::{openat, OFlags, Mode, CWD}; use rustix::mm::{mmap, mmap_anonymous, mprotect, munmap, msync, MapFlags, MsyncFlags, ProtFlags}; use rustix::io; use std::ptr::null_mut; fn main() -> io::Result<()> { let page = 4096usize; // Anonymous read-write mapping let ptr = unsafe { mmap_anonymous(null_mut(), page, ProtFlags::READ | ProtFlags::WRITE, MapFlags::PRIVATE)? }; println!("anon map @ {:p}", ptr); // Write data and sync unsafe { std::ptr::write_bytes(ptr.cast::(), 0xAB, page) }; // Downgrade to read-only unsafe { mprotect(ptr, page, ProtFlags::READ)? }; // File-backed mapping let fd = openat(CWD, "example.txt", OFlags::CREATE | OFlags::RDWR | OFlags::TRUNC, Mode::RUSR | Mode::WUSR)?; rustix::io::write(&fd, &[0u8; page])?; let fptr = unsafe { mmap(null_mut(), page, ProtFlags::READ | ProtFlags::WRITE, MapFlags::SHARED, &fd, 0)? }; unsafe { msync(fptr, page, MsyncFlags::SYNC)? }; // Unmap both regions unsafe { munmap(ptr, page)? }; unsafe { munmap(fptr, page)? }; Ok(()) } ``` ``` -------------------------------- ### rustix::pipe — Pipe and Splice Operations Source: https://context7.com/bytecodealliance/rustix/llms.txt Provides functions for creating pipes (`pipe`, `pipe_with`) and, on Linux, for splice, tee, and vmsplice operations. All pipe operations return `OwnedFd` pairs for type-safe lifetime management. ```APIDOC ## `rustix::pipe` — Pipe and Splice Operations `rustix::pipe` provides `pipe()`, `pipe_with()`, and on Linux: `splice`, `tee`, `vmsplice`, `fcntl_getpipe_size`, and `fcntl_setpipe_size`. All return `OwnedFd` pairs so lifetimes are tracked by the type system. ```rust use rustix::io::{self, retry_on_intr}; use rustix::pipe::{pipe, pipe_with, PipeFlags}; fn main() -> io::Result<()> { // Basic pipe let (reader, writer) = pipe()?; rustix::io::write(&writer, b"data through pipe")?; drop(writer); // close write end so reader sees EOF let mut buf = [0u8; 64]; let n = rustix::io::read(&reader, &mut buf)?; println!("read {} bytes: {:?}", n, &buf[..n]); // Non-blocking pipe (O_NONBLOCK | O_CLOEXEC) let (_r2, _w2) = pipe_with(PipeFlags::NONBLOCK | PipeFlags::CLOEXEC)?; // Linux only: query and resize pipe buffer #[cfg(target_os = "linux")] { use rustix::pipe::{fcntl_getpipe_size, fcntl_setpipe_size}; let sz = fcntl_getpipe_size(&_w2)?; println!("default pipe buffer: {sz}"); let new_sz = fcntl_setpipe_size(&_w2, 65536)?; println!("new pipe buffer: {new_sz}"); } Ok(()) } // Expected output: // read 17 bytes: [100, 97, 116, 97, ...] // default pipe buffer: 65536 // new pipe buffer: 65536 ``` ``` -------------------------------- ### Generate Cryptographically Secure Random Bytes with rustix::rand Source: https://context7.com/bytecodealliance/rustix/llms.txt Use `getrandom` to fill a buffer with secure random bytes from the kernel. `GetRandomFlags::NONBLOCK` can be used for non-blocking behavior, returning `EAGAIN` if the entropy pool is not ready. ```Rust use rustix::rand::{getrandom, GetRandomFlags}; use rustix::io; fn main() -> io::Result<()> { // Fill a 32-byte buffer (e.g., for a cryptographic key) let mut key = [0u8; 32]; getrandom(&mut key, GetRandomFlags::empty())?; println!("random key: {}", key.iter().map(|b| format!("{b:02x}")).collect::()); // Non-blocking: returns Err(Errno::AGAIN) if entropy pool not ready let mut nonce = [0u8; 12]; match getrandom(&mut nonce, GetRandomFlags::NONBLOCK) { Ok(_) => println!("nonce: {}", nonce.iter().map(|b| format!("{b:02x}")).collect::()), Err(rustix::io::Errno::AGAIN) => println!("entropy not ready yet"), Err(e) => return Err(e), } Ok(()) } ``` -------------------------------- ### Use rustix::fd for I/O Safety with Files Source: https://context7.com/bytecodealliance/rustix/llms.txt Illustrates how rustix::fd types like OwnedFd and BorrowedFd, along with the AsFd trait, enable safe and transparent handling of file descriptors across different Rust I/O types. This snippet shows a function accepting any AsFd type and demonstrates its usage with both rustix::OwnedFd and std::fs::File. ```rust use rustix::fd::{AsFd, OwnedFd, FromRawFd}; use rustix::fs::{openat, OFlags, Mode, CWD}; use rustix::io; // Accepts any type implementing AsFd – std::fs::File, OwnedFd, BorrowedFd, etc. fn file_size(fd: impl AsFd) -> io::Result { let st = rustix::fs::fstat(fd)?; Ok(st.st_size as u64) } fn main() -> io::Result<()> { // rustix OwnedFd let rustix_fd: OwnedFd = openat(CWD, "Cargo.toml", OFlags::RDONLY, Mode::empty())?; println!("size via OwnedFd : {}", file_size(&rustix_fd)?); // std::fs::File also implements AsFd let std_file = std::fs::File::open("Cargo.toml")?; println!("size via std::File: {}", file_size(&std_file)?); // Interop: convert std File → OwnedFd let owned: OwnedFd = std_file.into(); println!("size via converted: {}", file_size(&owned)?); Ok(()) } // Example output: // size via OwnedFd : 3521 // size via std::File: 3521 // size via converted: 3521 ``` -------------------------------- ### Configure Terminal Settings with rustix::termios Source: https://context7.com/bytecodealliance/rustix/llms.txt Manage terminal I/O settings using functions like `tcgetattr` and `tcsetattr`. The `Termios` struct allows modification of input/output modes, and `make_raw()` enables character-at-a-time input without echoing. ```Rust use rustix::termios::{isatty, tcgetattr, tcsetattr, OptionalActions, Termios}; use rustix::stdio::stdin; use rustix::io; fn main() -> io::Result<()> { let tty = stdin(); if !isatty(tty) { println!("stdin is not a tty"); return Ok(()) } // Inspect current terminal settings let termios: Termios = tcgetattr(tty)?; println!("input speed: {} baud", termios.input_speed()); println!("output speed: {} baud", termios.output_speed()); // Switch to raw mode (no line buffering, no echo) let mut raw = termios.clone(); raw.make_raw(); tcsetattr(tty, OptionalActions::Flush, &raw)?; // … read single keystrokes here … // Restore original settings tcsetattr(tty, OptionalActions::Flush, &termios)?; println!("restored terminal settings"); Ok(()) } ``` -------------------------------- ### rustix::shm — POSIX Shared Memory Source: https://context7.com/bytecodealliance/rustix/llms.txt Provides functions for creating (`shm_open`) and removing (`shm_unlink`) POSIX shared memory objects. It is intended to be used with `rustix::mm::mmap` and `rustix::fs::ftruncate` for inter-process communication via shared memory. ```APIDOC ## `rustix::shm` — POSIX Shared Memory `rustix::shm` provides `open` (`shm_open`) and `unlink` (`shm_unlink`) for creating and removing POSIX shared memory objects. Used together with `rustix::mm::mmap` and `rustix::fs::ftruncate` to set up shared memory regions between processes. ```rust use rustix::fs::{ftruncate, Mode}; use rustix::mm::{mmap, munmap, MapFlags, ProtFlags}; use rustix::shm; use rustix::io; use std::mem::size_of; use std::ptr::null_mut; #[repr(C)] struct SharedData { counter: u64 } fn main() -> io::Result<()> { let name = "/rustix-example-shm"; let size = size_of::(); // Create and size the shared memory object let fd = shm::open( name, shm::OFlags::CREATE | shm::OFlags::EXCL | shm::OFlags::RDWR, Mode::RUSR | Mode::WUSR, )?; ftruncate(&fd, size as u64)?; // Map it into the process address space let ptr = unsafe { mmap(null_mut(), size, ProtFlags::READ | ProtFlags::WRITE, MapFlags::SHARED, &fd, 0)? }; // Write to shared memory let shared = ptr.cast::(); unsafe { (*shared).counter = 42 }; println!("counter = {}", unsafe { (*shared).counter }); // Clean up unsafe { munmap(ptr, size)? }; shm::unlink(name)?; Ok(()) } // Expected output: // counter = 42 ``` ``` -------------------------------- ### rustix::net — Network (Socket) Operations Source: https://context7.com/bytecodealliance/rustix/llms.txt Exposes socket APIs including socket creation, binding, connecting, sending, and receiving data. Supports IPv4, IPv6, and Unix domain sockets via the SocketAddrAny type. ```APIDOC ## `rustix::net` — Network (Socket) Operations `rustix::net` exposes socket APIs: `socket`, `bind`, `connect`, `listen`, `accept`, `send`, `recv`, `sendto`, `recvfrom`, `shutdown`, `getsockopt`, `setsockopt`, and scatter-gather `sendmsg`/`recvmsg`. On Windows, it wraps Winsock. The `SocketAddrAny` type abstracts over IPv4, IPv6, and Unix addresses. ```rust use rustix::net::{ accept, bind, connect, listen, recv, send, socket, AddressFamily, RecvFlags, SendFlags, SocketFlags, SocketType, }; use rustix::net::SocketAddrV4; use std::net::Ipv4Addr; use rustix::io; fn main() -> io::Result<()> { // --- Server side --- let server = socket(AddressFamily::INET, SocketType::STREAM, None)?; let addr = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0); // OS picks port bind(&server, &addr)?; listen(&server, 1)?; // --- Client side --- let client = socket(AddressFamily::INET, SocketType::STREAM, None)?; // Retrieve the port the OS assigned let local = rustix::net::getsockname(&server)?; connect(&client, &local)?; // Accept the connection let (conn, peer_addr) = accept(&server)?; println!("peer: {:?}", peer_addr); // Send and receive send(&client, b"ping", SendFlags::empty())?; let mut buf = [0u8; 16]; let n = recv(&conn, &mut buf, RecvFlags::empty())?; println!("received: {:?}", &buf[..n]); // b"ping" Ok(()) } // Expected output: // peer: Some(V4(127.0.0.1:NNNNN)) // received: [112, 105, 110, 103] ``` ```