summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulio Merino <julio@meroh.net>2018-10-17 06:02:12 -0400
committerJulio Merino <jmmv@google.com>2018-10-17 16:44:09 -0400
commit1f817c7b8e97b828dce4648c2d8fa311666806f4 (patch)
treec49b911888861917c625288743416da63b356c01
parenta063625c766e84dd5ef510935f50264b6c986abf (diff)
downloadnix-1f817c7b8e97b828dce4648c2d8fa311666806f4.zip
Add a truncate(2) wrapper
This also adds a test for truncate (obviously) but, while doing so, also adds a test for the already-existing ftruncate.
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/unistd.rs14
-rw-r--r--test/test_unistd.rs38
3 files changed, 53 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e1e0c01d..7e16278a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Added `AF_UNSPEC` wrapper to `AddressFamily` ([#948](https://github.com/nix-rust/nix/pull/948))
- Added the `mode_t` public alias within `sys::stat`.
([#954](https://github.com/nix-rust/nix/pull/954))
+- Added a `truncate` wrapper.
+ ([#956](https://github.com/nix-rust/nix/pull/956))
### Changed
- Increased required Rust version to 1.22.1/
diff --git a/src/unistd.rs b/src/unistd.rs
index ad06a3c0..70882604 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -989,6 +989,20 @@ fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
/// Truncate a file to a specified length
///
/// See also
+/// [truncate(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html)
+pub fn truncate<P: ?Sized + NixPath>(path: &P, len: off_t) -> Result<()> {
+ let res = try!(path.with_nix_path(|cstr| {
+ unsafe {
+ libc::truncate(cstr.as_ptr(), len)
+ }
+ }));
+
+ Errno::result(res).map(drop)
+}
+
+/// Truncate a file to a specified length
+///
+/// See also
/// [ftruncate(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html)
pub fn ftruncate(fd: RawFd, len: off_t) -> Result<()> {
Errno::result(unsafe { libc::ftruncate(fd, len) }).map(drop)
diff --git a/test/test_unistd.rs b/test/test_unistd.rs
index 54cbff8d..981ab53d 100644
--- a/test/test_unistd.rs
+++ b/test/test_unistd.rs
@@ -6,7 +6,7 @@ use nix::sys::wait::*;
use nix::sys::stat::{self, Mode, SFlag};
use std::{env, iter};
use std::ffi::CString;
-use std::fs::File;
+use std::fs::{self, File};
use std::io::Write;
use std::os::unix::prelude::*;
use tempfile::{self, tempfile};
@@ -390,6 +390,42 @@ fn test_pipe2() {
assert!(f1.contains(FdFlag::FD_CLOEXEC));
}
+#[test]
+fn test_truncate() {
+ let tempdir = tempfile::tempdir().unwrap();
+ let path = tempdir.path().join("file");
+
+ {
+ let mut tmp = File::create(&path).unwrap();
+ const CONTENTS: &[u8] = b"12345678";
+ tmp.write_all(CONTENTS).unwrap();
+ }
+
+ truncate(&path, 4).unwrap();
+
+ let metadata = fs::metadata(&path).unwrap();
+ assert_eq!(4, metadata.len());
+}
+
+#[test]
+fn test_ftruncate() {
+ let tempdir = tempfile::tempdir().unwrap();
+ let path = tempdir.path().join("file");
+
+ let tmpfd = {
+ let mut tmp = File::create(&path).unwrap();
+ const CONTENTS: &[u8] = b"12345678";
+ tmp.write_all(CONTENTS).unwrap();
+ tmp.into_raw_fd()
+ };
+
+ ftruncate(tmpfd, 2).unwrap();
+ close(tmpfd).unwrap();
+
+ let metadata = fs::metadata(&path).unwrap();
+ assert_eq!(2, metadata.len());
+}
+
// Used in `test_alarm`.
static mut ALARM_CALLED: bool = false;