Skip to content

Commit

Permalink
modernize stdlib usage
Browse files Browse the repository at this point in the history
  • Loading branch information
Stebalien committed Feb 11, 2019
1 parent d7fac6b commit 8389b79
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 105 deletions.
69 changes: 19 additions & 50 deletions src/file/imp/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@ use std::ffi::{CString, OsStr};
use std::fs::{self, File, OpenOptions};
use std::io;
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::os::unix::fs::{MetadataExt, OpenOptionsExt};
use std::path::Path;
use util;

#[cfg(target_os = "linux")]
use libc::{fstat64 as fstat, open64 as open, stat64 as stat_t};

#[cfg(target_os = "redox")]
use syscall::{self, fstat, open, Stat as stat_t, O_CLOEXEC, O_CREAT, O_EXCL, O_RDWR};

#[cfg(not(target_os = "redox"))]
use libc::{c_char, c_int, link, rename, unlink, O_CLOEXEC, O_CREAT, O_EXCL, O_RDWR};

#[cfg(not(any(target_os = "linux", target_os = "redox")))]
use libc::{fstat, open, stat as stat_t};
use libc::{c_char, c_int, link, rename, unlink};

#[cfg(not(target_os = "redox"))]
#[inline(always)]
Expand All @@ -41,28 +32,13 @@ pub fn cstr(path: &Path) -> io::Result<CString> {
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "path contained a null"))
}

#[cfg(not(target_os = "redox"))]
pub fn create_named(path: &Path) -> io::Result<File> {
unsafe {
let path = cstr(path)?;
let fd = cvt_err(open(
path.as_ptr() as *const c_char,
O_CLOEXEC | O_EXCL | O_RDWR | O_CREAT,
0o600,
))?;
Ok(FromRawFd::from_raw_fd(fd))
}
}

#[cfg(target_os = "redox")]
pub fn create_named(path: &Path) -> io::Result<File> {
unsafe {
let fd = cvt_err(open(
path.as_os_str().as_bytes(),
O_CLOEXEC | O_EXCL | O_RDWR | O_CREAT | 0o600,
))?;
Ok(FromRawFd::from_raw_fd(fd))
}
OpenOptions::new()
.read(true)
.write(true)
.create_new(true)
.mode(0o600)
.open(path)
}

