]> git.proxmox.com Git - rustc.git/blame - library/std/src/sys/vxworks/fd.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / library / std / src / sys / vxworks / fd.rs
CommitLineData
dfeec247 1#![unstable(reason = "not public", issue = "none", feature = "fd")]
416331ca
XL
2
3use crate::cmp;
60c5eb7d 4use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
416331ca
XL
5use crate::mem;
6use crate::sys::cvt;
7use crate::sys_common::AsInner;
8
9use libc::{self, c_int, c_void, ssize_t};
10
11#[derive(Debug)]
12pub struct FileDesc {
13 fd: c_int,
14}
15
3dfed10e
XL
16// The maximum read limit on most POSIX-like systems is `SSIZE_MAX`,
17// with the man page quoting that if the count of bytes to read is
18// greater than `SSIZE_MAX` the result is "unspecified".
19const READ_LIMIT: usize = ssize_t::MAX as usize;
416331ca
XL
20
21impl FileDesc {
22 pub fn new(fd: c_int) -> FileDesc {
23 FileDesc { fd: fd }
24 }
25
60c5eb7d
XL
26 pub fn raw(&self) -> c_int {
27 self.fd
28 }
416331ca 29
3dfed10e 30 /// Extracts the actual file descriptor without closing it.
416331ca
XL
31 pub fn into_raw(self) -> c_int {
32 let fd = self.fd;
33 mem::forget(self);
34 fd
35 }
36
37 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
38 let ret = cvt(unsafe {
3dfed10e 39 libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), READ_LIMIT))
416331ca
XL
40 })?;
41 Ok(ret as usize)
42 }
43
44 pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
45 let ret = cvt(unsafe {
60c5eb7d
XL
46 libc::readv(
47 self.fd,
48 bufs.as_ptr() as *const libc::iovec,
f035d41b 49 cmp::min(bufs.len(), c_int::MAX as usize) as c_int,
60c5eb7d 50 )
416331ca
XL
51 })?;
52 Ok(ret as usize)
53 }
54
f9f354fc 55 #[inline]
1b1a35ee 56 pub fn is_read_vectored(&self) -> bool {
f9f354fc
XL
57 true
58 }
59
416331ca
XL
60 pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
61 let mut me = self;
62 (&mut me).read_to_end(buf)
63 }
64
65 pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
60c5eb7d
XL
66 unsafe fn cvt_pread(
67 fd: c_int,
68 buf: *mut c_void,
69 count: usize,
70 offset: i64,
71 ) -> io::Result<isize> {
416331ca
XL
72 use libc::pread;
73 cvt(pread(fd, buf, count, offset))
74 }
75
76 unsafe {
60c5eb7d
XL
77 cvt_pread(
78 self.fd,
416331ca 79 buf.as_mut_ptr() as *mut c_void,
3dfed10e 80 cmp::min(buf.len(), READ_LIMIT),
60c5eb7d
XL
81 offset as i64,
82 )
416331ca
XL
83 .map(|n| n as usize)
84 }
85 }
86
87 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
88 let ret = cvt(unsafe {
3dfed10e 89 libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), READ_LIMIT))
416331ca
XL
90 })?;
91 Ok(ret as usize)
92 }
93
94 pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
95 let ret = cvt(unsafe {
60c5eb7d
XL
96 libc::writev(
97 self.fd,
98 bufs.as_ptr() as *const libc::iovec,
f035d41b 99 cmp::min(bufs.len(), c_int::MAX as usize) as c_int,
60c5eb7d 100 )
416331ca
XL
101 })?;
102 Ok(ret as usize)
103 }
104
f9f354fc
XL
105 #[inline]
106 pub fn is_write_vectored(&self) -> bool {
107 true
108 }
109
416331ca 110 pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
60c5eb7d
XL
111 unsafe fn cvt_pwrite(
112 fd: c_int,
113 buf: *const c_void,
114 count: usize,
115 offset: i64,
116 ) -> io::Result<isize> {
416331ca
XL
117 use libc::pwrite;
118 cvt(pwrite(fd, buf, count, offset))
119 }
120
121 unsafe {
60c5eb7d
XL
122 cvt_pwrite(
123 self.fd,
416331ca 124 buf.as_ptr() as *const c_void,
3dfed10e 125 cmp::min(buf.len(), READ_LIMIT),
60c5eb7d
XL
126 offset as i64,
127 )
128 .map(|n| n as usize)
416331ca
XL
129 }
130 }
131
132 pub fn get_cloexec(&self) -> io::Result<bool> {
60c5eb7d 133 unsafe { Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) }
416331ca
XL
134 }
135
136 pub fn set_cloexec(&self) -> io::Result<()> {
137 unsafe {
138 let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?;
139 let new = previous | libc::FD_CLOEXEC;
140 if new != previous {
141 cvt(libc::fcntl(self.fd, libc::F_SETFD, new))?;
142 }
143 Ok(())
144 }
145 }
146
147 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
148 unsafe {
149 let v = nonblocking as c_int;
150 cvt(libc::ioctl(self.fd, libc::FIONBIO, &v))?;
151 Ok(())
152 }
153 }
154
155 // refer to pxPipeDrv library documentation.
156 // VxWorks uses fcntl to set O_NONBLOCK to the pipes
157 pub fn set_nonblocking_pipe(&self, nonblocking: bool) -> io::Result<()> {
158 unsafe {
159 let mut flags = cvt(libc::fcntl(self.fd, libc::F_GETFL, 0))?;
60c5eb7d 160 flags = if nonblocking { flags | libc::O_NONBLOCK } else { flags & !libc::O_NONBLOCK };
416331ca
XL
161 cvt(libc::fcntl(self.fd, libc::F_SETFL, flags))?;
162 Ok(())
163 }
164 }
165
416331ca
XL
166 pub fn duplicate(&self) -> io::Result<FileDesc> {
167 let fd = self.raw();
168 match cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, 0) }) {
60c5eb7d 169 Ok(newfd) => Ok(FileDesc::new(newfd)),
416331ca
XL
170 Err(e) => return Err(e),
171 }
172 }
173}
174
175impl<'a> Read for &'a FileDesc {
176 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
177 (**self).read(buf)
178 }
179
180 #[inline]
181 unsafe fn initializer(&self) -> Initializer {
182 Initializer::nop()
183 }
184}
185
186impl AsInner<c_int> for FileDesc {
60c5eb7d
XL
187 fn as_inner(&self) -> &c_int {
188 &self.fd
189 }
416331ca
XL
190}
191
192impl Drop for FileDesc {
193 fn drop(&mut self) {
194 // Note that errors are ignored when closing a file descriptor. The
195 // reason for this is that if an error occurs we don't actually know if
196 // the file descriptor was closed or not, and if we retried (for
197 // something like EINTR), we might close another valid file descriptor
198 // (opened after we closed ours.
199 let _ = unsafe { libc::close(self.fd) };
200 }
201}