Rust friendly bindings to *nix APIs

Overview

Rust bindings to *nix APIs

Cirrus Build Status crates.io

Documentation (Releases)

Nix seeks to provide friendly bindings to various *nix platform APIs (Linux, Darwin, ...). The goal is to not provide a 100% unified interface, but to unify what can be while still providing platform specific APIs.

For many system APIs, Nix provides a safe alternative to the unsafe APIs exposed by the libc crate. This is done by wrapping the libc functionality with types/abstractions that enforce legal/safe usage.

As an example of what Nix provides, examine the differences between what is exposed by libc and nix for the gethostname system call:

// libc api (unsafe, requires handling return code/errno)
pub unsafe extern fn gethostname(name: *mut c_char, len: size_t) -> c_int;

// nix api (returns a nix::Result<CStr>)
pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr>;

Supported Platforms

nix target support consists of two tiers. While nix attempts to support all platforms supported by libc, only some platforms are actively supported due to either technical or manpower limitations. Support for platforms is split into three tiers:

  • Tier 1 - Builds and tests for this target are run in CI. Failures of either block the inclusion of new code.
  • Tier 2 - Builds for this target are run in CI. Failures during the build blocks the inclusion of new code. Tests may be run, but failures in tests don't block the inclusion of new code.
  • Tier 3 - Builds for this target are run in CI. Failures during the build do not block the inclusion of new code. Testing may be run, but failures in tests don't block the inclusion of new code.

The following targets are supported by nix:

Tier 1:

  • aarch64-unknown-linux-gnu
  • arm-unknown-linux-gnueabi
  • armv7-unknown-linux-gnueabihf
  • i686-unknown-freebsd
  • i686-unknown-linux-gnu
  • i686-unknown-linux-musl
  • mips-unknown-linux-gnu
  • mips64-unknown-linux-gnuabi64
  • mips64el-unknown-linux-gnuabi64
  • mipsel-unknown-linux-gnu
  • powerpc64le-unknown-linux-gnu
  • x86_64-apple-darwin
  • x86_64-unknown-freebsd
  • x86_64-unknown-linux-gnu
  • x86_64-unknown-linux-musl

Tier 2:

  • aarch64-apple-ios
  • aarch64-linux-android
  • arm-linux-androideabi
  • arm-unknown-linux-musleabi
  • armv7-apple-ios
  • armv7-linux-androideabi
  • armv7s-apple-ios
  • i386-apple-ios
  • i686-apple-darwin
  • i686-linux-android
  • powerpc-unknown-linux-gnu
  • s390x-unknown-linux-gnu
  • x86_64-apple-ios
  • x86_64-linux-android
  • x86_64-unknown-netbsd

Tier 3:

  • x86_64-fuchsia
  • x86_64-unknown-redox
  • x86_64-unknown-linux-gnux32

Usage

nix requires Rust 1.40.0 or newer.

To use nix, add this to your Cargo.toml:

[dependencies]
nix = "0.20.0"

Contributing

Contributions are very welcome. Please See CONTRIBUTING for additional details.

Feel free to join us in the nix-rust/nix channel on Gitter to discuss nix development.

License

Nix is licensed under the MIT license. See LICENSE for more details.

