summaryrefslogtreecommitdiff
path: root/src/unistd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/unistd.rs')
-rw-r--r--src/unistd.rs48
1 files changed, 45 insertions, 3 deletions
diff --git a/src/unistd.rs b/src/unistd.rs
index 74d74c9c..2eb218b3 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -5,10 +5,10 @@ use fcntl::{fcntl, OFlag, O_NONBLOCK, O_CLOEXEC, FD_CLOEXEC};
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
use libc::{self, c_char, c_void, c_int, c_uint, size_t, pid_t, off_t, uid_t, gid_t, mode_t};
use std::mem;
-use std::ffi::{CString, CStr, OsString};
-use std::os::unix::ffi::OsStringExt;
-use std::path::PathBuf;
+use std::ffi::{CString, CStr, OsString, OsStr};
+use std::os::unix::ffi::{OsStringExt, OsStrExt};
use std::os::unix::io::RawFd;
+use std::path::{PathBuf};
use void::Void;
use sys::stat::Mode;
@@ -511,6 +511,48 @@ pub fn sleep(seconds: libc::c_uint) -> c_uint {
unsafe { libc::sleep(seconds) }
}
+/// Creates a regular file which persists even after process termination
+///
+/// * `template`: a path whose 6 rightmost characters must be X, e.g. /tmp/tmpfile_XXXXXX
+/// * returns: tuple of file descriptor and filename
+///
+/// Err is returned either if no temporary filename could be created or the template doesn't
+/// end with XXXXXX
+///
+/// # Example
+///
+/// ```rust
+/// use nix::unistd;
+///
+/// let fd = match unistd::mkstemp("/tmp/tempfile_XXXXXX") {
+/// Ok((fd, path)) => {
+/// unistd::unlink(path.as_path()).unwrap(); // flag file to be deleted at app termination
+/// fd
+/// }
+/// Err(e) => panic!("mkstemp failed: {}", e)
+/// };
+/// // do something with fd
+/// ```
+#[inline]
+pub fn mkstemp<P: ?Sized + NixPath>(template: &P) -> Result<(RawFd, PathBuf)> {
+ let res = template.with_nix_path(|path| {
+ let mut path_copy = path.to_bytes_with_nul().to_owned();
+ let p: *mut i8 = path_copy.as_mut_ptr() as *mut i8;
+ unsafe {
+ (libc::mkstemp(p), OsStr::from_bytes(CStr::from_ptr(p).to_bytes()))
+ }
+ });
+ match res {
+ Ok((fd, pathname)) => {
+ try!(Errno::result(fd));
+ Ok((fd, PathBuf::from(pathname).to_owned()))
+ }
+ Err(e) => {
+ Err(e)
+ }
+ }
+}
+
#[cfg(any(target_os = "linux", target_os = "android"))]
mod linux {
use sys::syscall::{syscall, SYSPIVOTROOT};