Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Strange struct definition from crate nix

I just encountered this weird struct definition, it is in fcntl.rs from the crate nix.

pub struct OFlag: c_int {
    /// Mask for the access mode of the file.
    O_ACCMODE; 

    // other fields are omitted.
}

A normal struct in my perspective will be something like this:

struct Person{
    name: String,
    age: u8,
}

So, here are my doubts:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  1. what is OFlag: c_int?

    c_int is an type alias of i32. pub type c_int = i32;

  2. Why don’t its fields have any type annotation?

My surmise is that OFlag is of type c_int, and the fields are something similar to enum‘s fields.(compliant to the open syscall function signature int open(const char *pathname, int flags, mode_t mode) ) But this is just my guesswork, an explanation citing rust official doc would be appreciated.

>Solution :

The code you quoted is not valid Rust code on its own. It’s code that gets passed to an internal macro of the nix crate called libc_bitflags!(). This macro takes the quoted code as input and transforms it into valid Rust code.

The libc_bitflags!() macro is a simple wrapper around the bitflags!() macro from the bitflags crate. The wrapper simplifies creating bitflags structs that take all their values from constants defined in the libc crate. For example this invocation

libc_bitflags!{
    pub struct ProtFlags: libc::c_int {
        PROT_NONE;
        PROT_READ;
        PROT_WRITE;
        PROT_EXEC;
    }
}

gets expanded to

bitflags!{
    pub struct ProtFlags: libc::c_int {
        const PROT_NONE = libc::PROT_NONE;
        const PROT_READ = libc::PROT_READ;
        const PROT_WRITE = libc::PROT_WRITE;
        const PROT_EXEC = libc::PROT_EXEC;
    }
}

which in turn will be expanded to Rust code by the bitflags!() macro. The libc::c_int type is used as the type of the bits field of the resulting struct. The constants inside will become associated constants of the resulting struct. See the documentation of the bitflags crate for further details.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading