Skip to content

Commit

Permalink
native: Improve windows file handling
Browse files Browse the repository at this point in the history
This commit splits the file implementation into file_unix and file_win32. The
two implementations have diverged to the point that they share almost 0 code at
this point, so it's easier to maintain as separate files.

The other major change accompanied with this commit is that file::open is no
longer based on libc's open function on windows, but rather windows's CreateFile
function. This fixes dealing with binary files on windows (test added in
previous commit).

This also changes the read/write functions to use ReadFile and WriteFile instead
of libc's read/write.

Closes #12406
  • Loading branch information
alexcrichton committed Feb 27, 2014
1 parent 843c5e6 commit cd9010c
Show file tree
Hide file tree
Showing 11 changed files with 1,146 additions and 1,018 deletions.
995 changes: 0 additions & 995 deletions src/libnative/io/file.rs

This file was deleted.

573 changes: 573 additions & 0 deletions src/libnative/io/file_unix.rs

Large diffs are not rendered by default.

516 changes: 516 additions & 0 deletions src/libnative/io/file_win32.rs

Large diffs are not rendered by default.

28 changes: 26 additions & 2 deletions src/libnative/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,16 @@ pub use self::process::Process;

// Native I/O implementations
pub mod addrinfo;
pub mod file;
pub mod net;
pub mod process;

#[cfg(unix)]
#[path = "file_unix.rs"]
pub mod file;
#[cfg(windows)]
#[path = "file_win32.rs"]
pub mod file;

#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "android")]
Expand Down Expand Up @@ -97,7 +103,7 @@ fn translate_error(errno: i32, detail: bool) -> IoError {
libc::WSAECONNABORTED => (io::ConnectionAborted, "connection aborted"),
libc::WSAEADDRNOTAVAIL => (io::ConnectionRefused, "address not available"),
libc::WSAEADDRINUSE => (io::ConnectionRefused, "address in use"),
libc::ERROR_BROKEN_PIPE => (io::BrokenPipe, "the pipe has ended"),
libc::ERROR_BROKEN_PIPE => (io::EndOfFile, "the pipe has ended"),

x => {
debug!("ignoring {}: {}", x, os::last_os_error());
Expand Down Expand Up @@ -185,6 +191,24 @@ fn retry(f: || -> libc::c_int) -> libc::c_int {
}
}

fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
let origamt = data.len();
let mut data = data.as_ptr();
let mut amt = origamt;
while amt > 0 {
let ret = retry(|| f(data, amt) as libc::c_int);
if ret == 0 {
break
} else if ret != -1 {
amt -= ret as uint;
data = unsafe { data.offset(ret as int) };
} else {
return ret as i64;
}
}
return (origamt - amt) as i64;
}

