@@ -18,7 +18,7 @@ use libc::{
18
18
use std:: io:: { IoSlice , IoSliceMut } ;
19
19
#[ cfg( feature = "net" ) ]
20
20
use std:: net;
21
- use std:: os:: unix:: io:: RawFd ;
21
+ use std:: os:: unix:: io:: { AsFd , AsRawFd , FromRawFd , RawFd , OwnedFd } ;
22
22
use std:: { mem, ptr} ;
23
23
24
24
#[ deny( missing_docs) ]
@@ -693,6 +693,7 @@ pub enum ControlMessageOwned {
693
693
/// # use std::io::{IoSlice, IoSliceMut};
694
694
/// # use std::time::*;
695
695
/// # use std::str::FromStr;
696
+ /// # use std::os::unix::io::AsRawFd;
696
697
/// # fn main() {
697
698
/// // Set up
698
699
/// let message = "Ohayō!".as_bytes();
@@ -701,22 +702,22 @@ pub enum ControlMessageOwned {
701
702
/// SockType::Datagram,
702
703
/// SockFlag::empty(),
703
704
/// None).unwrap();
704
- /// setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
705
+ /// setsockopt(& in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
705
706
/// let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap();
706
- /// bind(in_socket, &localhost).unwrap();
707
- /// let address: SockaddrIn = getsockname(in_socket).unwrap();
707
+ /// bind(in_socket.as_raw_fd() , &localhost).unwrap();
708
+ /// let address: SockaddrIn = getsockname(in_socket.as_raw_fd() ).unwrap();
708
709
/// // Get initial time
709
710
/// let time0 = SystemTime::now();
710
711
/// // Send the message
711
712
/// let iov = [IoSlice::new(message)];
712
713
/// let flags = MsgFlags::empty();
713
- /// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
714
+ /// let l = sendmsg(in_socket.as_raw_fd() , &iov, &[], flags, Some(&address)).unwrap();
714
715
/// assert_eq!(message.len(), l);
715
716
/// // Receive the message
716
717
/// let mut buffer = vec![0u8; message.len()];
717
718
/// let mut cmsgspace = cmsg_space!(TimeVal);
718
719
/// let mut iov = [IoSliceMut::new(&mut buffer)];
719
- /// let r = recvmsg::<SockaddrIn>(in_socket, &mut iov, Some(&mut cmsgspace), flags)
720
+ /// let r = recvmsg::<SockaddrIn>(in_socket.as_raw_fd() , &mut iov, Some(&mut cmsgspace), flags)
720
721
/// .unwrap();
721
722
/// let rtime = match r.cmsgs().next() {
722
723
/// Some(ControlMessageOwned::ScmTimestamp(rtime)) => rtime,
@@ -732,7 +733,6 @@ pub enum ControlMessageOwned {
732
733
/// assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
733
734
/// assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
734
735
/// // Close socket
735
- /// nix::unistd::close(in_socket).unwrap();
736
736
/// # }
737
737
/// ```
738
738
ScmTimestamp ( TimeVal ) ,
@@ -1451,6 +1451,7 @@ impl<'a> ControlMessage<'a> {
1451
1451
/// # use nix::sys::socket::*;
1452
1452
/// # use nix::unistd::pipe;
1453
1453
/// # use std::io::IoSlice;
1454
+ /// # use std::os::unix::io::AsRawFd;
1454
1455
/// let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None,
1455
1456
/// SockFlag::empty())
1456
1457
/// .unwrap();
@@ -1459,14 +1460,15 @@ impl<'a> ControlMessage<'a> {
1459
1460
/// let iov = [IoSlice::new(b"hello")];
1460
1461
/// let fds = [r];
1461
1462
/// let cmsg = ControlMessage::ScmRights(&fds);
1462
- /// sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap();
1463
+ /// sendmsg::<()>(fd1.as_raw_fd() , &iov, &[cmsg], MsgFlags::empty(), None).unwrap();
1463
1464
/// ```
1464
1465
/// When directing to a specific address, the generic type will be inferred.
1465
1466
/// ```
1466
1467
/// # use nix::sys::socket::*;
1467
1468
/// # use nix::unistd::pipe;
1468
1469
/// # use std::io::IoSlice;
1469
1470
/// # use std::str::FromStr;
1471
+ /// # use std::os::unix::io::AsRawFd;
1470
1472
/// let localhost = SockaddrIn::from_str("1.2.3.4:8080").unwrap();
1471
1473
/// let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(),
1472
1474
/// None).unwrap();
@@ -1475,7 +1477,7 @@ impl<'a> ControlMessage<'a> {
1475
1477
/// let iov = [IoSlice::new(b"hello")];
1476
1478
/// let fds = [r];
1477
1479
/// let cmsg = ControlMessage::ScmRights(&fds);
1478
- /// sendmsg(fd, &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap();
1480
+ /// sendmsg(fd.as_raw_fd() , &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap();
1479
1481
/// ```
1480
1482
pub fn sendmsg<S >( fd: RawFd , iov: & [ IoSlice <' _>] , cmsgs: & [ ControlMessage ] ,
1481
1483
flags: MsgFlags , addr: Option <& S >) -> Result <usize >
@@ -1823,6 +1825,7 @@ mod test {
1823
1825
use crate :: sys:: socket:: { AddressFamily , ControlMessageOwned } ;
1824
1826
use crate :: * ;
1825
1827
use std:: str :: FromStr ;
1828
+ use std:: os:: unix:: io:: AsRawFd ;
1826
1829
1827
1830
#[ cfg_attr( qemu, ignore) ]
1828
1831
#[ test]
@@ -1849,9 +1852,9 @@ mod test {
1849
1852
None ,
1850
1853
) ?;
1851
1854
1852
- crate :: sys:: socket:: bind( rsock, & sock_addr) ?;
1855
+ crate :: sys:: socket:: bind( rsock. as_raw_fd ( ) , & sock_addr) ?;
1853
1856
1854
- setsockopt( rsock, Timestamping , & TimestampingFlag :: all( ) ) ?;
1857
+ setsockopt( & rsock, Timestamping , & TimestampingFlag :: all( ) ) ?;
1855
1858
1856
1859
let sbuf = ( 0 ..400 ) . map( |i| i as u8 ) . collect:: <Vec <_>>( ) ;
1857
1860
@@ -1873,13 +1876,13 @@ mod test {
1873
1876
let iov1 = [ IoSlice :: new( & sbuf) ] ;
1874
1877
1875
1878
let cmsg = cmsg_space!( crate :: sys:: socket:: Timestamps ) ;
1876
- sendmsg( ssock, & iov1, & [ ] , flags, Some ( & sock_addr) ) . unwrap( ) ;
1879
+ sendmsg( ssock. as_raw_fd ( ) , & iov1, & [ ] , flags, Some ( & sock_addr) ) . unwrap( ) ;
1877
1880
1878
1881
let mut data = super :: MultiHeaders :: <( ) >:: preallocate( recv_iovs. len( ) , Some ( cmsg) ) ;
1879
1882
1880
1883
let t = sys:: time:: TimeSpec :: from_duration( std:: time:: Duration :: from_secs( 10 ) ) ;
1881
1884
1882
- let recv = super :: recvmmsg( rsock, & mut data, recv_iovs. iter( ) , flags, Some ( t) ) ?;
1885
+ let recv = super :: recvmmsg( rsock. as_raw_fd ( ) , & mut data, recv_iovs. iter( ) , flags, Some ( t) ) ?;
1883
1886
1884
1887
for rmsg in recv {
1885
1888
#[ cfg( not( any( qemu, target_arch = "aarch64" ) ) ) ]
@@ -2091,7 +2094,7 @@ pub fn socket<T: Into<Option<SockProtocol>>>(
2091
2094
ty : SockType ,
2092
2095
flags : SockFlag ,
2093
2096
protocol : T ,
2094
- ) -> Result < RawFd > {
2097
+ ) -> Result < OwnedFd > {
2095
2098
let protocol = match protocol. into ( ) {
2096
2099
None => 0 ,
2097
2100
Some ( p) => p as c_int ,
@@ -2105,7 +2108,13 @@ pub fn socket<T: Into<Option<SockProtocol>>>(
2105
2108
2106
2109
let res = unsafe { libc:: socket ( domain as c_int , ty, protocol) } ;
2107
2110
2108
- Errno :: result ( res)
2111
+ match res {
2112
+ -1 => Err ( Errno :: last ( ) ) ,
2113
+ fd => {
2114
+ // Safe because libc::socket returned success
2115
+ unsafe { Ok ( OwnedFd :: from_raw_fd ( fd) ) }
2116
+ }
2117
+ }
2109
2118
}
2110
2119
2111
2120
/// Create a pair of connected sockets
@@ -2116,7 +2125,7 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(
2116
2125
ty : SockType ,
2117
2126
protocol : T ,
2118
2127
flags : SockFlag ,
2119
- ) -> Result < ( RawFd , RawFd ) > {
2128
+ ) -> Result < ( OwnedFd , OwnedFd ) > {
2120
2129
let protocol = match protocol. into ( ) {
2121
2130
None => 0 ,
2122
2131
Some ( p) => p as c_int ,
@@ -2135,14 +2144,18 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(
2135
2144
} ;
2136
2145
Errno :: result ( res) ?;
2137
2146
2138
- Ok ( ( fds[ 0 ] , fds[ 1 ] ) )
2147
+ // Safe because socketpair returned success.
2148
+ unsafe {
2149
+ Ok ( ( OwnedFd :: from_raw_fd ( fds[ 0 ] ) , OwnedFd :: from_raw_fd ( fds[ 1 ] ) ) )
2150
+ }
2139
2151
}
2140
2152
2141
2153
/// Listen for connections on a socket
2142
2154
///
2143
2155
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html)
2144
- pub fn listen ( sockfd : RawFd , backlog : usize ) -> Result < ( ) > {
2145
- let res = unsafe { libc:: listen ( sockfd, backlog as c_int ) } ;
2156
+ pub fn listen < F : AsFd > ( sock : & F , backlog : usize ) -> Result < ( ) > {
2157
+ let fd = sock. as_fd ( ) . as_raw_fd ( ) ;
2158
+ let res = unsafe { libc:: listen ( fd, backlog as c_int ) } ;
2146
2159
2147
2160
Errno :: result ( res) . map ( drop)
2148
2161
}
@@ -2302,21 +2315,21 @@ pub trait GetSockOpt: Copy {
2302
2315
type Val ;
2303
2316
2304
2317
/// Look up the value of this socket option on the given socket.
2305
- fn get ( & self , fd : RawFd ) -> Result < Self :: Val > ;
2318
+ fn get < F : AsFd > ( & self , fd : & F ) -> Result < Self :: Val > ;
2306
2319
}
2307
2320
2308
2321
/// Represents a socket option that can be set.
2309
2322
pub trait SetSockOpt : Clone {
2310
2323
type Val ;
2311
2324
2312
2325
/// Set the value of this socket option on the given socket.
2313
- fn set ( & self , fd : RawFd , val : & Self :: Val ) -> Result < ( ) > ;
2326
+ fn set < F : AsFd > ( & self , fd : & F , val : & Self :: Val ) -> Result < ( ) > ;
2314
2327
}
2315
2328
2316
2329
/// Get the current value for the requested socket option
2317
2330
///
2318
2331
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html)
2319
- pub fn getsockopt < O : GetSockOpt > ( fd : RawFd , opt : O ) -> Result < O :: Val > {
2332
+ pub fn getsockopt < F : AsFd , O : GetSockOpt > ( fd : & F , opt : O ) -> Result < O :: Val > {
2320
2333
opt. get ( fd)
2321
2334
}
2322
2335
@@ -2330,15 +2343,14 @@ pub fn getsockopt<O: GetSockOpt>(fd: RawFd, opt: O) -> Result<O::Val> {
2330
2343
/// use nix::sys::socket::setsockopt;
2331
2344
/// use nix::sys::socket::sockopt::KeepAlive;
2332
2345
/// use std::net::TcpListener;
2333
- /// use std::os::unix::io::AsRawFd;
2334
2346
///
2335
2347
/// let listener = TcpListener::bind("0.0.0.0:0").unwrap();
2336
- /// let fd = listener.as_raw_fd() ;
2337
- /// let res = setsockopt(fd, KeepAlive, &true);
2348
+ /// let fd = listener;
2349
+ /// let res = setsockopt(& fd, KeepAlive, &true);
2338
2350
/// assert!(res.is_ok());
2339
2351
/// ```
2340
- pub fn setsockopt < O : SetSockOpt > (
2341
- fd : RawFd ,
2352
+ pub fn setsockopt < F : AsFd , O : SetSockOpt > (
2353
+ fd : & F ,
2342
2354
opt : O ,
2343
2355
val : & O :: Val ,
2344
2356
) -> Result < ( ) > {
0 commit comments