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..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,6 +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) -> int; } pub trait RtioProcess { @@ -326,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 { @@ -343,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/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. 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 {