Skip to content

Commit bbd498d

Browse files
posix_fallocate
1 parent 414cc86 commit bbd498d

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/fcntl.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,3 +504,16 @@ mod posix_fadvise {
504504
Errno::result(res)
505505
}
506506
}
507+
508+
#[cfg(any(
509+
target_os = "linux",
510+
target_os = "android",
511+
target_os = "emscripten",
512+
target_os = "fuchsia",
513+
any(target_os = "wasi", target_env = "wasi"),
514+
target_env = "freebsd"
515+
))]
516+
pub fn posix_fallocate(fd: RawFd, offset: libc::off_t, len: libc::off_t) -> Result<libc::c_int> {
517+
let res = unsafe { libc::posix_fallocate(fd, offset, len) };
518+
Errno::result(res)
519+
}

test/test_fcntl.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,56 @@ mod test_posix_fadvise {
232232
assert_eq!(errno, Errno::ESPIPE as i32);
233233
}
234234
}
235+
236+
#[cfg(any(target_os = "linux",
237+
target_os = "android",
238+
target_os = "emscripten",
239+
target_os = "fuchsia",
240+
any(target_os = "wasi", target_env = "wasi"),
241+
target_env = "freebsd"))]
242+
mod test_posix_fallocate {
243+
244+
use tempfile::NamedTempFile;
245+
use std::{io::Read, os::unix::io::{RawFd, AsRawFd}};
246+
use nix::errno::Errno;
247+
use nix::fcntl::*;
248+
use nix::unistd::pipe;
249+
250+
#[test]
251+
fn test_success() {
252+
const LEN: usize = 100;
253+
let mut tmp = NamedTempFile::new().unwrap();
254+
let fd = tmp.as_raw_fd();
255+
let res = posix_fallocate(fd, 0, LEN as libc::off_t).unwrap();
256+
if res == 0 {
257+
let mut data = [1u8; LEN];
258+
assert_eq!(tmp.read(&mut data).expect("read failure"), LEN);
259+
assert_eq!(&data as &[u8], &[0u8; LEN] as &[u8]);
260+
} else {
261+
match Errno::from_i32(res) {
262+
Errno::EINVAL => {
263+
eprintln!(r#"
264+
`posix_fallocate` returned EINVAL.
265+
According to POSIX.1-2008, its implementation shall return `EINVAL` if `len` is 0, `offset` is negative or the filesystem does not support this operation.
266+
According to POSIX.1-2001, its implementation shall return `EINVAL` if `len` is negative, `offset` is negative or the filesystem does not support this operation; and may return `EINVAL` if `len` is 0.
267+
However, this test is using `offset=0` and `len={}`.
268+
Suppose that the host platform is POSIX-compliant, then this can only be due to an underlying filesystem on `/tmp` that does not support `posix_fallocate`.
269+
270+
This test is passing by giving it the benefit of doubt.
271+
"#, LEN as libc::off_t);
272+
}
273+
errno => panic!("unexpected errno={}", errno),
274+
}
275+
}
276+
}
277+
278+
#[test]
279+
fn test_errno() {
280+
let (rd, _wr) = pipe().unwrap();
281+
let errno = posix_fallocate(rd as RawFd, 0, 100).unwrap();
282+
match Errno::from_i32(errno) {
283+
Errno::EINVAL | Errno::ENODEV | Errno::ESPIPE | Errno::EBADF => (),
284+
errno => panic!("errno does not match posix_fallocate spec, errno={}", errno),
285+
}
286+
}
287+
}

0 commit comments

Comments
 (0)