Comments
  • Add more ptrace_* wrappers

    Add more ptrace_* wrappers

    Btw. I think that the nix::sys::ptrace::ptrace function should be marked as unsafe. It allows to change arbitrary registers and addresses in a child process - just as dereferencing a pointer is unsafe in Rust.

    I was unable to use libc::user_regs_struct, the Rust compiler complains that it can't find the members. By the way, we're missing PTRACE_GETREGS.

    I tried to use the user_regs_struct in the following way:

    extern crate libc;
    
    fn main() {
        println!("{}", libc::user_regs_struct::rdx);
    }
    

    which bails out with

    file: 'file:///home/marcin/proj/user_regs/src/main.rs'
    severity: 'Error'
    message: 'no associated item named `rdx` found for type `libc::user_regs_struct` in the current scope'
    at: '4,22'
    source: ''
    
    opened by marmistrz 69
  • Add fuchsia support

    Add fuchsia support

    This change adds support for the Fuchsia operating system to the nix crate. Fuchsia developers have a use case for nix, particularly its safe interfaces to the recvmsg(2) and sendmsg(2). Adding support requires:

    • incrementing the libc dependency to 0.2.74
    • conditionally not compiling nix functionality which depends on libc functionality that does not exist for Fuchsia
    opened by amanda-tait 60
  • Add `getpwnam` and related functions

    Add `getpwnam` and related functions

    This PR closes #862.

    Implemented functions:

    • As User::query:
      • getpwnam
      • getpwuid
    • As Group::query:
      • getgrgid
      • getgrnam
    • As Users iterator:
      • getpwent
      • setpwent
      • endpwent
    • As Groups iterator:
      • getgrent
      • setgrent
      • endgrent

    ~I wanted to implement getgrent, setgrent and endgrent, but they are missing from libc. (See https://github.com/rust-lang/libc/issues/923 )~

    opened by ctrlcctrlv 50
  • Improve ioctl docs

    Improve ioctl docs

    Integrates suggestions and comments made in #641. Basically we hid a lot of the internal workings of things and also revised the docs to make it more clear the exact API that nix is exposing.

    There is a small amount of code cleanup I did in the macros. I also fixed the bad version of the ioctl! macro and also added a bad none version for use with no-data, hardcoded-number ioctls.

    Would appreciate any and all feedback. Please especially fetch this code locally and generate the pretty docs for it (cargo doc --no-deps --open) so you can see what our users will see.

    Closes #641. Closes #573.

    cc @cmr @roblabla

    opened by Susurrus 41
  • reimplement sendmmsg/recvmmsg with better API

    reimplement sendmmsg/recvmmsg with better API

    Motivation is explained in #1602, new version allows to receive data without performing allocations inside the receive loop and to use received data without extra copying.

    This pull request contains a breaking change to API recvmmsg (obviously) and also affects recvmsg - new version does not set length of control message buffer if one is passed. Later change can be avoided with a bit more copy-paste.

    Fixes #1602

    opened by pacak 40
  • Merge New CI Infrastructure Based on Trust/Cross Into Master

    Merge New CI Infrastructure Based on Trust/Cross Into Master

    See discussion on https://github.com/nix-rust/nix/pull/528. This PR is to track the final decision of whether we are ready to merge the new CI infrastructure (and related bug fixes) back into master. Initially, we know that the branch is not ready to merge (as there are still failing tests).

    This PR acts as a single point of reference to get the current status of how close we are to merging things back into master. A number of issues with "TRUST CI" in the title have been created for the work that appears to be required to get us to the point where this branch can be merged.

    opened by posborne 38
  • Added ptrace utilities.

    Added ptrace utilities.

    Some ptrace functions return structures through the data argument. This commit adds utilities to return data through this mechanism and function specialisations for a few of these functions (getting event messages or the siginfo_t struct). Once the next version of libc is released these utilities will be expanded to include the fpregs and user_regs structs.

    Due to the need to use unsafe blocks to utilise these ptrace features I feel these are good candidates for inclusion into rust-nix

    opened by xd009642 37
  • Add Redox support for most of the modules

    Add Redox support for most of the modules

    Some things are not implemented yet in redox, so a lot of annotations were added to remove functions when compiling for redox. Those functions will hopefully be added in time, but for now it's better to have partial support than none.

    Blocked by https://github.com/rust-lang/libc/pull/1438

    opened by AdminXVII 33
  • Add reboot() support on Linux

    Add reboot() support on Linux

    This adds support for calling reboot(2) on Linux (useful for implementing PID 1!).

    • Testing: I can't imagine how this could be tested other than manually, which is what I did to ensure it works.
    • libc: for some reason libc includes neither reboot() function, nor RB_* constants, so I had to hack-define them here. Should I open a bug/PR against the libc crate?
    • API: I went with reboot() function for restarting, powering off, halting, etc. and an additional set_cad_enabled() function for enabling/disabling Ctrl-Alt-Delete, which still corresponds to reboot() C call, but has different semantics and return type. (But I'm open to suggestions here -- maybe it would be better to separate each action into its own function, i.e. restart(), poweroff(), halt()?)
    • Documentation: I see most of the things in nix are undocumented, so I didn't document anything except for the set_cad_enabled() function, which obviously uses a non-standard name.
    • Portability: I implemented the Linux version as I'm not familiar with anything else, but there surely are others (ex. BSD). If I didn't mess up anything, the new code is only compiled on Linux/Android, so it should be straightforward to implement the other versions too.
    opened by bugaevc 33
  • Rename project to avoid confusion with Nix.

    Rename project to avoid confusion with Nix.

    While I don't mind "*nix" to denote Unix (and Unix-like) systems, "Nix" specifically is taken by the "purely functional package manager". This could get worse in the future, because of how cargo fits almost perfectly with the Nix model, and I have seen integration prototypes already. You might have to deal with crates.io packages that interact with Nix, or even fully reimplement it in Rust.

    I know it doesn't sound as cool, but what about "posix.rs" or some variation thereof?

    opened by eddyb 31
  • Add support for getifaddrs.

    Add support for getifaddrs.

    Here's a first attempt at a rustian interface for getifaddrs, please review.

    Changes for the changelog:

    • Added nix::ifaddrs::{getifaddrs, InterfaceAddressIterator, InterfaceAddress and InterfaceFlags}

    Closes #650. Closes #764.

    opened by mwanner 30
  • Failures in `Linux armv7 uclibceabihf` CI target

    Failures in `Linux armv7 uclibceabihf` CI target

    The Linux armv7 uclibceabihf CI target is failing in multiple unrelated PRs e.g.:

    • https://github.com/nix-rust/nix/pull/1948/checks?check_run_id=10378264392
    • https://github.com/nix-rust/nix/pull/1945/checks?check_run_id=10378274766
    • https://github.com/nix-rust/nix/pull/1947/checks?check_run_id=10378270076

    With

    $TOOL +$TOOLCHAIN clippy $ZFLAGS --target $TARGET --all-targets -- -D warnings
        Checking nix v0.26.1 (/tmp/cirrus-ci-build)
    error: argument to `std::mem::size_of_val()` is a reference to a reference
        --> src/sys/socket/mod.rs:1295:17
         |
    1295 |                 mem::size_of_val(&iv) + iv.len()
         |                 ^^^^^^^^^^^^^^^^^^^^^
         |
         = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#size_of_ref
         = note: `-D clippy::size-of-ref` implied by `-D warnings`
    
    error: argument to `std::mem::size_of_val()` is a reference to a reference
        --> src/sys/socket/mod.rs:1295:17
         |
    1295 |                 mem::size_of_val(&iv) + iv.len()
         |                 ^^^^^^^^^^^^^^^^^^^^^
         |
         = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#size_of_ref
    note: the lint level is defined here
        --> src/lib.rs:46:24
         |
    46   | #![cfg_attr(test, deny(warnings))]
         |                        ^^^^^^^^
         = note: `#[deny(clippy::size_of_ref)]` implied by `#[deny(warnings)]`
    
    error: could not compile `nix` due to previous error
    warning: build failed, waiting for other jobs to finish...
    error: could not compile `nix` due to previous error
    
    Exit status: 101
    
    opened by JonathanWoollett-Light 0
  • sendmmsg() in v0.26 do not support different content in control messages among messages

    sendmmsg() in v0.26 do not support different content in control messages among messages

    For a UDP server program, it is very useful to use sendmmsg() and recvmmsg() to improve the performance by reducing syscalls.

    And it is not a uncommon setup that a single socket can receive IP packets with difference destination addresses. In this type of setup, we obtain the real destination addresses of messages from the Ipv4PacketInfo/Ipv6PacketInfo control message when using recvmmsg(). Corresponding to that, Ipv4PacketInfo/Ipv6PacketInfo control messages are used to set source addresss when sending out multiple messages at once via sendmmsg().

    In the breaking change introduced by 0.26 about sendmmsg() api (#1744), it seems it was assumed that control messages are shared/same across all the messages in the batch, I think this is a false assumption.

    Did I read the code wrong? If so, is there any example of how to use the new API correctly in this use case.

    opened by hunts 0
  • SockProtocol: Missing IPPROTO_IP

    SockProtocol: Missing IPPROTO_IP

    Hi,

    I try to implement a raw socket to be able to fetch all (sent/received) IP packets through a given network interface. For this I would like to use libc::IPPROTO_IP, but it does not seem to be available in SockProtocol.

    I try to do the following (obviously nix::sys::socket::SockProtocol::IpProtoIp does not exist)

      let fd = match nix::sys::socket::socket(
                nix::sys::socket::AddressFamily::Packet,
                nix::sys::socket::SockType::Raw,
                nix::sys::socket::SockFlag::SOCK_NONBLOCK,
                nix::sys::socket::SockProtocol::IpProtoIp,
            ) {
                Err(err) => return Err(format!("Error: {}", err).to_string()),
                Ok(fd) => fd,
            };
    
            // attach to device
            match nix::sys::socket::setsockopt(
                fd,
                nix::sys::socket::sockopt::BindToDevice,
                &OsString::from(&iface.to_string()),
            ) {
                Ok(()) => (),
                Err(err) => return Err(format!("Error: {}", err).to_string()),
            };
    

    Is there a workaround to add a protocol not supported by nix::sys::socket::SockProtocol?

    Thanks.

    opened by jornfranke 0
  • How is ucontext's interface safe?

    How is ucontext's interface safe?

    The following segfaults just as it gets out of libc::setcontext -> libc::getcontext, after printing "Run" just once (latest arch on x86_64):

    use nix::ucontext::UContext;
    
    fn main() {
        let v = vec![1, 2, 3];
        let ctx = UContext::get().unwrap();
        println!("Run");
        std::mem::drop(v);
        ctx.set().unwrap();
    }
    

    Considering that it seems to restore the stack pointer and registries without any information about what has happened to the referred variables in the meantime I don't find it surprising... Or do I not understand what UContext is supposed to do at all?

    How is this supposed to be used/to work? Doesn't the set miss being marked unsafe and extensive explanation on what would make its usage correct?

    NB: This also segfaults:

    use nix::ucontext::UContext;
    
    fn main() {
        let ctx = UContext::get().unwrap();
        println!("Run");
        ctx.set().unwrap();
    }
    

    but even if that turned into an infinite loop I wouldn't consider the behavior correct unless something reasonable happens to the first example as well...

    opened by Ten0 0
  • release-please

    release-please

    Adds release-please automation.

    • release-please: Automatically updates the SemVer version, creates a PR for each release (people don't need to manually edit the changelog) when merged adds the release tag. This can be expanded to incorporate other functionality later (e.g. publishing to crates.io).
    • gitlint: Enforce conventional commits required by release-please

    See https://github.com/JonathanWoollett-Light/nix/pull/1

    opened by JonathanWoollett-Light 8
Releases(v0.8.0)
Owner
null
nginx bindings for Rust

nginx-rs This crate provides nginx bindings for Rust. Currently, only Linux is supported. How to Use Add nginx crate to Cargo.toml [dependencies] ngin

ArvanCloud 104 Jan 2, 2023
Rust bindings for iptables

Rust iptables This crate provides bindings for iptables application in Linux (inspired by go-iptables). This crate uses iptables binary to manipulate

Navid 63 Nov 17, 2022
Rust bindings to Windows API

winapi-rs Documentation Official communication channel: #windows-dev on the Rust Community Discord This crate provides raw FFI bindings to all of Wind

Peter Atashian 1.6k Jan 1, 2023
Rust bindings for the FreeBSD capsicum framework

capsicum Contain the awesome! Rust bindings for the FreeBSD capsicum framework for OS capability and sandboxing Prerequisites Rust, Cargo, and FreeBSD

Dan Robertson 52 Dec 5, 2022
Idiomatic inotify wrapper for the Rust programming language

inotify-rs Idiomatic inotify wrapper for the Rust programming language. extern crate inotify; use std::env; use inotify::{ EventMask, Watch

Hanno Braun 220 Dec 26, 2022
Rust library for filesystems in userspace (FUSE)

Rust FUSE - Filesystem in Userspace About fuse-rs is a Rust library crate for easy implementation of FUSE filesystems in userspace. fuse-rs does not j

Andreas Neuhaus 916 Jan 9, 2023
Rust implementation of a FreeBSD jail library

libjail-rs libjail-rs aims to be a rust implementation of the FreeBSD jail(3) library. While feature parity is a goal, a one-to-one implementation of

fubarnetes 38 Sep 27, 2022
A `nix` and `nix-shell` wrapper for shells other than `bash`

nix-your-shell A nix and nix-shell wrapper for shells other than bash. nix develop and nix-shell use bash as the default shell, so nix-your-shell prin

Mercury 15 Apr 10, 2023
Progress In Nix - Pacman inspired frontend for Nix

Progress In Nix Pinix is a Pacman inspired frontend for Nix. It wraps a regular Nix command and replaces the output with a more modern and informative

Rémi Dupré 23 Mar 9, 2024
Rust bindings for the WebView2 COM APIs

webview2-rs Rust bindings for the WebView2 COM APIs Crates in this repo The root of this repo defines a virtual workspace in Cargo.toml which includes

Bill Avery 24 Dec 15, 2022
Safe, idiomatic bindings to cFE and OSAL APIs for Rust

n2o4 The n2o4 crate provides safe, idiomatic Rust bindings to the APIs of cFE and OSAL, the libraries of the Core Flight System (cFS). IMPORTANT NOTE

null 3 Aug 29, 2022
Dog command for *nix systems, Rust port of dog.

dog-rs Dog command for *nix systems, Rust port of dog. Because there is a cat command, should be a dog command too. It was written completely using VS

Juanjo Salvador 2 Sep 29, 2021
An alternative broken buggy Nix implementation in Rust + Java (for evaluation)

An alternative broken buggy Nix implementation in Rust + Java (for evaluation)

Moritz Hedtke 1 Feb 12, 2022
NixEl is a Rust library that turns Nix code into a variety of correct, typed, memory-safe data-structures

?? NixEL Lexer, Parser, Abstract Syntax Tree and Concrete Syntax Tree for the Nix Expressions Language. NixEl is a Rust library that turns Nix code in

Kevin Amado 56 Dec 29, 2022
Nix binary cache implemented in rust using libnix-store

harmonia Build Whole application nix-shell --run cargo b C Library Wrapper around libnixstore nix-shell --run make Note: The makefile is only to pro

Helsinki Systems 84 Dec 24, 2022
Tvix - A Rust implementation of Nix

Tvix Tvix is a new implementation of the Nix language and package manager. See the announcement post for information about the background of this proj

The Virus Lounge 49 Feb 17, 2023
A type-safe Rust interface to the Nix CLI

runix A typesafe interface to the nix CLI. by flox Installation Install with cargo add (Rust >= 1.64) cargo add runix Alternatively, manually add runi

flox 43 Mar 6, 2023
A Nix template for full-stack web apps in Rust using Leptos

leptos-fullstack A Nix template for full-stack web apps in Rust using Leptos. Tech used: Leptos full-stack framework server functions ssr + hydration

Sridhar Ratnakumar 6 Aug 4, 2023
Rust + htmx + tailwind + nix + redb + twind demo web app

htmx sorta A demo project where I learn and play with my "Rust web stack": Rust Nix flakes for building and dev shell redb Rust local key-value store

Rustshop 19 Oct 5, 2023
Your project’s nix-env [maintainer=@Profpatsch]

lorri https://github.com/nix-community/lorri lorri is a nix-shell replacement for project development. lorri is based around fast direnv integration f

Nix community projects 442 Jan 1, 2023