@@ -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) ]
@@ -682,6 +682,7 @@ pub enum ControlMessageOwned {
682
682
/// # use std::io::{IoSlice, IoSliceMut};
683
683
/// # use std::time::*;
684
684
/// # use std::str::FromStr;
685
+ /// # use std::os::unix::io::AsRawFd;
685
686
/// # fn main() {
686
687
/// // Set up
687
688
/// let message = "Ohayō!".as_bytes();
@@ -690,22 +691,22 @@ pub enum ControlMessageOwned {
690
691
/// SockType::Datagram,
691
692
/// SockFlag::empty(),
692
693
/// None).unwrap();
693
- /// setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
694
+ /// setsockopt(& in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
694
695
/// let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap();
695
- /// bind(in_socket, &localhost).unwrap();
696
- /// let address: SockaddrIn = getsockname(in_socket).unwrap();
696
+ /// bind(in_socket.as_raw_fd() , &localhost).unwrap();
697
+ /// let address: SockaddrIn = getsockname(in_socket.as_raw_fd() ).unwrap();
697
698
/// // Get initial time
698
699
/// let time0 = SystemTime::now();
699
700
/// // Send the message
700
701
/// let iov = [IoSlice::new(message)];
701
702
/// let flags = MsgFlags::empty();
702
- /// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
703
+ /// let l = sendmsg(in_socket.as_raw_fd() , &iov, &[], flags, Some(&address)).unwrap();
703
704
/// assert_eq!(message.len(), l);
704
705
/// // Receive the message
705
706
/// let mut buffer = vec![0u8; message.len()];
706
707
/// let mut cmsgspace = cmsg_space!(TimeVal);
707
708
/// let mut iov = [IoSliceMut::new(&mut buffer)];
708
- /// let r = recvmsg::<SockaddrIn>(in_socket, &mut iov, Some(&mut cmsgspace), flags)
709
+ /// let r = recvmsg::<SockaddrIn>(in_socket.as_raw_fd() , &mut iov, Some(&mut cmsgspace), flags)
709
710
/// .unwrap();
710
711
/// let rtime = match r.cmsgs().next() {
711
712
/// Some(ControlMessageOwned::ScmTimestamp(rtime)) => rtime,
@@ -721,7 +722,6 @@ pub enum ControlMessageOwned {
721
722
/// assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
722
723
/// assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
723
724
/// // Close socket
724
- /// nix::unistd::close(in_socket).unwrap();
725
725
/// # }
726
726
/// ```
727
727
ScmTimestamp ( TimeVal ) ,
@@ -1440,6 +1440,7 @@ impl<'a> ControlMessage<'a> {
1440
1440
/// # use nix::sys::socket::*;
1441
1441
/// # use nix::unistd::pipe;
1442
1442
/// # use std::io::IoSlice;
1443
+ /// # use std::os::unix::io::AsRawFd;
1443
1444
/// let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None,
1444
1445
/// SockFlag::empty())
1445
1446
/// .unwrap();
@@ -1448,14 +1449,15 @@ impl<'a> ControlMessage<'a> {
1448
1449
/// let iov = [IoSlice::new(b"hello")];
1449
1450
/// let fds = [r];
1450
1451
/// let cmsg = ControlMessage::ScmRights(&fds);
1451
- /// sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap();
1452
+ /// sendmsg::<()>(fd1.as_raw_fd() , &iov, &[cmsg], MsgFlags::empty(), None).unwrap();
1452
1453
/// ```
1453
1454
/// When directing to a specific address, the generic type will be inferred.
1454
1455
/// ```
1455
1456
/// # use nix::sys::socket::*;
1456
1457
/// # use nix::unistd::pipe;
1457
1458
/// # use std::io::IoSlice;
1458
1459
/// # use std::str::FromStr;
1460
+ /// # use std::os::unix::io::AsRawFd;
1459
1461
/// let localhost = SockaddrIn::from_str("1.2.3.4:8080").unwrap();
1460
1462
/// let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(),
1461
1463
/// None).unwrap();
@@ -1464,7 +1466,7 @@ impl<'a> ControlMessage<'a> {
1464
1466
/// let iov = [IoSlice::new(b"hello")];
1465
1467
/// let fds = [r];
1466
1468
/// let cmsg = ControlMessage::ScmRights(&fds);
1467
- /// sendmsg(fd, &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap();
1469
+ /// sendmsg(fd.as_raw_fd() , &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap();
1468
1470
/// ```
1469
1471
pub fn sendmsg<S >( fd: RawFd , iov: & [ IoSlice <' _>] , cmsgs: & [ ControlMessage ] ,
1470
1472
flags: MsgFlags , addr: Option <& S >) -> Result <usize >
@@ -1812,6 +1814,7 @@ mod test {
1812
1814
use crate :: sys:: socket:: { AddressFamily , ControlMessageOwned } ;
1813
1815
use crate :: * ;
1814
1816
use std:: str :: FromStr ;
1817
+ use std:: os:: unix:: io:: AsRawFd ;
1815
1818
1816
1819
#[ cfg_attr( qemu, ignore) ]
1817
1820
#[ test]
@@ -1838,9 +1841,9 @@ mod test {
1838
1841
None ,
1839
1842
) ?;
1840
1843
1841
- crate :: sys:: socket:: bind( rsock, & sock_addr) ?;
1844
+ crate :: sys:: socket:: bind( rsock. as_raw_fd ( ) , & sock_addr) ?;
1842
1845
1843
- setsockopt( rsock, Timestamping , & TimestampingFlag :: all( ) ) ?;
1846
+ setsockopt( & rsock, Timestamping , & TimestampingFlag :: all( ) ) ?;
1844
1847
1845
1848
let sbuf = ( 0 ..400 ) . map( |i| i as u8 ) . collect:: <Vec <_>>( ) ;
1846
1849
@@ -1862,13 +1865,13 @@ mod test {
1862
1865
let iov1 = [ IoSlice :: new( & sbuf) ] ;
1863
1866
1864
1867
let cmsg = cmsg_space!( crate :: sys:: socket:: Timestamps ) ;
1865
- sendmsg( ssock, & iov1, & [ ] , flags, Some ( & sock_addr) ) . unwrap( ) ;
1868
+ sendmsg( ssock. as_raw_fd ( ) , & iov1, & [ ] , flags, Some ( & sock_addr) ) . unwrap( ) ;
1866
1869
1867
1870
let mut data = super :: MultiHeaders :: <( ) >:: preallocate( recv_iovs. len( ) , Some ( cmsg) ) ;
1868
1871
1869
1872
let t = sys:: time:: TimeSpec :: from_duration( std:: time:: Duration :: from_secs( 10 ) ) ;
1870
1873
1871
- let recv = super :: recvmmsg( rsock, & mut data, recv_iovs. iter( ) , flags, Some ( t) ) ?;
1874
+ let recv = super :: recvmmsg( rsock. as_raw_fd ( ) , & mut data, recv_iovs. iter( ) , flags, Some ( t) ) ?;
1872
1875
1873
1876
for rmsg in recv {
1874
1877
#[ cfg( not( any( qemu, target_arch = "aarch64" ) ) ) ]
@@ -2075,7 +2078,7 @@ pub fn socket<T: Into<Option<SockProtocol>>>(
2075
2078
ty : SockType ,
2076
2079
flags : SockFlag ,
2077
2080
protocol : T ,
2078
- ) -> Result < RawFd > {
2081
+ ) -> Result < OwnedFd > {
2079
2082
let protocol = match protocol. into ( ) {
2080
2083
None => 0 ,
2081
2084
Some ( p) => p as c_int ,
@@ -2089,7 +2092,13 @@ pub fn socket<T: Into<Option<SockProtocol>>>(
2089
2092
2090
2093
let res = unsafe { libc:: socket ( domain as c_int , ty, protocol) } ;
2091
2094
2092
- Errno :: result ( res)
2095
+ match res {
2096
+ -1 => Err ( Errno :: last ( ) ) ,
2097
+ fd => {
2098
+ // Safe because libc::socket returned success
2099
+ unsafe { Ok ( OwnedFd :: from_raw_fd ( fd) ) }
2100
+ }
2101
+ }
2093
2102
}
2094
2103
2095
2104
/// Create a pair of connected sockets
@@ -2100,7 +2109,7 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(
2100
2109
ty : SockType ,
2101
2110
protocol : T ,
2102
2111
flags : SockFlag ,
2103
- ) -> Result < ( RawFd , RawFd ) > {
2112
+ ) -> Result < ( OwnedFd , OwnedFd ) > {
2104
2113
let protocol = match protocol. into ( ) {
2105
2114
None => 0 ,
2106
2115
Some ( p) => p as c_int ,
@@ -2119,14 +2128,18 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(
2119
2128
} ;
2120
2129
Errno :: result ( res) ?;
2121
2130
2122
- Ok ( ( fds[ 0 ] , fds[ 1 ] ) )
2131
+ // Safe because socketpair returned success.
2132
+ unsafe {
2133
+ Ok ( ( OwnedFd :: from_raw_fd ( fds[ 0 ] ) , OwnedFd :: from_raw_fd ( fds[ 1 ] ) ) )
2134
+ }
2123
2135
}
2124
2136
2125
2137
/// Listen for connections on a socket
2126
2138
///
2127
2139
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html)
2128
- pub fn listen ( sockfd : RawFd , backlog : usize ) -> Result < ( ) > {
2129
- let res = unsafe { libc:: listen ( sockfd, backlog as c_int ) } ;
2140
+ pub fn listen < F : AsFd > ( sock : & F , backlog : usize ) -> Result < ( ) > {
2141
+ let fd = sock. as_fd ( ) . as_raw_fd ( ) ;
2142
+ let res = unsafe { libc:: listen ( fd, backlog as c_int ) } ;
2130
2143
2131
2144
Errno :: result ( res) . map ( drop)
2132
2145
}
@@ -2286,21 +2299,21 @@ pub trait GetSockOpt: Copy {
2286
2299
type Val ;
2287
2300
2288
2301
/// Look up the value of this socket option on the given socket.
2289
- fn get ( & self , fd : RawFd ) -> Result < Self :: Val > ;
2302
+ fn get < F : AsFd > ( & self , fd : & F ) -> Result < Self :: Val > ;
2290
2303
}
2291
2304
2292
2305
/// Represents a socket option that can be set.
2293
2306
pub trait SetSockOpt : Clone {
2294
2307
type Val ;
2295
2308
2296
2309
/// Set the value of this socket option on the given socket.
2297
- fn set ( & self , fd : RawFd , val : & Self :: Val ) -> Result < ( ) > ;
2310
+ fn set < F : AsFd > ( & self , fd : & F , val : & Self :: Val ) -> Result < ( ) > ;
2298
2311
}
2299
2312
2300
2313
/// Get the current value for the requested socket option
2301
2314
///
2302
2315
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html)
2303
- pub fn getsockopt < O : GetSockOpt > ( fd : RawFd , opt : O ) -> Result < O :: Val > {
2316
+ pub fn getsockopt < F : AsFd , O : GetSockOpt > ( fd : & F , opt : O ) -> Result < O :: Val > {
2304
2317
opt. get ( fd)
2305
2318
}
2306
2319
@@ -2314,15 +2327,14 @@ pub fn getsockopt<O: GetSockOpt>(fd: RawFd, opt: O) -> Result<O::Val> {
2314
2327
/// use nix::sys::socket::setsockopt;
2315
2328
/// use nix::sys::socket::sockopt::KeepAlive;
2316
2329
/// use std::net::TcpListener;
2317
- /// use std::os::unix::io::AsRawFd;
2318
2330
///
2319
2331
/// let listener = TcpListener::bind("0.0.0.0:0").unwrap();
2320
- /// let fd = listener.as_raw_fd() ;
2321
- /// let res = setsockopt(fd, KeepAlive, &true);
2332
+ /// let fd = listener;
2333
+ /// let res = setsockopt(& fd, KeepAlive, &true);
2322
2334
/// assert!(res.is_ok());
2323
2335
/// ```
2324
- pub fn setsockopt < O : SetSockOpt > (
2325
- fd : RawFd ,
2336
+ pub fn setsockopt < F : AsFd , O : SetSockOpt > (
2337
+ fd : & F ,
2326
2338
opt : O ,
2327
2339
val : & O :: Val ,
2328
2340
) -> Result < ( ) > {
0 commit comments