From 718fae2ff6b082829be2e381ad89295f27a2b4dc Mon Sep 17 00:00:00 2001 From: Ilya Dmitrichenko Date: Sun, 13 Jul 2014 10:19:50 +0100 Subject: [PATCH 1/2] Provide a way of obtaining numeric file descriptors. This is to improve the interoperability with external C libraries. One should be able to leverage most Rust's standard run-time functions for openning and closing files with all the error handling etc, while only making C library calls when it's very neccessary. --- src/libnative/io/file_unix.rs | 4 ++++ src/librustrt/rtio.rs | 1 + src/librustuv/file.rs | 2 ++ src/libstd/io/fs.rs | 11 +++++++++++ 4 files changed, 18 insertions(+) diff --git a/src/libnative/io/file_unix.rs b/src/libnative/io/file_unix.rs index ddcff2be5f340..db4d702bfd027 100644 --- a/src/libnative/io/file_unix.rs +++ b/src/libnative/io/file_unix.rs @@ -159,6 +159,8 @@ impl rtio::RtioFileStream for FileDesc { _ => Err(super::last_error()), } } + + fn get_fd(&self) -> libc::c_int { self.fd() } } impl rtio::RtioPipe for FileDesc { @@ -314,6 +316,8 @@ impl rtio::RtioFileStream for CFile { fn fstat(&mut self) -> IoResult { self.flush().and_then(|()| self.fd.fstat()) } + + fn get_fd(&self) -> libc::c_int { self.fd.get_fd() } } impl Drop for CFile { diff --git a/src/librustrt/rtio.rs b/src/librustrt/rtio.rs index 81a033e4c987e..c97b39ad6d002 100644 --- a/src/librustrt/rtio.rs +++ b/src/librustrt/rtio.rs @@ -307,6 +307,7 @@ pub trait RtioFileStream { fn datasync(&mut self) -> IoResult<()>; fn truncate(&mut self, offset: i64) -> IoResult<()>; fn fstat(&mut self) -> IoResult; + fn get_fd(&self) -> c_int; } pub trait RtioProcess { diff --git a/src/librustuv/file.rs b/src/librustuv/file.rs index f42f42d211160..0ac1b24f55a15 100644 --- a/src/librustuv/file.rs +++ b/src/librustuv/file.rs @@ -458,6 +458,8 @@ impl rtio::RtioFileStream for FileWatcher { let _m = self.fire_homing_missile(); FsRequest::fstat(&self.loop_, self.fd).map_err(uv_error_to_io_error) } + + fn get_fd(&self) -> libc::c_int { self.fd } } #[cfg(test)] diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index d49c56b470440..08e300c559900 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -251,6 +251,17 @@ impl File { err.update_err("couldn't fstat file", |e| format!("{}; path={}", e, self.path.display())) } + + /// Obtain numeric file descriptor that can be passed to a C library call. + /// + /// It is not considered unsafe to obtain this, however calling C library + /// is inherently unsafe. The advantage of this method is that opening + /// a file and handling of error cases with pattern matching is much nicer + /// in Rust, then it is in C. If one is to call `libc::open()`, or other + /// similar function that opens files in POSIX fashion, they would need + /// to reimplement a large chunk of code that copies some of the functions + /// from this and the underlying traits and modules. + pub fn get_fd(&self) -> libc::c_int { self.fd.get_fd() } } /// Unlink a file from the underlying filesystem. From 5f97d6d54e16f31928e303fd2de450e475234550 Mon Sep 17 00:00:00 2001 From: Ilya Dmitrichenko Date: Sat, 19 Jul 2014 23:32:45 +0100 Subject: [PATCH 2/2] [wip] adding get_fd everywhere... --- src/librustrt/rtio.rs | 6 +++++- src/libstd/io/pipe.rs | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustrt/rtio.rs b/src/librustrt/rtio.rs index c97b39ad6d002..b64c00d1d6e03 100644 --- a/src/librustrt/rtio.rs +++ b/src/librustrt/rtio.rs @@ -235,6 +235,7 @@ pub trait IoFactory { -> IoResult>; fn signal(&mut self, signal: int, cb: Box) -> IoResult>; + fn get_fd(&self) -> int; } pub trait RtioTcpListener : RtioSocket { @@ -262,6 +263,7 @@ pub trait RtioTcpStream : RtioSocket { fn set_timeout(&mut self, timeout_ms: Option); fn set_read_timeout(&mut self, timeout_ms: Option); fn set_write_timeout(&mut self, timeout_ms: Option); + fn get_fd(&self) -> int; } pub trait RtioSocket { @@ -307,7 +309,7 @@ pub trait RtioFileStream { fn datasync(&mut self) -> IoResult<()>; fn truncate(&mut self, offset: i64) -> IoResult<()>; fn fstat(&mut self) -> IoResult; - fn get_fd(&self) -> c_int; + fn get_fd(&self) -> int; } pub trait RtioProcess { @@ -327,6 +329,7 @@ pub trait RtioPipe { fn set_timeout(&mut self, timeout_ms: Option); fn set_read_timeout(&mut self, timeout_ms: Option); fn set_write_timeout(&mut self, timeout_ms: Option); + fn get_fd(&self) -> int; } pub trait RtioUnixListener { @@ -344,6 +347,7 @@ pub trait RtioTTY { fn set_raw(&mut self, raw: bool) -> IoResult<()>; fn get_winsize(&mut self) -> IoResult<(int, int)>; fn isatty(&self) -> bool; + fn get_fd(&self) -> int; } pub trait PausableIdleCallback { diff --git a/src/libstd/io/pipe.rs b/src/libstd/io/pipe.rs index c476a99fee9dc..feaeda62252c1 100644 --- a/src/libstd/io/pipe.rs +++ b/src/libstd/io/pipe.rs @@ -97,6 +97,8 @@ impl PipeStream { } } } + + pub fn get_fd(&self) -> int { self.fd as int } } impl Clone for PipeStream {