summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-09-28 16:10:22 +0000
committerGitHub <noreply@github.com>2019-09-28 16:10:22 +0000
commit5abef55ea3a9851cd6e83717112126b5df860cde (patch)
tree19bef9379e103fe70793a3451477c9e76cb918cb
parent2b07f8d84a03af7208dc08e0687bbea4653a8395 (diff)
parent877afa11f557a256c0d04c04f6fed14c8aa6b51d (diff)
downloadnix-5abef55ea3a9851cd6e83717112126b5df860cde.zip
Merge #1105
1105: posix_fallocate support r=asomers a=dingxiangfei2009 This PR add [`posix_fallocate`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_fallocate.html), which is available on - Linux - FreeBSD - Android - Emscripten - Fuchsia - WASI Here is a question: for some reason, `posix_fallocate` returns `EBADF` instead of `EPIPE` if a FIFO file descriptor is passed in on Linux 4.19.64. In the test `EBADF` is used for now, but I would like to know if such behaviour is expected. Co-authored-by: Ding Xiang Fei <dingxiangfei2009@gmail.com>
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/fcntl.rs21
-rw-r--r--test/test_fcntl.rs57
3 files changed, 81 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index af2069a0..74ecba0b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased] - ReleaseDate
### Added
+- Added `posix_fallocate`.
+ ([#1105](https://github.com/nix-rust/nix/pull/1105))
+
- Implemented `Default` for `FdSet`
([#1107](https://github.com/nix-rust/nix/pull/1107))
diff --git a/src/fcntl.rs b/src/fcntl.rs
index 2cb7f505..7d745b06 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -505,3 +505,24 @@ mod posix_fadvise {
Errno::result(res)
}
}
+
+#[cfg(any(
+ target_os = "linux",
+ target_os = "android",
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ any(target_os = "wasi", target_env = "wasi"),
+ target_os = "freebsd"
+))]
+pub fn posix_fallocate(
+ fd: RawFd,
+ offset: libc::off_t,
+ len: libc::off_t
+) -> Result<()> {
+ let res = unsafe { libc::posix_fallocate(fd, offset, len) };
+ match Errno::result(res) {
+ Err(err) => Err(err),
+ Ok(0) => Ok(()),
+ Ok(errno) => Err(crate::Error::Sys(Errno::from_i32(errno))),
+ }
+}
diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs
index 1bcf12cb..38a1e7b9 100644
--- a/test/test_fcntl.rs
+++ b/test/test_fcntl.rs
@@ -231,3 +231,60 @@ mod test_posix_fadvise {
assert_eq!(errno, Errno::ESPIPE as i32);
}
}
+
+#[cfg(any(target_os = "linux",
+ target_os = "android",
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ any(target_os = "wasi", target_env = "wasi"),
+ target_os = "freebsd"))]
+mod test_posix_fallocate {
+
+ use tempfile::NamedTempFile;
+ use std::{io::Read, os::unix::io::{RawFd, AsRawFd}};
+ use nix::errno::Errno;
+ use nix::fcntl::*;
+ use nix::unistd::pipe;
+
+ #[test]
+ fn success() {
+ const LEN: usize = 100;
+ let mut tmp = NamedTempFile::new().unwrap();
+ let fd = tmp.as_raw_fd();
+ let res = posix_fallocate(fd, 0, LEN as libc::off_t);
+ match res {
+ Ok(_) => {
+ let mut data = [1u8; LEN];
+ assert_eq!(tmp.read(&mut data).expect("read failure"), LEN);
+ assert_eq!(&data[..], &[0u8; LEN][..]);
+ }
+ Err(nix::Error::Sys(Errno::EINVAL)) => {
+ // POSIX requires posix_fallocate to return EINVAL both for
+ // invalid arguments (i.e. len < 0) and if the operation is not
+ // supported by the file system.
+ // There's no way to tell for sure whether the file system
+ // supports posix_fallocate, so we must pass the test if it
+ // returns EINVAL.
+ }
+ _ => res.unwrap(),
+ }
+ }
+
+ #[test]
+ fn errno() {
+ let (rd, _wr) = pipe().unwrap();
+ let err = posix_fallocate(rd as RawFd, 0, 100).unwrap_err();
+ use nix::Error::Sys;
+ match err {
+ Sys(Errno::EINVAL)
+ | Sys(Errno::ENODEV)
+ | Sys(Errno::ESPIPE)
+ | Sys(Errno::EBADF) => (),
+ errno =>
+ panic!(
+ "unexpected errno {}",
+ errno,
+ ),
+ }
+ }
+}