@@ -15,7 +15,7 @@ use libc::{
15
15
use std:: io:: { IoSlice , IoSliceMut } ;
16
16
#[ cfg( feature = "net" ) ]
17
17
use std:: net;
18
- use std:: os:: unix:: io:: RawFd ;
18
+ use std:: os:: unix:: io:: { AsFd , AsRawFd , FromRawFd , RawFd , OwnedFd } ;
19
19
use std:: { mem, ptr, slice} ;
20
20
21
21
#[ deny( missing_docs) ]
@@ -669,6 +669,7 @@ pub enum ControlMessageOwned {
669
669
/// # use std::io::{IoSlice, IoSliceMut};
670
670
/// # use std::time::*;
671
671
/// # use std::str::FromStr;
672
+ /// # use std::os::unix::io::AsRawFd;
672
673
/// # fn main() {
673
674
/// // Set up
674
675
/// let message = "Ohayō!".as_bytes();
@@ -677,22 +678,22 @@ pub enum ControlMessageOwned {
677
678
/// SockType::Datagram,
678
679
/// SockFlag::empty(),
679
680
/// None).unwrap();
680
- /// setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
681
+ /// setsockopt(& in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
681
682
/// let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap();
682
- /// bind(in_socket, &localhost).unwrap();
683
- /// let address: SockaddrIn = getsockname(in_socket).unwrap();
683
+ /// bind(in_socket.as_raw_fd() , &localhost).unwrap();
684
+ /// let address: SockaddrIn = getsockname(in_socket.as_raw_fd() ).unwrap();
684
685
/// // Get initial time
685
686
/// let time0 = SystemTime::now();
686
687
/// // Send the message
687
688
/// let iov = [IoSlice::new(message)];
688
689
/// let flags = MsgFlags::empty();
689
- /// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
690
+ /// let l = sendmsg(in_socket.as_raw_fd() , &iov, &[], flags, Some(&address)).unwrap();
690
691
/// assert_eq!(message.len(), l);
691
692
/// // Receive the message
692
693
/// let mut buffer = vec![0u8; message.len()];
693
694
/// let mut cmsgspace = cmsg_space!(TimeVal);
694
695
/// let mut iov = [IoSliceMut::new(&mut buffer)];
695
- /// let r = recvmsg::<SockaddrIn>(in_socket, &mut iov, Some(&mut cmsgspace), flags)
696
+ /// let r = recvmsg::<SockaddrIn>(in_socket.as_raw_fd() , &mut iov, Some(&mut cmsgspace), flags)
696
697
/// .unwrap();
697
698
/// let rtime = match r.cmsgs().next() {
698
699
/// Some(ControlMessageOwned::ScmTimestamp(rtime)) => rtime,
@@ -708,7 +709,6 @@ pub enum ControlMessageOwned {
708
709
/// assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
709
710
/// assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
710
711
/// // Close socket
711
- /// nix::unistd::close(in_socket).unwrap();
712
712
/// # }
713
713
/// ```
714
714
ScmTimestamp ( TimeVal ) ,
@@ -1427,6 +1427,7 @@ impl<'a> ControlMessage<'a> {
1427
1427
/// # use nix::sys::socket::*;
1428
1428
/// # use nix::unistd::pipe;
1429
1429
/// # use std::io::IoSlice;
1430
+ /// # use std::os::unix::io::AsRawFd;
1430
1431
/// let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None,
1431
1432
/// SockFlag::empty())
1432
1433
/// .unwrap();
@@ -1435,14 +1436,15 @@ impl<'a> ControlMessage<'a> {
1435
1436
/// let iov = [IoSlice::new(b"hello")];
1436
1437
/// let fds = [r];
1437
1438
/// let cmsg = ControlMessage::ScmRights(&fds);
1438
- /// sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap();
1439
+ /// sendmsg::<()>(fd1.as_raw_fd() , &iov, &[cmsg], MsgFlags::empty(), None).unwrap();
1439
1440
/// ```
1440
1441
/// When directing to a specific address, the generic type will be inferred.
1441
1442
/// ```
1442
1443
/// # use nix::sys::socket::*;
1443
1444
/// # use nix::unistd::pipe;
1444
1445
/// # use std::io::IoSlice;
1445
1446
/// # use std::str::FromStr;
1447
+ /// # use std::os::unix::io::AsRawFd;
1446
1448
/// let localhost = SockaddrIn::from_str("1.2.3.4:8080").unwrap();
1447
1449
/// let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(),
1448
1450
/// None).unwrap();
@@ -1451,7 +1453,7 @@ impl<'a> ControlMessage<'a> {
1451
1453
/// let iov = [IoSlice::new(b"hello")];
1452
1454
/// let fds = [r];
1453
1455
/// let cmsg = ControlMessage::ScmRights(&fds);
1454
- /// sendmsg(fd, &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap();
1456
+ /// sendmsg(fd.as_raw_fd() , &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap();
1455
1457
/// ```
1456
1458
pub fn sendmsg<S >( fd: RawFd , iov: & [ IoSlice <' _>] , cmsgs: & [ ControlMessage ] ,
1457
1459
flags: MsgFlags , addr: Option <& S >) -> Result <usize >
@@ -1799,6 +1801,7 @@ mod test {
1799
1801
use crate :: sys:: socket:: { AddressFamily , ControlMessageOwned } ;
1800
1802
use crate :: * ;
1801
1803
use std:: str :: FromStr ;
1804
+ use std:: os:: unix:: io:: AsRawFd ;
1802
1805
1803
1806
#[ cfg_attr( qemu, ignore) ]
1804
1807
#[ test]
@@ -1825,9 +1828,9 @@ mod test {
1825
1828
None ,
1826
1829
) ?;
1827
1830
1828
- crate :: sys:: socket:: bind( rsock, & sock_addr) ?;
1831
+ crate :: sys:: socket:: bind( rsock. as_raw_fd ( ) , & sock_addr) ?;
1829
1832
1830
- setsockopt( rsock, Timestamping , & TimestampingFlag :: all( ) ) ?;
1833
+ setsockopt( & rsock, Timestamping , & TimestampingFlag :: all( ) ) ?;
1831
1834
1832
1835
let sbuf = ( 0 ..400 ) . map( |i| i as u8 ) . collect:: <Vec <_>>( ) ;
1833
1836
@@ -1849,13 +1852,13 @@ mod test {
1849
1852
let iov1 = [ IoSlice :: new( & sbuf) ] ;
1850
1853
1851
1854
let cmsg = cmsg_space!( crate :: sys:: socket:: Timestamps ) ;
1852
- sendmsg( ssock, & iov1, & [ ] , flags, Some ( & sock_addr) ) . unwrap( ) ;
1855
+ sendmsg( ssock. as_raw_fd ( ) , & iov1, & [ ] , flags, Some ( & sock_addr) ) . unwrap( ) ;
1853
1856
1854
1857
let mut data = super :: MultiHeaders :: <( ) >:: preallocate( recv_iovs. len( ) , Some ( cmsg) ) ;
1855
1858
1856
1859
let t = sys:: time:: TimeSpec :: from_duration( std:: time:: Duration :: from_secs( 10 ) ) ;
1857
1860
1858
- let recv = super :: recvmmsg( rsock, & mut data, recv_iovs. iter( ) , flags, Some ( t) ) ?;
1861
+ let recv = super :: recvmmsg( rsock. as_raw_fd ( ) , & mut data, recv_iovs. iter( ) , flags, Some ( t) ) ?;
1859
1862
1860
1863
for rmsg in recv {
1861
1864
#[ cfg( not( any( qemu, target_arch = "aarch64" ) ) ) ]
@@ -2062,7 +2065,7 @@ pub fn socket<T: Into<Option<SockProtocol>>>(
2062
2065
ty : SockType ,
2063
2066
flags : SockFlag ,
2064
2067
protocol : T ,
2065
- ) -> Result < RawFd > {
2068
+ ) -> Result < OwnedFd > {
2066
2069
let protocol = match protocol. into ( ) {
2067
2070
None => 0 ,
2068
2071
Some ( p) => p as c_int ,
@@ -2076,7 +2079,13 @@ pub fn socket<T: Into<Option<SockProtocol>>>(
2076
2079
2077
2080
let res = unsafe { libc:: socket ( domain as c_int , ty, protocol) } ;
2078
2081
2079
- Errno :: result ( res)
2082
+ match res {
2083
+ -1 => Err ( Errno :: last ( ) ) ,
2084
+ fd => {
2085
+ // Safe because libc::socket returned success
2086
+ unsafe { Ok ( OwnedFd :: from_raw_fd ( fd) ) }
2087
+ }
2088
+ }
2080
2089
}
2081
2090
2082
2091
/// Create a pair of connected sockets
@@ -2087,7 +2096,7 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(
2087
2096
ty : SockType ,
2088
2097
protocol : T ,
2089
2098
flags : SockFlag ,
2090
- ) -> Result < ( RawFd , RawFd ) > {
2099
+ ) -> Result < ( OwnedFd , OwnedFd ) > {
2091
2100
let protocol = match protocol. into ( ) {
2092
2101
None => 0 ,
2093
2102
Some ( p) => p as c_int ,
@@ -2106,14 +2115,18 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(
2106
2115
} ;
2107
2116
Errno :: result ( res) ?;
2108
2117
2109
- Ok ( ( fds[ 0 ] , fds[ 1 ] ) )
2118
+ // Safe because socketpair returned success.
2119
+ unsafe {
2120
+ Ok ( ( OwnedFd :: from_raw_fd ( fds[ 0 ] ) , OwnedFd :: from_raw_fd ( fds[ 1 ] ) ) )
2121
+ }
2110
2122
}
2111
2123
2112
2124
/// Listen for connections on a socket
2113
2125
///
2114
2126
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html)
2115
- pub fn listen ( sockfd : RawFd , backlog : usize ) -> Result < ( ) > {
2116
- let res = unsafe { libc:: listen ( sockfd, backlog as c_int ) } ;
2127
+ pub fn listen < F : AsFd > ( sock : & F , backlog : usize ) -> Result < ( ) > {
2128
+ let fd = sock. as_fd ( ) . as_raw_fd ( ) ;
2129
+ let res = unsafe { libc:: listen ( fd, backlog as c_int ) } ;
2117
2130
2118
2131
Errno :: result ( res) . map ( drop)
2119
2132
}
@@ -2273,21 +2286,21 @@ pub trait GetSockOpt: Copy {
2273
2286
type Val ;
2274
2287
2275
2288
/// Look up the value of this socket option on the given socket.
2276
- fn get ( & self , fd : RawFd ) -> Result < Self :: Val > ;
2289
+ fn get < F : AsFd > ( & self , fd : & F ) -> Result < Self :: Val > ;
2277
2290
}
2278
2291
2279
2292
/// Represents a socket option that can be set.
2280
2293
pub trait SetSockOpt : Clone {
2281
2294
type Val ;
2282
2295
2283
2296
/// Set the value of this socket option on the given socket.
2284
- fn set ( & self , fd : RawFd , val : & Self :: Val ) -> Result < ( ) > ;
2297
+ fn set < F : AsFd > ( & self , fd : & F , val : & Self :: Val ) -> Result < ( ) > ;
2285
2298
}
2286
2299
2287
2300
/// Get the current value for the requested socket option
2288
2301
///
2289
2302
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html)
2290
- pub fn getsockopt < O : GetSockOpt > ( fd : RawFd , opt : O ) -> Result < O :: Val > {
2303
+ pub fn getsockopt < F : AsFd , O : GetSockOpt > ( fd : & F , opt : O ) -> Result < O :: Val > {
2291
2304
opt. get ( fd)
2292
2305
}
2293
2306
@@ -2301,15 +2314,14 @@ pub fn getsockopt<O: GetSockOpt>(fd: RawFd, opt: O) -> Result<O::Val> {
2301
2314
/// use nix::sys::socket::setsockopt;
2302
2315
/// use nix::sys::socket::sockopt::KeepAlive;
2303
2316
/// use std::net::TcpListener;
2304
- /// use std::os::unix::io::AsRawFd;
2305
2317
///
2306
2318
/// let listener = TcpListener::bind("0.0.0.0:0").unwrap();
2307
- /// let fd = listener.as_raw_fd() ;
2308
- /// let res = setsockopt(fd, KeepAlive, &true);
2319
+ /// let fd = listener;
2320
+ /// let res = setsockopt(& fd, KeepAlive, &true);
2309
2321
/// assert!(res.is_ok());
2310
2322
/// ```
2311
- pub fn setsockopt < O : SetSockOpt > (
2312
- fd : RawFd ,
2323
+ pub fn setsockopt < F : AsFd , O : SetSockOpt > (
2324
+ fd : & F ,
2313
2325
opt : O ,
2314
2326
val : & O :: Val ,
2315
2327
) -> Result < ( ) > {
0 commit comments