1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 #![unstable(reason = "not public", issue = "0", feature = "fd")]
15 use sys
::{cvt, syscall}
;
16 use sys_common
::AsInner
;
17 use sys_common
::io
::read_to_end_uninitialized
;
24 pub fn new(fd
: usize) -> FileDesc
{
28 pub fn raw(&self) -> usize { self.fd }
30 /// Extracts the actual filedescriptor without closing it.
31 pub fn into_raw(self) -> usize {
37 pub fn read(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
38 cvt(syscall
::read(self.fd
, buf
))
41 pub fn read_to_end(&self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
43 (&mut me
).read_to_end(buf
)
46 pub fn write(&self, buf
: &[u8]) -> io
::Result
<usize> {
47 cvt(syscall
::write(self.fd
, buf
))
50 pub fn duplicate(&self) -> io
::Result
<FileDesc
> {
51 let new_fd
= cvt(syscall
::dup(self.fd
, &[]))?
;
52 Ok(FileDesc
::new(new_fd
))
55 pub fn nonblocking(&self) -> io
::Result
<bool
> {
56 let flags
= cvt(syscall
::fcntl(self.fd
, syscall
::F_GETFL
, 0))?
;
57 Ok(flags
& syscall
::O_NONBLOCK
== syscall
::O_NONBLOCK
)
60 pub fn set_cloexec(&self) -> io
::Result
<()> {
61 let mut flags
= cvt(syscall
::fcntl(self.fd
, syscall
::F_GETFL
, 0))?
;
62 flags
|= syscall
::O_CLOEXEC
;
63 cvt(syscall
::fcntl(self.fd
, syscall
::F_SETFL
, flags
)).and(Ok(()))
66 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
67 let mut flags
= cvt(syscall
::fcntl(self.fd
, syscall
::F_GETFL
, 0))?
;
69 flags
|= syscall
::O_NONBLOCK
;
71 flags
&= !syscall
::O_NONBLOCK
;
73 cvt(syscall
::fcntl(self.fd
, syscall
::F_SETFL
, flags
)).and(Ok(()))
77 impl<'a
> Read
for &'a FileDesc
{
78 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
82 fn read_to_end(&mut self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
83 unsafe { read_to_end_uninitialized(self, buf) }
87 impl AsInner
<usize> for FileDesc
{
88 fn as_inner(&self) -> &usize { &self.fd }
91 impl Drop
for FileDesc
{
93 // Note that errors are ignored when closing a file descriptor. The
94 // reason for this is that if an error occurs we don't actually know if
95 // the file descriptor was closed or not, and if we retried (for
96 // something like EINTR), we might close another valid file descriptor
97 // (opened after we closed ours.
98 let _
= syscall
::close(self.fd
);