2015-02-03 05:39:14 +00:00
|
|
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
use io;
|
|
|
|
use libc::{self, c_int, size_t, c_void};
|
|
|
|
use mem;
|
2015-04-03 22:30:10 +00:00
|
|
|
use sys::c;
|
2015-02-03 05:39:14 +00:00
|
|
|
use sys::cvt;
|
2015-02-06 00:50:11 +00:00
|
|
|
use sys_common::AsInner;
|
2015-02-03 05:39:14 +00:00
|
|
|
|
|
|
|
pub struct FileDesc {
|
|
|
|
fd: c_int,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FileDesc {
|
|
|
|
pub fn new(fd: c_int) -> FileDesc {
|
|
|
|
FileDesc { fd: fd }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn raw(&self) -> c_int { self.fd }
|
|
|
|
|
2015-04-13 14:21:32 +00:00
|
|
|
/// Extracts the actual filedescriptor without closing it.
|
2015-02-03 05:39:14 +00:00
|
|
|
pub fn into_raw(self) -> c_int {
|
|
|
|
let fd = self.fd;
|
2015-05-07 17:49:39 +00:00
|
|
|
mem::forget(self);
|
2015-02-03 05:39:14 +00:00
|
|
|
fd
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
|
|
|
let ret = try!(cvt(unsafe {
|
|
|
|
libc::read(self.fd,
|
|
|
|
buf.as_mut_ptr() as *mut c_void,
|
|
|
|
buf.len() as size_t)
|
|
|
|
}));
|
|
|
|
Ok(ret as usize)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
|
|
|
let ret = try!(cvt(unsafe {
|
|
|
|
libc::write(self.fd,
|
|
|
|
buf.as_ptr() as *const c_void,
|
|
|
|
buf.len() as size_t)
|
|
|
|
}));
|
|
|
|
Ok(ret as usize)
|
|
|
|
}
|
2015-04-03 22:30:10 +00:00
|
|
|
|
|
|
|
pub fn set_cloexec(&self) {
|
|
|
|
unsafe {
|
|
|
|
let ret = c::ioctl(self.fd, c::FIOCLEX);
|
|
|
|
debug_assert_eq!(ret, 0);
|
|
|
|
}
|
|
|
|
}
|
2015-02-03 05:39:14 +00:00
|
|
|
}
|
|
|
|
|
2015-02-06 00:50:11 +00:00
|
|
|
impl AsInner<c_int> for FileDesc {
|
|
|
|
fn as_inner(&self) -> &c_int { &self.fd }
|
|
|
|
}
|
|
|
|
|
2015-02-03 05:39:14 +00:00
|
|
|
impl Drop for FileDesc {
|
|
|
|
fn drop(&mut self) {
|
2015-04-03 22:44:14 +00:00
|
|
|
// Note that errors are ignored when closing a file descriptor. The
|
|
|
|
// reason for this is that if an error occurs we don't actually know if
|
|
|
|
// the file descriptor was closed or not, and if we retried (for
|
|
|
|
// something like EINTR), we might close another valid file descriptor
|
|
|
|
// (opened after we closed ours.
|
|
|
|
let _ = unsafe { libc::close(self.fd) };
|
2015-02-03 05:39:14 +00:00
|
|
|
}
|
|
|
|
}
|