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.
14 use libc
::consts
::os
::extra
::INVALID_SOCKET
;
15 use libc
::{self, c_int, c_void}
;
24 use sys_common
::{AsInner, FromInner, IntoInner}
;
25 use sys_common
::net
::{setsockopt, getsockopt}
;
28 pub type wrlen_t
= i32;
30 pub struct Socket(libc
::SOCKET
);
32 /// Checks whether the Windows socket interface has been started already, and
33 /// if not, starts it.
35 static START
: Once
= Once
::new();
37 START
.call_once(|| unsafe {
38 let mut data
: c
::WSADATA
= mem
::zeroed();
39 let ret
= c
::WSAStartup(0x202, // version 2.2
43 let _
= rt
::at_exit(|| { c::WSACleanup(); }
);
47 /// Returns the last error from the Windows socket interface.
48 fn last_error() -> io
::Error
{
49 io
::Error
::from_raw_os_error(unsafe { c::WSAGetLastError() }
)
52 /// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
53 /// and if so, returns the last error from the Windows socket interface. . This
54 /// function must be called before another call to the socket API is made.
55 pub fn cvt
<T
: One
+ Neg
<Output
=T
> + PartialEq
>(t
: T
) -> io
::Result
<T
> {
56 let one
: T
= T
::one();
64 /// Provides the functionality of `cvt` for the return values of `getaddrinfo`
65 /// and similar, meaning that they return an error if the return value is 0.
66 pub fn cvt_gai(err
: c_int
) -> io
::Result
<()> {
67 if err
== 0 { return Ok(()) }
71 /// Provides the functionality of `cvt` for a closure.
73 pub fn cvt_r
<T
, F
>(mut f
: F
) -> io
::Result
<T
>
74 where F
: FnMut() -> T
, T
: One
+ Neg
<Output
=T
> + PartialEq
80 pub fn new(addr
: &SocketAddr
, ty
: c_int
) -> io
::Result
<Socket
> {
81 let fam
= match *addr
{
82 SocketAddr
::V4(..) => libc
::AF_INET
,
83 SocketAddr
::V6(..) => libc
::AF_INET6
,
85 let socket
= try
!(unsafe {
86 match c
::WSASocketW(fam
, ty
, 0, 0 as *mut _
, 0,
87 c
::WSA_FLAG_OVERLAPPED
) {
88 INVALID_SOCKET
=> Err(last_error()),
92 try
!(socket
.set_no_inherit());
96 pub fn accept(&self, storage
: *mut libc
::sockaddr
,
97 len
: *mut libc
::socklen_t
) -> io
::Result
<Socket
> {
98 let socket
= try
!(unsafe {
99 match libc
::accept(self.0, storage
, len
) {
100 INVALID_SOCKET
=> Err(last_error()),
104 try
!(socket
.set_no_inherit());
108 pub fn duplicate(&self) -> io
::Result
<Socket
> {
109 let socket
= try
!(unsafe {
110 let mut info
: c
::WSAPROTOCOL_INFO
= mem
::zeroed();
111 try
!(cvt(c
::WSADuplicateSocketW(self.0,
112 c
::GetCurrentProcessId(),
114 match c
::WSASocketW(info
.iAddressFamily
,
118 c
::WSA_FLAG_OVERLAPPED
) {
119 INVALID_SOCKET
=> Err(last_error()),
123 try
!(socket
.set_no_inherit());
127 pub fn read(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
128 // On unix when a socket is shut down all further reads return 0, so we
129 // do the same on windows to map a shut down socket to returning EOF.
131 match libc
::recv(self.0, buf
.as_mut_ptr() as *mut c_void
,
132 buf
.len() as i32, 0) {
133 -1 if c
::WSAGetLastError() == c
::WSAESHUTDOWN
=> Ok(0),
134 -1 => Err(last_error()),
140 pub fn set_timeout(&self, dur
: Option
<Duration
>, kind
: libc
::c_int
) -> io
::Result
<()> {
141 let timeout
= match dur
{
143 let timeout
= sys
::dur2timeout(dur
);
145 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
146 "cannot set a 0 duration timeout"));
152 setsockopt(self, libc
::SOL_SOCKET
, kind
, timeout
)
155 pub fn timeout(&self, kind
: libc
::c_int
) -> io
::Result
<Option
<Duration
>> {
156 let raw
: libc
::DWORD
= try
!(getsockopt(self, libc
::SOL_SOCKET
, kind
));
160 let secs
= raw
/ 1000;
161 let nsec
= (raw
% 1000) * 1000000;
162 Ok(Some(Duration
::new(secs
as u64, nsec
as u32)))
166 fn set_no_inherit(&self) -> io
::Result
<()> {
168 c
::SetHandleInformation(self.0 as libc
::HANDLE
,
169 c
::HANDLE_FLAG_INHERIT
, 0)
174 impl Drop
for Socket
{
176 let _
= unsafe { libc::closesocket(self.0) }
;
180 impl AsInner
<libc
::SOCKET
> for Socket
{
181 fn as_inner(&self) -> &libc
::SOCKET { &self.0 }
184 impl FromInner
<libc
::SOCKET
> for Socket
{
185 fn from_inner(sock
: libc
::SOCKET
) -> Socket { Socket(sock) }
188 impl IntoInner
<libc
::SOCKET
> for Socket
{
189 fn into_inner(self) -> libc
::SOCKET
{