rust-lang / libc

Raw bindings to platform APIs for Rust
https://docs.rs/libc
Apache License 2.0
2.09k stars 1.04k forks source link

Statvfs members overflows in i686 (32bit) linux system #738

Closed ixeft closed 7 years ago

ixeft commented 7 years ago

Trying to compile https://github.com/greshake/i3status-rust and particularly this file : https://github.com/greshake/i3status-rust/blob/master/src/blocks/disk_space.rs I noticed that Statvfs::b_fsize where u32 instead of u64 creating a compilation error

using "as u64" I got the code compiling but now, with path bigger than 2Gio, I got an overflow getting wrong value of statvfs.f_bfree / statvfs.f_bsize (crazy big values)

Exemple of code that should demontrate the bug with 32bit system (Archlinux i686 - Intel Atom Z520)

extern crate nix;
use self::nix::sys::statvfs::vfs::Statvfs;
let statvfs = Statvfs::for_path(Path::new("a/path/with/size/bigger/than/4Gio"))

Using glibc in C/C++ I would define _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE or even _FILE_OFFSET_BITS

to solve this problem. I didn't found a way to do it with libc

I reported the problem to rust-nix project, https://github.com/nix-rust/nix/issues/743

@Susurrus Sugested me to report it here :

We just wrap the statvfs strict provided by libc. This is likely an issue with the type as it's declared there. Please open and issue there to discuss this and link back to this one.

Regards,

alexcrichton commented 7 years ago

I think this is where typically statvfs64 is typically used, although looks like there's not bindings for it yet?

ixeft commented 7 years ago

However, if I'm not wrong, you need to define LARGEFILE_SOURCE to access statvfs64 :)

Susurrus commented 7 years ago

@ixeft Yes, I think the correct solution is not to have two different versions of the statvfs struct but instead to define _LARGEFILE64_SOURCE and expose the statvfs64 struct and then i3status should use statvfs64 directly rather than using statvfs.