1# Conventions 2 3In order to achieve our goal of wrapping [libc][libc] code in idiomatic rust 4constructs with minimal performance overhead, we follow the following 5conventions. 6 7Note that, thus far, not all the code follows these conventions and not all 8conventions we try to follow have been documented here. If you find an instance 9of either, feel free to remedy the flaw by opening a pull request with 10appropriate changes or additions. 11 12## Change Log 13 14We follow the conventions laid out in [Keep A CHANGELOG][kacl]. 15 16[kacl]: https://github.com/olivierlacan/keep-a-changelog/tree/18adb5f5be7a898d046f6a4acb93e39dcf40c4ad 17 18## libc constants, functions and structs 19 20We do not define integer constants ourselves, but use or reexport them from the 21[libc crate][libc]. 22 23We use the functions exported from [libc][libc] instead of writing our own 24`extern` declarations. 25 26We use the `struct` definitions from [libc][libc] internally instead of writing 27our own. If we want to add methods to a libc type, we use the newtype pattern. 28For example, 29 30```rust 31pub struct SigSet(libc::sigset_t); 32 33impl SigSet { 34 ... 35} 36``` 37 38When creating newtypes, we use Rust's `CamelCase` type naming convention. 39 40## Bitflags 41 42Many C functions have flags parameters that are combined from constants using 43bitwise operations. We represent the types of these parameters by types defined 44using our `libc_bitflags!` macro, which is a convenience wrapper around the 45`bitflags!` macro from the [bitflags crate][bitflags] that brings in the 46constant value from `libc`. 47 48We name the type for a set of constants whose element's names start with `FOO_` 49`FooFlags`. 50 51For example, 52 53```rust 54libc_bitflags!{ 55 pub struct ProtFlags: libc::c_int { 56 PROT_NONE; 57 PROT_READ; 58 PROT_WRITE; 59 PROT_EXEC; 60 #[cfg(any(target_os = "linux", target_os = "android"))] 61 PROT_GROWSDOWN; 62 #[cfg(any(target_os = "linux", target_os = "android"))] 63 PROT_GROWSUP; 64 } 65} 66``` 67 68 69## Enumerations 70 71We represent sets of constants that are intended as mutually exclusive arguments 72to parameters of functions by [enumerations][enum]. 73 74 75## Structures Initialized by libc Functions 76 77Whenever we need to use a [libc][libc] function to properly initialize a 78variable and said function allows us to use uninitialized memory, we use 79[`std::mem::MaybeUninit`][std_MaybeUninit] when defining the variable. This 80allows us to avoid the overhead incurred by zeroing or otherwise initializing 81the variable. 82 83[bitflags]: https://crates.io/crates/bitflags/ 84[enum]: https://doc.rust-lang.org/reference.html#enumerations 85[libc]: https://crates.io/crates/libc/ 86[std_MaybeUninit]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html 87