1
- use std:: { mem, ptr} ;
1
+ use std:: { mem, ptr, fmt } ;
2
2
use libc:: { c_void, c_int, socklen_t, size_t} ;
3
3
use fcntl:: { Fd , fcntl, F_SETFL , F_SETFD , FD_CLOEXEC , O_NONBLOCK } ;
4
4
use errno:: { SysResult , SysError , from_ffi} ;
5
5
use features;
6
6
7
- pub use libc:: { in_addr, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, sa_family_t, ip_mreq} ;
7
+ pub use libc:: { in_addr, sockaddr, sockaddr_storage , sockaddr_in, sockaddr_in6, sockaddr_un, sa_family_t, ip_mreq} ;
8
8
9
9
pub use self :: consts:: * ;
10
10
@@ -120,6 +120,12 @@ mod consts {
120
120
pub const INADDR_ANY : InAddrT = 0 ;
121
121
pub const INADDR_NONE : InAddrT = 0xffffffff ;
122
122
pub const INADDR_BROADCAST : InAddrT = 0xffffffff ;
123
+
124
+ pub type SockMessageFlags = i32 ;
125
+ // Flags for send/recv and their relatives
126
+ pub const MSG_OOB : SockMessageFlags = 0x1 ;
127
+ pub const MSG_PEEK : SockMessageFlags = 0x2 ;
128
+ pub const MSG_DONTWAIT : SockMessageFlags = 0x40 ;
123
129
}
124
130
125
131
#[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ]
@@ -324,9 +330,7 @@ mod sa_helpers {
324
330
}
325
331
}
326
332
327
- pub fn recvfrom ( sockfd : Fd , buf : & mut [ u8 ] , addr : & mut SockAddr ) -> SysResult < uint > {
328
- use libc:: sockaddr_storage;
329
-
333
+ pub fn recvfrom ( sockfd : Fd , buf : & mut [ u8 ] ) -> SysResult < ( uint , SockAddr ) > {
330
334
let mut saddr : sockaddr_storage = unsafe { mem:: zeroed ( ) } ;
331
335
let mut len = mem:: size_of :: < sockaddr_storage > ( ) as socklen_t ;
332
336
@@ -338,24 +342,51 @@ pub fn recvfrom(sockfd: Fd, buf: &mut [u8], addr: &mut SockAddr) -> SysResult<ui
338
342
return Err ( SysError :: last ( ) ) ;
339
343
}
340
344
341
- match saddr. ss_family as i32 {
342
- AF_INET => { * addr = sa_helpers:: to_sockaddr_ipv4 ( & saddr) ; } ,
343
- AF_INET6 => { * addr = sa_helpers:: to_sockaddr_ipv6 ( & saddr) ; } ,
344
- AF_UNIX => { * addr = sa_helpers:: to_sockaddr_unix ( & saddr) ; } ,
345
- _ => unimplemented ! ( )
346
- }
345
+ Ok ( ( ret as uint ,
346
+ match saddr. ss_family as i32 {
347
+ AF_INET => { sa_helpers:: to_sockaddr_ipv4 ( & saddr) } ,
348
+ AF_INET6 => { sa_helpers:: to_sockaddr_ipv6 ( & saddr) } ,
349
+ AF_UNIX => { sa_helpers:: to_sockaddr_unix ( & saddr) } ,
350
+ _ => unimplemented ! ( )
351
+ }
352
+ ) )
353
+ }
354
+
355
+ fn print_ipv4_addr ( sin : & sockaddr_in , f : & mut fmt:: Formatter ) -> fmt:: Result {
356
+ let ip_addr = Int :: from_be ( sin. sin_addr . s_addr ) ;
357
+ let port = Int :: from_be ( sin. sin_port ) ;
358
+
359
+ write ! ( f, "{}.{}.{}.{}:{}" ,
360
+ ( ip_addr >> 24 ) & 0xff ,
361
+ ( ip_addr >> 16 ) & 0xff ,
362
+ ( ip_addr >> 8 ) & 0xff ,
363
+ ( ip_addr) & 0xff ,
364
+ port)
365
+ }
347
366
348
- Ok ( ret as uint )
367
+ impl fmt:: Show for SockAddr {
368
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
369
+ match * self {
370
+ SockIpV4 ( sin) => print_ipv4_addr ( & sin, f) ,
371
+ _ => unimplemented ! ( )
372
+ }
373
+ }
349
374
}
350
375
351
- pub fn sendto ( sockfd : Fd , buf : & [ u8 ] , addr : & SockAddr ) -> SysResult < uint > {
352
- let len = match * addr {
353
- SockIpV4 ( _) => mem:: size_of :: < sockaddr_in > ( ) ,
354
- SockIpV6 ( _) => mem:: size_of :: < sockaddr_in6 > ( ) ,
355
- SockUnix ( _) => mem:: size_of :: < sockaddr_un > ( ) ,
356
- } as socklen_t ;
376
+ ///
377
+ /// Generic wrapper around sendto
378
+ fn sendto_sockaddr < T > ( sockfd : Fd , buf : & [ u8 ] , flags : SockMessageFlags , addr : & T ) -> i64 {
379
+ unsafe {
380
+ ffi:: sendto ( sockfd, buf. as_ptr ( ) as * const c_void , buf. len ( ) as size_t , flags, mem:: transmute ( addr) , mem:: size_of :: < T > ( ) as socklen_t )
381
+ }
382
+ }
357
383
358
- let ret = unsafe { ffi:: sendto ( sockfd, buf. as_ptr ( ) as * const c_void , buf. len ( ) as size_t , 0 , mem:: transmute ( addr) , len as socklen_t ) } ;
384
+ pub fn sendto ( sockfd : Fd , buf : & [ u8 ] , addr : & SockAddr , flags : SockMessageFlags ) -> SysResult < uint > {
385
+ let ret = match * addr {
386
+ SockIpV4 ( ref addr) => sendto_sockaddr ( sockfd, buf, flags, addr) ,
387
+ SockIpV6 ( ref addr) => sendto_sockaddr ( sockfd, buf, flags, addr) ,
388
+ SockUnix ( ref addr) => sendto_sockaddr ( sockfd, buf, flags, addr) ,
389
+ } ;
359
390
360
391
if ret < 0 {
361
392
Err ( SysError :: last ( ) )
0 commit comments