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 12 use std::io; 13 use std::mem; 14 use std::net::{TcpListener, TcpStream, UdpSocket}; 15 use std::os::unix::io::FromRawFd; 16 use libc::{self, c_int}; 17 18 mod impls; 19 20 pub mod c { 21 pub use libc::*; 22 sockaddr_in_u32(sa: &sockaddr_in) -> u3223 pub fn sockaddr_in_u32(sa: &sockaddr_in) -> u32 { 24 ::ntoh((*sa).sin_addr.s_addr) 25 } 26 in_addr_to_u32(addr: &in_addr) -> u3227 pub fn in_addr_to_u32(addr: &in_addr) -> u32 { 28 ::ntoh(addr.s_addr) 29 } 30 } 31 32 pub struct Socket { 33 fd: c_int, 34 } 35 36 impl Socket { new(family: c_int, ty: c_int) -> io::Result<Socket>37 pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> { 38 unsafe { 39 let fd = ::cvt(libc::socket(family, ty, 0))?; 40 let mut flags = ::cvt(libc::fcntl(fd, libc::F_GETFD))?; 41 flags |= libc::O_CLOEXEC; 42 ::cvt(libc::fcntl(fd, libc::F_SETFD, flags))?; 43 Ok(Socket { fd: fd }) 44 } 45 } 46 raw(&self) -> c_int47 pub fn raw(&self) -> c_int { self.fd } 48 into_fd(self) -> c_int49 fn into_fd(self) -> c_int { 50 let fd = self.fd; 51 mem::forget(self); 52 fd 53 } 54 into_tcp_listener(self) -> TcpListener55 pub fn into_tcp_listener(self) -> TcpListener { 56 unsafe { TcpListener::from_raw_fd(self.into_fd() as usize) } 57 } 58 into_tcp_stream(self) -> TcpStream59 pub fn into_tcp_stream(self) -> TcpStream { 60 unsafe { TcpStream::from_raw_fd(self.into_fd() as usize) } 61 } 62 into_udp_socket(self) -> UdpSocket63 pub fn into_udp_socket(self) -> UdpSocket { 64 unsafe { UdpSocket::from_raw_fd(self.into_fd() as usize) } 65 } 66 } 67 68 impl ::FromInner for Socket { 69 type Inner = usize; from_inner(fd: usize) -> Socket70 fn from_inner(fd: usize) -> Socket { 71 Socket { fd: fd as c_int } 72 } 73 } 74 75 impl Drop for Socket { drop(&mut self)76 fn drop(&mut self) { 77 unsafe { 78 let _ = libc::close(self.fd); 79 } 80 } 81 } 82