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.
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(issue = "0", feature = "windows_net")]
17 use libc
::{c_int, c_void, c_ulong}
;
19 use net
::{SocketAddr, Shutdown}
;
26 use sys_common
::{self, AsInner, FromInner, IntoInner}
;
27 use sys_common
::io
::read_to_end_uninitialized
;
31 pub type wrlen_t
= i32;
35 pub use sys
::c
::SOCKADDR
as sockaddr
;
36 pub use sys
::c
::SOCKADDR_STORAGE_LH
as sockaddr_storage
;
37 pub use sys
::c
::ADDRINFOA
as addrinfo
;
38 pub use sys
::c
::ADDRESS_FAMILY
as sa_family_t
;
41 pub struct Socket(c
::SOCKET
);
43 /// Checks whether the Windows socket interface has been started already, and
44 /// if not, starts it.
46 static START
: Once
= Once
::new();
48 START
.call_once(|| unsafe {
49 let mut data
: c
::WSADATA
= mem
::zeroed();
50 let ret
= c
::WSAStartup(0x202, // version 2.2
54 let _
= sys_common
::at_exit(|| { c::WSACleanup(); }
);
58 /// Returns the last error from the Windows socket interface.
59 fn last_error() -> io
::Error
{
60 io
::Error
::from_raw_os_error(unsafe { c::WSAGetLastError() }
)
63 /// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
64 /// and if so, returns the last error from the Windows socket interface. This
65 /// function must be called before another call to the socket API is made.
66 pub fn cvt
<T
: One
+ PartialEq
+ Neg
<Output
=T
>>(t
: T
) -> io
::Result
<T
> {
74 /// A variant of `cvt` for `getaddrinfo` which return 0 for a success.
75 pub fn cvt_gai(err
: c_int
) -> io
::Result
<()> {
83 /// Just to provide the same interface as sys/unix/net.rs
84 pub fn cvt_r
<T
, F
>(mut f
: F
) -> io
::Result
<T
>
85 where T
: One
+ PartialEq
+ Neg
<Output
=T
>, F
: FnMut() -> T
91 pub fn new(addr
: &SocketAddr
, ty
: c_int
) -> io
::Result
<Socket
> {
92 let fam
= match *addr
{
93 SocketAddr
::V4(..) => c
::AF_INET
,
94 SocketAddr
::V6(..) => c
::AF_INET6
,
97 match c
::WSASocketW(fam
, ty
, 0, ptr
::null_mut(), 0,
98 c
::WSA_FLAG_OVERLAPPED
) {
99 c
::INVALID_SOCKET
=> Err(last_error()),
103 socket
.set_no_inherit()?
;
107 pub fn accept(&self, storage
: *mut c
::SOCKADDR
,
108 len
: *mut c_int
) -> io
::Result
<Socket
> {
109 let socket
= unsafe {
110 match c
::accept(self.0, storage
, len
) {
111 c
::INVALID_SOCKET
=> Err(last_error()),
115 socket
.set_no_inherit()?
;
119 pub fn duplicate(&self) -> io
::Result
<Socket
> {
120 let socket
= unsafe {
121 let mut info
: c
::WSAPROTOCOL_INFO
= mem
::zeroed();
122 cvt(c
::WSADuplicateSocketW(self.0,
123 c
::GetCurrentProcessId(),
125 match c
::WSASocketW(info
.iAddressFamily
,
129 c
::WSA_FLAG_OVERLAPPED
) {
130 c
::INVALID_SOCKET
=> Err(last_error()),
134 socket
.set_no_inherit()?
;
138 pub fn read(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
139 // On unix when a socket is shut down all further reads return 0, so we
140 // do the same on windows to map a shut down socket to returning EOF.
141 let len
= cmp
::min(buf
.len(), i32::max_value() as usize) as i32;
143 match c
::recv(self.0, buf
.as_mut_ptr() as *mut c_void
, len
, 0) {
144 -1 if c
::WSAGetLastError() == c
::WSAESHUTDOWN
=> Ok(0),
145 -1 => Err(last_error()),
151 pub fn read_to_end(&self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
153 (&mut me
).read_to_end(buf
)
156 pub fn set_timeout(&self, dur
: Option
<Duration
>,
157 kind
: c_int
) -> io
::Result
<()> {
158 let timeout
= match dur
{
160 let timeout
= sys
::dur2timeout(dur
);
162 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
163 "cannot set a 0 duration timeout"));
169 net
::setsockopt(self, c
::SOL_SOCKET
, kind
, timeout
)
172 pub fn timeout(&self, kind
: c_int
) -> io
::Result
<Option
<Duration
>> {
173 let raw
: c
::DWORD
= net
::getsockopt(self, c
::SOL_SOCKET
, kind
)?
;
177 let secs
= raw
/ 1000;
178 let nsec
= (raw
% 1000) * 1000000;
179 Ok(Some(Duration
::new(secs
as u64, nsec
as u32)))
183 fn set_no_inherit(&self) -> io
::Result
<()> {
185 c
::SetHandleInformation(self.0 as c
::HANDLE
,
186 c
::HANDLE_FLAG_INHERIT
, 0)
190 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
191 let how
= match how
{
192 Shutdown
::Write
=> c
::SD_SEND
,
193 Shutdown
::Read
=> c
::SD_RECEIVE
,
194 Shutdown
::Both
=> c
::SD_BOTH
,
196 cvt(unsafe { c::shutdown(self.0, how) }
)?
;
200 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
201 let mut nonblocking
= nonblocking
as c_ulong
;
202 let r
= unsafe { c::ioctlsocket(self.0, c::FIONBIO as c_int, &mut nonblocking) }
;
206 Err(io
::Error
::last_os_error())
210 pub fn set_nodelay(&self, nodelay
: bool
) -> io
::Result
<()> {
211 net
::setsockopt(self, c
::IPPROTO_TCP
, c
::TCP_NODELAY
, nodelay
as c
::BYTE
)
214 pub fn nodelay(&self) -> io
::Result
<bool
> {
215 let raw
: c
::BYTE
= net
::getsockopt(self, c
::IPPROTO_TCP
, c
::TCP_NODELAY
)?
;
219 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
220 let raw
: c_int
= net
::getsockopt(self, c
::SOL_SOCKET
, c
::SO_ERROR
)?
;
224 Ok(Some(io
::Error
::from_raw_os_error(raw
as i32)))
229 #[unstable(reason = "not public", issue = "0", feature = "fd_read")]
230 impl<'a
> Read
for &'a Socket
{
231 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
235 fn read_to_end(&mut self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
236 unsafe { read_to_end_uninitialized(self, buf) }
240 impl Drop
for Socket
{
242 let _
= unsafe { c::closesocket(self.0) }
;
246 impl AsInner
<c
::SOCKET
> for Socket
{
247 fn as_inner(&self) -> &c
::SOCKET { &self.0 }
250 impl FromInner
<c
::SOCKET
> for Socket
{
251 fn from_inner(sock
: c
::SOCKET
) -> Socket { Socket(sock) }
254 impl IntoInner
<c
::SOCKET
> for Socket
{
255 fn into_inner(self) -> c
::SOCKET
{