]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/unix/mod.rs
Fallout of std::old_io deprecation
[rust.git] / src / libstd / sys / unix / mod.rs
1 // Copyright 2014 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.
4 //
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.
10
11 #![allow(missing_docs)]
12 #![allow(non_camel_case_types)]
13
14 use prelude::v1::*;
15
16 use ffi::CStr;
17 use io::{self, ErrorKind};
18 use libc;
19 use num::{Int, SignedInt};
20 use old_io::{self, IoError};
21 use str;
22 use sys_common::mkerr_libc;
23
24 pub mod backtrace;
25 pub mod c;
26 pub mod condvar;
27 pub mod ext;
28 pub mod fd;
29 pub mod fs;  // support for std::old_io
30 pub mod fs2; // support for std::fs
31 pub mod helper_signal;
32 pub mod mutex;
33 pub mod net;
34 pub mod os;
35 pub mod os_str;
36 pub mod pipe;
37 pub mod pipe2;
38 pub mod process;
39 pub mod process2;
40 pub mod rwlock;
41 pub mod stack_overflow;
42 pub mod sync;
43 pub mod tcp;
44 pub mod thread;
45 pub mod thread_local;
46 pub mod time;
47 pub mod timer;
48 pub mod tty;
49 pub mod udp;
50 pub mod stdio;
51
52 pub mod addrinfo {
53     pub use sys_common::net::get_host_addresses;
54     pub use sys_common::net::get_address_name;
55 }
56
57 // FIXME: move these to c module
58 pub type sock_t = self::fs::fd_t;
59 pub type wrlen = libc::size_t;
60 pub type msglen_t = libc::size_t;
61 pub unsafe fn close_sock(sock: sock_t) { let _ = libc::close(sock); }
62
63 #[allow(deprecated)]
64 pub fn last_error() -> IoError {
65     decode_error_detailed(os::errno() as i32)
66 }
67
68 #[allow(deprecated)]
69 pub fn last_net_error() -> IoError {
70     last_error()
71 }
72
73 extern "system" {
74     fn gai_strerror(errcode: libc::c_int) -> *const libc::c_char;
75 }
76
77 #[allow(deprecated)]
78 pub fn last_gai_error(s: libc::c_int) -> IoError {
79
80     let mut err = decode_error(s);
81     err.detail = Some(unsafe {
82         let data = CStr::from_ptr(gai_strerror(s));
83         str::from_utf8(data.to_bytes()).unwrap().to_string()
84     });
85     err
86 }
87
88 /// Convert an `errno` value into a high-level error variant and description.
89 #[allow(deprecated)]
90 pub fn decode_error(errno: i32) -> IoError {
91     // FIXME: this should probably be a bit more descriptive...
92     let (kind, desc) = match errno {
93         libc::EOF => (old_io::EndOfFile, "end of file"),
94         libc::ECONNREFUSED => (old_io::ConnectionRefused, "connection refused"),
95         libc::ECONNRESET => (old_io::ConnectionReset, "connection reset"),
96         libc::EPERM | libc::EACCES =>
97             (old_io::PermissionDenied, "permission denied"),
98         libc::EPIPE => (old_io::BrokenPipe, "broken pipe"),
99         libc::ENOTCONN => (old_io::NotConnected, "not connected"),
100         libc::ECONNABORTED => (old_io::ConnectionAborted, "connection aborted"),
101         libc::EADDRNOTAVAIL => (old_io::ConnectionRefused, "address not available"),
102         libc::EADDRINUSE => (old_io::ConnectionRefused, "address in use"),
103         libc::ENOENT => (old_io::FileNotFound, "no such file or directory"),
104         libc::EISDIR => (old_io::InvalidInput, "illegal operation on a directory"),
105         libc::ENOSYS => (old_io::IoUnavailable, "function not implemented"),
106         libc::EINVAL => (old_io::InvalidInput, "invalid argument"),
107         libc::ENOTTY =>
108             (old_io::MismatchedFileTypeForOperation,
109              "file descriptor is not a TTY"),
110         libc::ETIMEDOUT => (old_io::TimedOut, "operation timed out"),
111         libc::ECANCELED => (old_io::TimedOut, "operation aborted"),
112         libc::consts::os::posix88::EEXIST =>
113             (old_io::PathAlreadyExists, "path already exists"),
114
115         // These two constants can have the same value on some systems,
116         // but different values on others, so we can't use a match
117         // clause
118         x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
119             (old_io::ResourceUnavailable, "resource temporarily unavailable"),
120
121         _ => (old_io::OtherIoError, "unknown error")
122     };
123     IoError { kind: kind, desc: desc, detail: None }
124 }
125
126 #[allow(deprecated)]
127 pub fn decode_error_detailed(errno: i32) -> IoError {
128     let mut err = decode_error(errno);
129     err.detail = Some(os::error_string(errno));
130     err
131 }
132
133 #[allow(deprecated)]
134 pub fn decode_error_kind(errno: i32) -> ErrorKind {
135     match errno as libc::c_int {
136         libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
137         libc::ECONNRESET => ErrorKind::ConnectionReset,
138         libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied,
139         libc::EPIPE => ErrorKind::BrokenPipe,
140         libc::ENOTCONN => ErrorKind::NotConnected,
141         libc::ECONNABORTED => ErrorKind::ConnectionAborted,
142         libc::EADDRNOTAVAIL => ErrorKind::ConnectionRefused,
143         libc::EADDRINUSE => ErrorKind::ConnectionRefused,
144         libc::ENOENT => ErrorKind::FileNotFound,
145         libc::EISDIR => ErrorKind::InvalidInput,
146         libc::EINTR => ErrorKind::Interrupted,
147         libc::EINVAL => ErrorKind::InvalidInput,
148         libc::ENOTTY => ErrorKind::MismatchedFileTypeForOperation,
149         libc::ETIMEDOUT => ErrorKind::TimedOut,
150         libc::ECANCELED => ErrorKind::TimedOut,
151         libc::consts::os::posix88::EEXIST => ErrorKind::PathAlreadyExists,
152
153         // These two constants can have the same value on some systems,
154         // but different values on others, so we can't use a match
155         // clause
156         x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
157             ErrorKind::ResourceUnavailable,
158
159         _ => ErrorKind::Other,
160     }
161 }
162
163 #[inline]
164 #[allow(deprecated)]
165 pub fn retry<T, F> (mut f: F) -> T where
166     T: SignedInt,
167     F: FnMut() -> T,
168 {
169     let one: T = Int::one();
170     loop {
171         let n = f();
172         if n == -one && os::errno() == libc::EINTR as i32 { }
173         else { return n }
174     }
175 }
176
177 pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> {
178     let one: T = Int::one();
179     if t == -one {
180         Err(io::Error::last_os_error())
181     } else {
182         Ok(t)
183     }
184 }
185
186 pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
187     where T: SignedInt, F: FnMut() -> T
188 {
189     loop {
190         match cvt(f()) {
191             Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
192             other => return other,
193         }
194     }
195 }
196
197 pub fn ms_to_timeval(ms: u64) -> libc::timeval {
198     libc::timeval {
199         tv_sec: (ms / 1000) as libc::time_t,
200         tv_usec: ((ms % 1000) * 1000) as libc::suseconds_t,
201     }
202 }
203
204 #[allow(deprecated)]
205 pub fn wouldblock() -> bool {
206     let err = os::errno();
207     err == libc::EWOULDBLOCK as i32 || err == libc::EAGAIN as i32
208 }
209
210 #[allow(deprecated)]
211 pub fn set_nonblocking(fd: sock_t, nb: bool) {
212     let set = nb as libc::c_int;
213     mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) })).unwrap();
214 }
215
216 // nothing needed on unix platforms
217 pub fn init_net() {}