diff options
author | Julio Merino <julio@meroh.net> | 2018-10-17 06:02:12 -0400 |
---|---|---|
committer | Julio Merino <jmmv@google.com> | 2018-10-17 16:44:09 -0400 |
commit | 1f817c7b8e97b828dce4648c2d8fa311666806f4 (patch) | |
tree | c49b911888861917c625288743416da63b356c01 | |
parent | a063625c766e84dd5ef510935f50264b6c986abf (diff) | |
download | nix-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.md | 2 | ||||
-rw-r--r-- | src/unistd.rs | 14 | ||||
-rw-r--r-- | test/test_unistd.rs | 38 |
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; |