1
1
//! Support for Unix domain socket clients and servers.
2
2
#![ warn( missing_docs) ]
3
- #![ doc( html_root_url="https://sfackler.github.io/rust-unix-socket/doc/v0.4.4 " ) ]
3
+ #![ doc( html_root_url="https://sfackler.github.io/rust-unix-socket/doc/v0.4.5 " ) ]
4
4
#![ cfg_attr( feature = "socket_timeout" , feature( duration) ) ]
5
5
#![ cfg_attr( all( test, feature = "socket_timeout" ) , feature( duration_span) ) ]
6
6
@@ -81,10 +81,10 @@ impl Inner {
81
81
}
82
82
}
83
83
84
- fn new_pair ( ) -> io:: Result < ( Inner , Inner ) > {
84
+ fn new_pair ( kind : libc :: c_int ) -> io:: Result < ( Inner , Inner ) > {
85
85
unsafe {
86
86
let mut fds = [ 0 , 0 ] ;
87
- try!( cvt ( socketpair ( libc:: AF_UNIX , libc :: SOCK_STREAM , 0 , & mut fds) ) ) ;
87
+ try!( cvt ( socketpair ( libc:: AF_UNIX , kind , 0 , & mut fds) ) ) ;
88
88
Ok ( ( Inner ( fds[ 0 ] ) , Inner ( fds[ 1 ] ) ) )
89
89
}
90
90
}
@@ -132,19 +132,19 @@ impl Inner {
132
132
fn set_timeout ( & self , dur : Option < std:: time:: Duration > , kind : libc:: c_int ) -> io:: Result < ( ) > {
133
133
let timeout = match dur {
134
134
Some ( dur) => {
135
- if dur. secs ( ) == 0 && dur. extra_nanos ( ) == 0 {
135
+ if dur. as_secs ( ) == 0 && dur. subsec_nanos ( ) == 0 {
136
136
return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidInput ,
137
137
"cannot set a 0 duration timeout" ) ) ;
138
138
}
139
139
140
- let secs = if dur. secs ( ) > libc:: time_t:: max_value ( ) as u64 {
140
+ let secs = if dur. as_secs ( ) > libc:: time_t:: max_value ( ) as u64 {
141
141
libc:: time_t:: max_value ( )
142
142
} else {
143
- dur. secs ( ) as libc:: time_t
143
+ dur. as_secs ( ) as libc:: time_t
144
144
} ;
145
145
let mut timeout = libc:: timeval {
146
146
tv_sec : secs,
147
- tv_usec : ( dur. extra_nanos ( ) / 1000 ) as libc:: suseconds_t ,
147
+ tv_usec : ( dur. subsec_nanos ( ) / 1000 ) as libc:: suseconds_t ,
148
148
} ;
149
149
if timeout. tv_sec == 0 && timeout. tv_usec == 0 {
150
150
timeout. tv_usec = 1 ;
@@ -242,9 +242,7 @@ impl SocketAddr {
242
242
// When there is a datagram from unnamed unix socket
243
243
// linux returns zero bytes of address
244
244
len = sun_path_offset ( ) as libc:: socklen_t ; // i.e. zero-length address
245
- } else if ( len as usize ) < size_of :: < libc:: sa_family_t > ( ) ||
246
- addr. sun_family != libc:: AF_UNIX as libc:: sa_family_t
247
- {
245
+ } else if addr. sun_family != libc:: AF_UNIX as libc:: sa_family_t {
248
246
return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidInput ,
249
247
"file descriptor did not correspond to a Unix socket" ) ) ;
250
248
}
@@ -353,11 +351,18 @@ impl UnixStream {
353
351
/// Create an unnamed pair of connected sockets.
354
352
///
355
353
/// Returns two `UnixStream`s which are connected to each other.
356
- pub fn unnamed ( ) -> io:: Result < ( UnixStream , UnixStream ) > {
357
- let ( i1, i2) = try!( Inner :: new_pair ( ) ) ;
354
+ pub fn pair ( ) -> io:: Result < ( UnixStream , UnixStream ) > {
355
+ let ( i1, i2) = try!( Inner :: new_pair ( libc :: SOCK_STREAM ) ) ;
358
356
Ok ( ( UnixStream { inner : i1 } , UnixStream { inner : i2 } ) )
359
357
}
360
358
359
+ /// # Deprecated
360
+ ///
361
+ /// Use `UnixStream::pair` instead.
362
+ pub fn unnamed ( ) -> io:: Result < ( UnixStream , UnixStream ) > {
363
+ UnixStream :: pair ( )
364
+ }
365
+
361
366
/// Create a new independently owned handle to the underlying socket.
362
367
///
363
368
/// The returned `UnixStream` is a reference to the same stream that this
@@ -479,7 +484,7 @@ impl AsRawFd for UnixStream {
479
484
}
480
485
481
486
#[ cfg( feature = "from_raw_fd" ) ]
482
- /// Requires the `from_raw_fd` feature.
487
+ /// Requires the `from_raw_fd` feature (enabled by default) .
483
488
impl std:: os:: unix:: io:: FromRawFd for UnixStream {
484
489
unsafe fn from_raw_fd ( fd : RawFd ) -> UnixStream {
485
490
UnixStream {
@@ -598,7 +603,7 @@ impl AsRawFd for UnixListener {
598
603
}
599
604
600
605
#[ cfg( feature = "from_raw_fd" ) ]
601
- /// Requires the `from_raw_fd` feature.
606
+ /// Requires the `from_raw_fd` feature (enabled by default) .
602
607
impl std:: os:: unix:: io:: FromRawFd for UnixListener {
603
608
unsafe fn from_raw_fd ( fd : RawFd ) -> UnixListener {
604
609
UnixListener {
@@ -660,12 +665,21 @@ impl fmt::Debug for UnixDatagram {
660
665
if let Ok ( addr) = self . local_addr ( ) {
661
666
builder = builder. field ( "local" , & addr) ;
662
667
}
668
+ if let Ok ( addr) = self . peer_addr ( ) {
669
+ builder = builder. field ( "peer" , & addr) ;
670
+ }
663
671
builder. finish ( )
664
672
}
665
673
}
666
674
667
675
impl UnixDatagram {
668
676
/// Creates a Unix datagram socket bound to the given path.
677
+ ///
678
+ /// Linux provides, as a nonportable extension, a separate "abstract"
679
+ /// address namespace as opposed to filesystem-based addressing. If `path`
680
+ /// begins with a null byte, it will be interpreted as an "abstract"
681
+ /// address. Otherwise, it will be interpreted as a "pathname" address,
682
+ /// corresponding to a path on the filesystem.
669
683
pub fn bind < P : AsRef < Path > > ( path : P ) -> io:: Result < UnixDatagram > {
670
684
unsafe {
671
685
let inner = try!( Inner :: new ( libc:: SOCK_DGRAM ) ) ;
@@ -687,6 +701,14 @@ impl UnixDatagram {
687
701
} )
688
702
}
689
703
704
+ /// Create an unnamed pair of connected sockets.
705
+ ///
706
+ /// Returns two `UnixDatagrams`s which are connected to each other.
707
+ pub fn pair ( ) -> io:: Result < ( UnixDatagram , UnixDatagram ) > {
708
+ let ( i1, i2) = try!( Inner :: new_pair ( libc:: SOCK_DGRAM ) ) ;
709
+ Ok ( ( UnixDatagram { inner : i1 } , UnixDatagram { inner : i2 } ) )
710
+ }
711
+
690
712
/// Connect the socket to the specified address.
691
713
///
692
714
/// The `send` method may be used to send data to the specified address.
@@ -708,6 +730,13 @@ impl UnixDatagram {
708
730
SocketAddr :: new ( |addr, len| unsafe { libc:: getsockname ( self . inner . 0 , addr, len) } )
709
731
}
710
732
733
+ /// Returns the address of this socket's peer.
734
+ ///
735
+ /// The `connect` method will connect the socket to a peer.
736
+ pub fn peer_addr ( & self ) -> io:: Result < SocketAddr > {
737
+ SocketAddr :: new ( |addr, len| unsafe { libc:: getpeername ( self . inner . 0 , addr, len) } )
738
+ }
739
+
711
740
/// Receives data from the socket.
712
741
///
713
742
/// On success, returns the number of bytes read and the address from
@@ -777,8 +806,8 @@ impl UnixDatagram {
777
806
778
807
/// Sets the read timeout for the socket.
779
808
///
780
- /// If the provided value is `None`, then `recv_from` calls will block
781
- /// indefinitely. It is an error to pass the zero `Duration` to this
809
+ /// If the provided value is `None`, then `recv` and ` recv_from` calls will
810
+ /// block indefinitely. It is an error to pass the zero `Duration` to this
782
811
/// method.
783
812
///
784
813
/// Requires the `socket_timeout` feature.
@@ -789,8 +818,8 @@ impl UnixDatagram {
789
818
790
819
/// Sets the write timeout for the socket.
791
820
///
792
- /// If the provided value is `None`, then `send_to` calls will block
793
- /// indefinitely. It is an error to pass the zero `Duration` to this
821
+ /// If the provided value is `None`, then `send` and ` send_to` calls will
822
+ /// block indefinitely. It is an error to pass the zero `Duration` to this
794
823
/// method.
795
824
///
796
825
/// Requires the `socket_timeout` feature.
@@ -832,7 +861,7 @@ impl AsRawFd for UnixDatagram {
832
861
}
833
862
834
863
#[ cfg( feature = "from_raw_fd" ) ]
835
- /// Requires the `from_raw_fd` feature.
864
+ /// Requires the `from_raw_fd` feature (enabled by default) .
836
865
impl std:: os:: unix:: io:: FromRawFd for UnixDatagram {
837
866
unsafe fn from_raw_fd ( fd : RawFd ) -> UnixDatagram {
838
867
UnixDatagram {
@@ -888,11 +917,11 @@ mod test {
888
917
}
889
918
890
919
#[ test]
891
- fn unnamed ( ) {
920
+ fn pair ( ) {
892
921
let msg1 = b"hello" ;
893
922
let msg2 = b"world!" ;
894
923
895
- let ( mut s1, mut s2) = or_panic ! ( UnixStream :: unnamed ( ) ) ;
924
+ let ( mut s1, mut s2) = or_panic ! ( UnixStream :: pair ( ) ) ;
896
925
let thread = thread:: spawn ( move || {
897
926
// s1 must be moved in or the test will hang!
898
927
let mut buf = [ 0 ; 5 ] ;
@@ -1000,6 +1029,12 @@ mod test {
1000
1029
Err ( e) => panic ! ( "unexpected error {}" , e) ,
1001
1030
Ok ( _) => panic ! ( "unexpected success" ) ,
1002
1031
}
1032
+
1033
+ match UnixDatagram :: bind ( & socket_path) {
1034
+ Err ( ref e) if e. kind ( ) == io:: ErrorKind :: InvalidInput => { }
1035
+ Err ( e) => panic ! ( "unexpected error {}" , e) ,
1036
+ Ok ( _) => panic ! ( "unexpected success" ) ,
1037
+ }
1003
1038
}
1004
1039
1005
1040
#[ test]
@@ -1135,13 +1170,6 @@ mod test {
1135
1170
assert_eq ! ( addr. address( ) , AddressKind :: Unnamed ) ;
1136
1171
assert_eq ! ( msg, & buf[ ..] ) ;
1137
1172
1138
-
1139
- // Send to should still work too
1140
- let msg = b"hello world" ;
1141
- or_panic ! ( sock. send_to( msg, & path2) ) ;
1142
- or_panic ! ( bsock2. recv_from( & mut buf) ) ;
1143
- assert_eq ! ( msg, & buf[ ..] ) ;
1144
-
1145
1173
// Changing default socket works too
1146
1174
or_panic ! ( sock. connect( & path2) ) ;
1147
1175
or_panic ! ( sock. send( msg) ) ;
@@ -1158,10 +1186,33 @@ mod test {
1158
1186
or_panic ! ( sock2. connect( & path1) ) ;
1159
1187
1160
1188
let msg = b"hello world" ;
1161
- or_panic ! ( sock2. send_to ( msg, & path1 ) ) ;
1189
+ or_panic ! ( sock2. send ( msg) ) ;
1162
1190
let mut buf = [ 0 ; 11 ] ;
1163
1191
let size = or_panic ! ( sock1. recv( & mut buf) ) ;
1164
1192
assert_eq ! ( size, 11 ) ;
1165
1193
assert_eq ! ( msg, & buf[ ..] ) ;
1166
1194
}
1195
+
1196
+ #[ test]
1197
+ fn datagram_pair ( ) {
1198
+ let msg1 = b"hello" ;
1199
+ let msg2 = b"world!" ;
1200
+
1201
+ let ( s1, s2) = or_panic ! ( UnixDatagram :: pair( ) ) ;
1202
+ let thread = thread:: spawn ( move || {
1203
+ // s1 must be moved in or the test will hang!
1204
+ let mut buf = [ 0 ; 5 ] ;
1205
+ or_panic ! ( s1. recv( & mut buf) ) ;
1206
+ assert_eq ! ( & msg1[ ..] , & buf[ ..] ) ;
1207
+ or_panic ! ( s1. send( msg2) ) ;
1208
+ } ) ;
1209
+
1210
+ or_panic ! ( s2. send( msg1) ) ;
1211
+ let mut buf = [ 0 ; 6 ] ;
1212
+ or_panic ! ( s2. recv( & mut buf) ) ;
1213
+ assert_eq ! ( & msg2[ ..] , & buf[ ..] ) ;
1214
+ drop ( s2) ;
1215
+
1216
+ thread. join ( ) . unwrap ( ) ;
1217
+ }
1167
1218
}
0 commit comments