]> git.proxmox.com Git - rustc.git/blob - src/libstd/sys/windows/net.rs
Imported Upstream version 1.8.0+dfsg1
[rustc.git] / src / libstd / sys / windows / net.rs
1 // Copyright 2015 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 use cmp;
12 use io;
13 use libc::{c_int, c_void};
14 use mem;
15 use net::{SocketAddr, Shutdown};
16 use num::One;
17 use ops::Neg;
18 use ptr;
19 use sync::Once;
20 use sys::c;
21 use sys;
22 use sys_common::{self, AsInner, FromInner, IntoInner};
23 use sys_common::net;
24 use time::Duration;
25
26 pub type wrlen_t = i32;
27
28 pub mod netc {
29 pub use sys::c::*;
30 pub use sys::c::SOCKADDR as sockaddr;
31 pub use sys::c::SOCKADDR_STORAGE_LH as sockaddr_storage;
32 pub use sys::c::ADDRINFOA as addrinfo;
33 pub use sys::c::ADDRESS_FAMILY as sa_family_t;
34 }
35
36 pub struct Socket(c::SOCKET);
37
38 /// Checks whether the Windows socket interface has been started already, and
39 /// if not, starts it.
40 pub fn init() {
41 static START: Once = Once::new();
42
43 START.call_once(|| unsafe {
44 let mut data: c::WSADATA = mem::zeroed();
45 let ret = c::WSAStartup(0x202, // version 2.2
46 &mut data);
47 assert_eq!(ret, 0);
48
49 let _ = sys_common::at_exit(|| { c::WSACleanup(); });
50 });
51 }
52
53 /// Returns the last error from the Windows socket interface.
54 fn last_error() -> io::Error {
55 io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
56 }
57
58 /// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
59 /// and if so, returns the last error from the Windows socket interface. . This
60 /// function must be called before another call to the socket API is made.
61 pub fn cvt<T: One + Neg<Output=T> + PartialEq>(t: T) -> io::Result<T> {
62 let one: T = T::one();
63 if t == -one {
64 Err(last_error())
65 } else {
66 Ok(t)
67 }
68 }
69
70 /// Provides the functionality of `cvt` for the return values of `getaddrinfo`
71 /// and similar, meaning that they return an error if the return value is 0.
72 pub fn cvt_gai(err: c_int) -> io::Result<()> {
73 if err == 0 { return Ok(()) }
74 cvt(err).map(|_| ())
75 }
76
77 /// Provides the functionality of `cvt` for a closure.
78 pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
79 where F: FnMut() -> T, T: One + Neg<Output=T> + PartialEq
80 {
81 cvt(f())
82 }
83
84 impl Socket {
85 pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
86 let fam = match *addr {
87 SocketAddr::V4(..) => c::AF_INET,
88 SocketAddr::V6(..) => c::AF_INET6,
89 };
90 let socket = try!(unsafe {
91 match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0,
92 c::WSA_FLAG_OVERLAPPED) {
93 c::INVALID_SOCKET => Err(last_error()),
94 n => Ok(Socket(n)),
95 }
96 });
97 try!(socket.set_no_inherit());
98 Ok(socket)
99 }
100
101 pub fn accept(&self, storage: *mut c::SOCKADDR,
102 len: *mut c_int) -> io::Result<Socket> {
103 let socket = try!(unsafe {
104 match c::accept(self.0, storage, len) {
105 c::INVALID_SOCKET => Err(last_error()),
106 n => Ok(Socket(n)),
107 }
108 });
109 try!(socket.set_no_inherit());
110 Ok(socket)
111 }
112
113 pub fn duplicate(&self) -> io::Result<Socket> {
114 let socket = try!(unsafe {
115 let mut info: c::WSAPROTOCOL_INFO = mem::zeroed();
116 try!(cvt(c::WSADuplicateSocketW(self.0,
117 c::GetCurrentProcessId(),
118 &mut info)));
119 match c::WSASocketW(info.iAddressFamily,
120 info.iSocketType,
121 info.iProtocol,
122 &mut info, 0,
123 c::WSA_FLAG_OVERLAPPED) {
124 c::INVALID_SOCKET => Err(last_error()),
125 n => Ok(Socket(n)),
126 }
127 });
128 try!(socket.set_no_inherit());
129 Ok(socket)
130 }
131
132 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
133 // On unix when a socket is shut down all further reads return 0, so we
134 // do the same on windows to map a shut down socket to returning EOF.
135 let len = cmp::min(buf.len(), i32::max_value() as usize) as i32;
136 unsafe {
137 match c::recv(self.0, buf.as_mut_ptr() as *mut c_void, len, 0) {
138 -1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0),
139 -1 => Err(last_error()),
140 n => Ok(n as usize)
141 }
142 }
143 }
144
145 pub fn set_timeout(&self, dur: Option<Duration>,
146 kind: c_int) -> io::Result<()> {
147 let timeout = match dur {
148 Some(dur) => {
149 let timeout = sys::dur2timeout(dur);
150 if timeout == 0 {
151 return Err(io::Error::new(io::ErrorKind::InvalidInput,
152 "cannot set a 0 duration timeout"));
153 }
154 timeout
155 }
156 None => 0
157 };
158 net::setsockopt(self, c::SOL_SOCKET, kind, timeout)
159 }
160
161 pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
162 let raw: c::DWORD = try!(net::getsockopt(self, c::SOL_SOCKET, kind));
163 if raw == 0 {
164 Ok(None)
165 } else {
166 let secs = raw / 1000;
167 let nsec = (raw % 1000) * 1000000;
168 Ok(Some(Duration::new(secs as u64, nsec as u32)))
169 }
170 }
171
172 fn set_no_inherit(&self) -> io::Result<()> {
173 sys::cvt(unsafe {
174 c::SetHandleInformation(self.0 as c::HANDLE,
175 c::HANDLE_FLAG_INHERIT, 0)
176 }).map(|_| ())
177 }
178
179 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
180 let how = match how {
181 Shutdown::Write => c::SD_SEND,
182 Shutdown::Read => c::SD_RECEIVE,
183 Shutdown::Both => c::SD_BOTH,
184 };
185 try!(cvt(unsafe { c::shutdown(self.0, how) }));
186 Ok(())
187 }
188 }
189
190 impl Drop for Socket {
191 fn drop(&mut self) {
192 let _ = unsafe { c::closesocket(self.0) };
193 }
194 }
195
196 impl AsInner<c::SOCKET> for Socket {
197 fn as_inner(&self) -> &c::SOCKET { &self.0 }
198 }
199
200 impl FromInner<c::SOCKET> for Socket {
201 fn from_inner(sock: c::SOCKET) -> Socket { Socket(sock) }
202 }
203
204 impl IntoInner<c::SOCKET> for Socket {
205 fn into_inner(self) -> c::SOCKET {
206 let ret = self.0;
207 mem::forget(self);
208 ret
209 }
210 }