diff options
Diffstat (limited to 'src/unistd.rs')
-rw-r--r-- | src/unistd.rs | 48 |
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}; |