fn create_unlinked(path: &Path) -> io::Result<File> {
Expand All @@ -84,10 +60,11 @@ fn create_unlinked(path: &Path) -> io::Result<File> {

#[cfg(target_os = "linux")]
pub fn create(dir: &Path) -> io::Result<File> {
use libc::O_TMPFILE;
use libc::{open64, O_CLOEXEC, O_EXCL, O_RDWR, O_TMPFILE};
use std::os::unix::io::FromRawFd;
match unsafe {
let path = cstr(dir)?;
open(
open64(
path.as_ptr() as *const c_char,
O_CLOEXEC | O_EXCL | O_TMPFILE | O_RDWR,
0o600,
Expand All @@ -113,25 +90,17 @@ fn create_unix(dir: &Path) -> io::Result<File> {
)
}

unsafe fn stat(fd: RawFd) -> io::Result<stat_t> {
let mut meta: stat_t = ::std::mem::zeroed();
cvt_err(fstat(fd, &mut meta))?;
Ok(meta)
}

pub fn reopen(file: &File, path: &Path) -> io::Result<File> {
let new_file = OpenOptions::new().read(true).write(true).open(path)?;
unsafe {
let old_meta = stat(file.as_raw_fd())?;
let new_meta = stat(new_file.as_raw_fd())?;
if old_meta.st_dev != new_meta.st_dev || old_meta.st_ino != new_meta.st_ino {
return Err(io::Error::new(
io::ErrorKind::NotFound,
"original tempfile has been replaced",
));
}
Ok(new_file)
let old_meta = file.metadata()?;
let new_meta = new_file.metadata()?;
if old_meta.dev() != new_meta.dev() || old_meta.ino() != new_meta.ino() {
return Err(io::Error::new(
io::ErrorKind::NotFound,
"original tempfile has been replaced",
));
}
Ok(new_file)
}

#[cfg(not(target_os = "redox"))]
Expand Down
80 changes: 25 additions & 55 deletions src/file/imp/windows.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use std::ffi::OsStr;
use std::fs::File;
use std::io;
use std::fs::{File, OpenOptions};
use std::os::windows::ffi::OsStrExt;
use std::os::windows::fs::OpenOptionsExt;
use std::os::windows::io::{AsRawHandle, FromRawHandle, RawHandle};
use std::path::Path;
use std::ptr;
use std::{io, iter};

use winapi::shared::minwindef::DWORD;
use winapi::um::fileapi::{CreateFileW, SetFileAttributesW, CREATE_NEW};
use winapi::um::fileapi::SetFileAttributesW;
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
use winapi::um::winbase::{MoveFileExW, ReOpenFile};
use winapi::um::winbase::{FILE_FLAG_DELETE_ON_CLOSE, MOVEFILE_REPLACE_EXISTING};
Expand All @@ -17,51 +16,17 @@ use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE};

use util;

#[cfg_attr(irustfmt, rustfmt_skip)]
const ACCESS: DWORD = FILE_GENERIC_READ
| FILE_GENERIC_WRITE;
#[cfg_attr(irustfmt, rustfmt_skip)]
const SHARE_MODE: DWORD = FILE_SHARE_DELETE
| FILE_SHARE_READ
| FILE_SHARE_WRITE;
#[cfg_attr(irustfmt, rustfmt_skip)]
const FLAGS: DWORD = FILE_ATTRIBUTE_TEMPORARY;

fn to_utf16(s: &Path) -> Vec<u16> {
s.as_os_str()
.encode_wide()
.chain(Some(0).into_iter())
.collect()
}

fn win_create(
path: &Path,
access: DWORD,
share_mode: DWORD,
disp: DWORD,
flags: DWORD,
) -> io::Result<File> {
let path = to_utf16(path);
let handle = unsafe {
CreateFileW(
path.as_ptr(),
access,
share_mode,
0 as *mut _,
disp,
flags,
ptr::null_mut(),
)
};
if handle == INVALID_HANDLE_VALUE {
Err(io::Error::last_os_error())
} else {
Ok(unsafe { File::from_raw_handle(handle as RawHandle) })
}
s.as_os_str().encode_wide().chain(iter::once(0)).collect()
}

pub fn create_named(path: &Path) -> io::Result<File> {
win_create(path, ACCESS, SHARE_MODE, CREATE_NEW, FLAGS)
OpenOptions::new()
.create_new(true)
.read(true)
.write(true)
.custom_flags(FILE_ATTRIBUTE_TEMPORARY)
.open(path)
}

pub fn create(dir: &Path) -> io::Result<File> {
Expand All @@ -71,21 +36,26 @@ pub fn create(dir: &Path) -> io::Result<File> {
OsStr::new(""),
::NUM_RAND_CHARS,
|path| {
win_create(
&path,
ACCESS,
0, // Exclusive
CREATE_NEW,
FLAGS | FILE_FLAG_DELETE_ON_CLOSE,
)
OpenOptions::new()
.create_new(true)
.read(true)
.write(true)
.share_mode(0)
.custom_flags(FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE)
.open(path)
},
)
}

pub fn reopen(file: &File, _path: &Path) -> io::Result<File> {
let handle = file.as_raw_handle();
unsafe {
let handle = ReOpenFile(handle as HANDLE, ACCESS, SHARE_MODE, 0);
let handle = ReOpenFile(
handle as HANDLE,
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
);
if handle == INVALID_HANDLE_VALUE {
Err(io::Error::last_os_error())
} else {
Expand Down Expand Up @@ -118,7 +88,7 @@ pub fn persist(old_path: &Path, new_path: &Path, overwrite: bool) -> io::Result<
let e = io::Error::last_os_error();
// If this fails, the temporary file is now un-hidden and no longer marked temporary
// (slightly less efficient) but it will still work.
let _ = SetFileAttributesW(old_path_w.as_ptr(), FLAGS);
let _ = SetFileAttributesW(old_path_w.as_ptr(), FILE_ATTRIBUTE_TEMPORARY);
Err(e)
} else {
Ok(())
Expand Down

0 comments on commit 8389b79

Please sign in to comment.