/// Implementation of rt::rtio's IoFactory trait to generate handles to the
/// native I/O functionality.
pub struct IoFactory {
Expand Down
19 changes: 7 additions & 12 deletions src/libnative/io/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[allow(non_camel_case_types)];

use std::cast;
use std::io::net::ip;
use std::io;
Expand All @@ -18,8 +16,7 @@ use std::mem;
use std::rt::rtio;
use std::sync::arc::UnsafeArc;

use super::{IoResult, retry};
use super::file::keep_going;
use super::{IoResult, retry, keep_going};

////////////////////////////////////////////////////////////////////////////////
// sockaddr and misc bindings
Expand Down Expand Up @@ -323,16 +320,14 @@ impl rtio::RtioTcpStream for TcpStream {
}
}
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
let ret = keep_going(buf, |buf, len| {
unsafe {
libc::send(self.fd(),
buf as *mut libc::c_void,
len as wrlen,
0) as i64
}
let ret = keep_going(buf, |buf, len| unsafe {
libc::send(self.fd(),
buf as *mut libc::c_void,
len as wrlen,
0) as i64
});
if ret < 0 {
Err(last_error())
Err(super::last_error())
} else {
Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions src/libnative/io/pipe_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use std::rt::rtio;
use std::sync::arc::UnsafeArc;
use std::intrinsics;

use super::{IoResult, retry};
use super::file::{keep_going, fd_t};
use super::{IoResult, retry, keep_going};
use super::file::fd_t;

fn unix_socket(ty: libc::c_int) -> IoResult<fd_t> {
match unsafe { libc::socket(libc::AF_UNIX, ty, 0) } {
Expand Down
3 changes: 0 additions & 3 deletions src/libnative/io/timer_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
//! can be created in the future and there must be no active timers at that
//! time.
#[allow(non_camel_case_types)];

use std::cast;
use std::rt;
use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
Expand Down Expand Up @@ -100,7 +98,6 @@ mod imp {

use io::file::FileDesc;

#[allow(non_camel_case_types)]
pub type signal = libc::c_int;

pub fn new() -> (signal, signal) {
Expand Down
2 changes: 0 additions & 2 deletions src/libnative/io/timer_other.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@
//!
//! Note that all time units in this file are in *milliseconds*.
#[allow(non_camel_case_types)];

use std::comm::Data;
use std::libc;
use std::mem;
Expand Down
2 changes: 0 additions & 2 deletions src/libnative/io/timer_timerfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
//!
//! As with timer_other, all units in this file are in units of millseconds.
#[allow(non_camel_case_types)];

use std::comm::Data;
use std::libc;
use std::ptr;
Expand Down
1 change: 1 addition & 0 deletions src/libnative/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://static.rust-lang.org/doc/master")];
#[deny(unused_result, unused_must_use)];
#[allow(non_camel_case_types)];

// NB this crate explicitly does *not* allow glob imports, please seriously
// consider whether they're needed before adding that feature here (the
Expand Down
21 changes: 21 additions & 0 deletions src/libstd/libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1745,6 +1745,10 @@ pub mod consts {
pub static OPEN_EXISTING: DWORD = 3;
pub static TRUNCATE_EXISTING: DWORD = 5;

pub static FILE_APPEND_DATA: DWORD = 0x00000004;
pub static FILE_READ_DATA: DWORD = 0x00000001;
pub static FILE_WRITE_DATA: DWORD = 0x00000002;

pub static FILE_ATTRIBUTE_ARCHIVE: DWORD = 0x20;
pub static FILE_ATTRIBUTE_COMPRESSED: DWORD = 0x800;
pub static FILE_ATTRIBUTE_DEVICE: DWORD = 0x40;
Expand Down Expand Up @@ -1791,6 +1795,18 @@ pub mod consts {
pub static FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100;
pub static FILE_READ_ATTRIBUTES: DWORD = 0x00000080;

pub static STANDARD_RIGHTS_READ: DWORD = 0x20000;
pub static STANDARD_RIGHTS_WRITE: DWORD = 0x20000;
pub static FILE_WRITE_EA: DWORD = 0x00000010;
pub static FILE_READ_EA: DWORD = 0x00000008;
pub static FILE_GENERIC_READ: DWORD =
STANDARD_RIGHTS_READ | FILE_READ_DATA |
FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE;
pub static FILE_GENERIC_WRITE: DWORD =
STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA |
FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA |
SYNCHRONIZE;

pub static FILE_BEGIN: DWORD = 0;
pub static FILE_CURRENT: DWORD = 1;
pub static FILE_END: DWORD = 2;
Expand Down Expand Up @@ -4231,6 +4247,7 @@ pub mod funcs {

pub mod msvcrt {
use libc::types::os::arch::c95::{c_int, c_long};
use libc::types::os::arch::c99::intptr_t;

#[nolink]
extern {
Expand All @@ -4239,6 +4256,10 @@ pub mod funcs {

#[link_name = "_get_osfhandle"]
pub fn get_osfhandle(fd: c_int) -> c_long;

#[link_name = "_open_osfhandle"]
pub fn open_osfhandle(osfhandle: intptr_t,
flags: c_int) -> c_int;
}
}
}
Expand Down

0 comments on commit cd9010c

Please sign in to comment.