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.
13 use libc
::{c_int, c_void}
;
15 use net
::{SocketAddr, Shutdown}
;
22 use sys_common
::{self, AsInner, FromInner, IntoInner}
;
26 pub type wrlen_t
= i32;
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
;
36 pub struct Socket(c
::SOCKET
);
38 /// Checks whether the Windows socket interface has been started already, and
39 /// if not, starts it.
41 static START
: Once
= Once
::new();
43 START
.call_once(|| unsafe {
44 let mut data
: c
::WSADATA
= mem
::zeroed();
45 let ret
= c
::WSAStartup(0x202, // version 2.2
49 let _
= sys_common
::at_exit(|| { c::WSACleanup(); }
);
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() }
)
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();
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(()) }
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
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
,
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()),
97 try
!(socket
.set_no_inherit());
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()),
109 try
!(socket
.set_no_inherit());
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(),
119 match c
::WSASocketW(info
.iAddressFamily
,
123 c
::WSA_FLAG_OVERLAPPED
) {
124 c
::INVALID_SOCKET
=> Err(last_error()),
128 try
!(socket
.set_no_inherit());
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;
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()),
145 pub fn set_timeout(&self, dur
: Option
<Duration
>,
146 kind
: c_int
) -> io
::Result
<()> {
147 let timeout
= match dur
{
149 let timeout
= sys
::dur2timeout(dur
);
151 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
152 "cannot set a 0 duration timeout"));
158 net
::setsockopt(self, c
::SOL_SOCKET
, kind
, timeout
)
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
));
166 let secs
= raw
/ 1000;
167 let nsec
= (raw
% 1000) * 1000000;
168 Ok(Some(Duration
::new(secs
as u64, nsec
as u32)))
172 fn set_no_inherit(&self) -> io
::Result
<()> {
174 c
::SetHandleInformation(self.0 as c
::HANDLE
,
175 c
::HANDLE_FLAG_INHERIT
, 0)
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
,
185 try
!(cvt(unsafe { c::shutdown(self.0, how) }
));
190 impl Drop
for Socket
{
192 let _
= unsafe { c::closesocket(self.0) }
;
196 impl AsInner
<c
::SOCKET
> for Socket
{
197 fn as_inner(&self) -> &c
::SOCKET { &self.0 }
200 impl FromInner
<c
::SOCKET
> for Socket
{
201 fn from_inner(sock
: c
::SOCKET
) -> Socket { Socket(sock) }
204 impl IntoInner
<c
::SOCKET
> for Socket
{
205 fn into_inner(self) -> c
::SOCKET
{