Skip to content

Commit cd9010c

Browse files
committed
native: Improve windows file handling
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
1 parent 843c5e6 commit cd9010c

File tree

11 files changed

+1146
-1018
lines changed

11 files changed

+1146
-1018
lines changed

src/libnative/io/file.rs

-995
This file was deleted.

src/libnative/io/file_unix.rs

+573
Large diffs are not rendered by default.

src/libnative/io/file_win32.rs

+516
Large diffs are not rendered by default.

src/libnative/io/mod.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,16 @@ pub use self::process::Process;
4242

4343
// Native I/O implementations
4444
pub mod addrinfo;
45-
pub mod file;
4645
pub mod net;
4746
pub mod process;
4847

48+
#[cfg(unix)]
49+
#[path = "file_unix.rs"]
50+
pub mod file;
51+
#[cfg(windows)]
52+
#[path = "file_win32.rs"]
53+
pub mod file;
54+
4955
#[cfg(target_os = "macos")]
5056
#[cfg(target_os = "freebsd")]
5157
#[cfg(target_os = "android")]
@@ -97,7 +103,7 @@ fn translate_error(errno: i32, detail: bool) -> IoError {
97103
libc::WSAECONNABORTED => (io::ConnectionAborted, "connection aborted"),
98104
libc::WSAEADDRNOTAVAIL => (io::ConnectionRefused, "address not available"),
99105
libc::WSAEADDRINUSE => (io::ConnectionRefused, "address in use"),
100-
libc::ERROR_BROKEN_PIPE => (io::BrokenPipe, "the pipe has ended"),
106+
libc::ERROR_BROKEN_PIPE => (io::EndOfFile, "the pipe has ended"),
101107

102108
x => {
103109
debug!("ignoring {}: {}", x, os::last_os_error());
@@ -185,6 +191,24 @@ fn retry(f: || -> libc::c_int) -> libc::c_int {
185191
}
186192
}
187193

194+
fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
195+
let origamt = data.len();
196+
let mut data = data.as_ptr();
197+
let mut amt = origamt;
198+
while amt > 0 {
199+
let ret = retry(|| f(data, amt) as libc::c_int);
200+
if ret == 0 {
201+
break
202+
} else if ret != -1 {
203+
amt -= ret as uint;
204+
data = unsafe { data.offset(ret as int) };
205+
} else {
206+
return ret as i64;
207+
}
208+
}
209+
return (origamt - amt) as i64;
210+
}
211+
188212
/// Implementation of rt::rtio's IoFactory trait to generate handles to the
189213
/// native I/O functionality.
190214
pub struct IoFactory {

src/libnative/io/net.rs

+7-12
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#[allow(non_camel_case_types)];
12-
1311
use std::cast;
1412
use std::io::net::ip;
1513
use std::io;
@@ -18,8 +16,7 @@ use std::mem;
1816
use std::rt::rtio;
1917
use std::sync::arc::UnsafeArc;
2018

21-
use super::{IoResult, retry};
22-
use super::file::keep_going;
19+
use super::{IoResult, retry, keep_going};
2320

2421
////////////////////////////////////////////////////////////////////////////////
2522
// sockaddr and misc bindings
@@ -323,16 +320,14 @@ impl rtio::RtioTcpStream for TcpStream {
323320
}
324321
}
325322
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
326-
let ret = keep_going(buf, |buf, len| {
327-
unsafe {
328-
libc::send(self.fd(),
329-
buf as *mut libc::c_void,
330-
len as wrlen,
331-
0) as i64
332-
}
323+
let ret = keep_going(buf, |buf, len| unsafe {
324+
libc::send(self.fd(),
325+
buf as *mut libc::c_void,
326+
len as wrlen,
327+
0) as i64
333328
});
334329
if ret < 0 {
335-
Err(last_error())
330+
Err(super::last_error())
336331
} else {
337332
Ok(())
338333
}

src/libnative/io/pipe_unix.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use std::rt::rtio;
1717
use std::sync::arc::UnsafeArc;
1818
use std::intrinsics;
1919

20-
use super::{IoResult, retry};
21-
use super::file::{keep_going, fd_t};
20+
use super::{IoResult, retry, keep_going};
21+
use super::file::fd_t;
2222

2323
fn unix_socket(ty: libc::c_int) -> IoResult<fd_t> {
2424
match unsafe { libc::socket(libc::AF_UNIX, ty, 0) } {

src/libnative/io/timer_helper.rs

-3
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
//! can be created in the future and there must be no active timers at that
2121
//! time.
2222
23-
#[allow(non_camel_case_types)];
24-
2523
use std::cast;
2624
use std::rt;
2725
use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
@@ -100,7 +98,6 @@ mod imp {
10098

10199
use io::file::FileDesc;
102100

103-
#[allow(non_camel_case_types)]
104101
pub type signal = libc::c_int;
105102

106103
pub fn new() -> (signal, signal) {

src/libnative/io/timer_other.rs

-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@
4646
//!
4747
//! Note that all time units in this file are in *milliseconds*.
4848
49-
#[allow(non_camel_case_types)];
50-
5149
use std::comm::Data;
5250
use std::libc;
5351
use std::mem;

src/libnative/io/timer_timerfd.rs

-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
//!
2929
//! As with timer_other, all units in this file are in units of millseconds.
3030
31-
#[allow(non_camel_case_types)];
32-
3331
use std::comm::Data;
3432
use std::libc;
3533
use std::ptr;

src/libnative/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
5050
html_root_url = "http://static.rust-lang.org/doc/master")];
5151
#[deny(unused_result, unused_must_use)];
52+
#[allow(non_camel_case_types)];
5253

5354
// NB this crate explicitly does *not* allow glob imports, please seriously
5455
// consider whether they're needed before adding that feature here (the

src/libstd/libc.rs

+21
Original file line numberDiff line numberDiff line change
@@ -1745,6 +1745,10 @@ pub mod consts {
17451745
pub static OPEN_EXISTING: DWORD = 3;
17461746
pub static TRUNCATE_EXISTING: DWORD = 5;
17471747

1748+
pub static FILE_APPEND_DATA: DWORD = 0x00000004;
1749+
pub static FILE_READ_DATA: DWORD = 0x00000001;
1750+
pub static FILE_WRITE_DATA: DWORD = 0x00000002;
1751+
17481752
pub static FILE_ATTRIBUTE_ARCHIVE: DWORD = 0x20;
17491753
pub static FILE_ATTRIBUTE_COMPRESSED: DWORD = 0x800;
17501754
pub static FILE_ATTRIBUTE_DEVICE: DWORD = 0x40;
@@ -1791,6 +1795,18 @@ pub mod consts {
17911795
pub static FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100;
17921796
pub static FILE_READ_ATTRIBUTES: DWORD = 0x00000080;
17931797

1798+
pub static STANDARD_RIGHTS_READ: DWORD = 0x20000;
1799+
pub static STANDARD_RIGHTS_WRITE: DWORD = 0x20000;
1800+
pub static FILE_WRITE_EA: DWORD = 0x00000010;
1801+
pub static FILE_READ_EA: DWORD = 0x00000008;
1802+
pub static FILE_GENERIC_READ: DWORD =
1803+
STANDARD_RIGHTS_READ | FILE_READ_DATA |
1804+
FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE;
1805+
pub static FILE_GENERIC_WRITE: DWORD =
1806+
STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA |
1807+
FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA |
1808+
SYNCHRONIZE;
1809+
17941810
pub static FILE_BEGIN: DWORD = 0;
17951811
pub static FILE_CURRENT: DWORD = 1;
17961812
pub static FILE_END: DWORD = 2;
@@ -4231,6 +4247,7 @@ pub mod funcs {
42314247

42324248
pub mod msvcrt {
42334249
use libc::types::os::arch::c95::{c_int, c_long};
4250+
use libc::types::os::arch::c99::intptr_t;
42344251

42354252
#[nolink]
42364253
extern {
@@ -4239,6 +4256,10 @@ pub mod funcs {
42394256

42404257
#[link_name = "_get_osfhandle"]
42414258
pub fn get_osfhandle(fd: c_int) -> c_long;
4259+
4260+
#[link_name = "_open_osfhandle"]
4261+
pub fn open_osfhandle(osfhandle: intptr_t,
4262+
flags: c_int) -> c_int;
42424263
}
42434264
}
42444265
}

0 commit comments

Comments
 (0)