1
votes

I am building a server client app, where server is Rust and obtaining stat information for a given path and transfer it to C client. I want the C client to be able to directly use the bytes, and cast it to a struct. The stat I am talking about is this struct in C. Here is my Rust representation of the stat:

#[repr(C)]
pub struct Stat {
    st_dev: u64,
    st_ino: u64,
    st_nlink: u64,
    st_mode: u32,
    st_uid: u32,
    st_gid: u32,
    st_rdev: u64,
    st_size: u64,
    st_blksize: u64,
    st_blocks: u64,
    st_atime: i64,
    st_atime_nsec: i64,
    st_mtime: i64,
    st_mtime_nsec: i64,
    st_ctime: i64,
    st_ctime_nsec: i64
}

impl Stat {
    pub fn encode(self) -> Vec<u8> {
        unsafe {
            std::slice::from_raw_parts(
                (&self as *const Stat) as *const u8,
                std::mem::size_of::<Stat>()
            ).to_owned()
        }
    }
}

However, when I find the values are not matching once I received it from my C side. Below is the value comparison for each field following the order in the struct,

# C:
16777220
8613988721
0
0
5
0
16832
6879832142633762816
0
1327895242430480384
20
687194767360
17592186044416
0
6879832142633762816
0

#Rust:
16777220
8613988721
5
16832
501
20
0
160
4096
0
1601835746
0
1601835746
0
1601835746
309174704

Does anyone know what caused this problem? And how can I solve it?

1
From your link: “Note: the order of fields in the stat structure varies somewhat across architectures. In addition, the definition above does not show the padding bytes that may be present between some fields on various architectures. Consult the glibc and kernel source code if you need to know the details.”mcarton

1 Answers

1
votes

Use nix. See https://docs.rs/nix/newest/nix/sys/stat/fn.stat.html

nix uses the struct stat from the libc package, which has a separate manually generated struct definition for every supported platform. I don't precisely understand why you want to encode stat structures, but you need to keep in mind that they will most likely be mutually incompatible betweeen different architechtures, platforms, and OS versions. That is, you can only reliably bytewise encode and decode them when the encoder and decoder are running on the same version of the same platform.