Help understanding OS system calls and how Rust does this versus other languages

I need some help understanding how and what API's exist out there to communicate to an OS. In my case I'm running Ubuntu 17 on the Linux Kernel 4.12. I have a electrical engineering background with a minor in embedded software so i'm not a guru when it comes to understanding OS's. I assume this is a big question to ask so let me narrow it down to a few specifics to what I'm asking.

My understanding is that Rust is a systems programming language just like C/C++. In C/C++ we can use the POSIX standard API's to communicate to the OS in Linux. This is very useful and convenient since the Linux kernel/OS is written in C. So

Is there a POSIX like API out there but specifically for Rust? If not, is there a wrapper to the POSIX API's that Rust uses?

Which sources out there do I use. I did a search and found several results like the crate "nix" and a few others out there. I'm concerned that some of these are not supported or developed by random people. How do I know which ones are credible and maintained?

Is the term crate similar to a Library or API like POSIX?

My understanding is that there exists an ABI to provide this one to one translation from an API like POSIX to the Kernel upon compilation?! I read somewhere that Rust doesn't have a ABI, is that true? Could someone perhaps point me to a resource that better explains how an API or ABI makes that communication possible between a systems programming language like C/C++ and the Kernel? I slightly confused in this area and it's preventing me the ability to really understand the architecture of Rust from this perspective.

2 Likes

https://crates.io/crates/libc if you want a low-level, direct binding. https://crates.io/crates/nix if you'd like something slightly more rust-like.

I personally go by things like download counts, and authors. libc is maintained by the Rust libs team and is one of the most downloaded crates ever. nix also has many familiar faces and has 2/3rds of a million downloads.

There are a bunch, if you search on crates.io you'll find them :smile:

Rust does not have a stable ABI, but when you're trying to call into other code, like the kernel, you need to follow its ABI, which isn't Rust's :slight_smile: In this case, it's C's, which Rust has good support for.

6 Likes

Thank you so much for that explanation. In the crate libc and others that fall under this category does it show how Rust calls into the C ABI?

@shanedora when looking into how Rust interfaces with C code, search for the term FFI (Foreign Function Interface). You'll find the links to knowledge you need to represent your Rust strings as C-strings, binary compatible struct layouts, call stack conventions and the like.

IMHO, this is a part of Rust that is really well done. Enjoy--you are in for a treat when you find "it just works". :slight_smile:

2 Likes

Probably stating the obvious, but please note that in most cases you will NOT need to call POSIX APIs directly. You'd instead just use Rust's standard library.

Is the term crate similar to a Library or API like POSIX?

A crate is nothing but a library packaged in special way such that Rust's tools can easily work with it (for example Cargo can automatically download crates for you.)

2 Likes

It's worth mentioning that although rust doesn't have a stable ABI, you can choose to use a stable (C) ABI by marking things with #[repr(C)] and extern "C". You can also use other reprs, for example on enums you can use #[repr(u32)] on a plain enum to force it to be a u32.

Lots of information on this in the nomicon.