@@ -4,7 +4,7 @@ use std::{
44 ffi:: CString ,
55 io,
66 marker:: PhantomPinned ,
7- os:: fd:: { FromRawFd , OwnedFd } ,
7+ os:: fd:: { FromRawFd , IntoRawFd , OwnedFd } ,
88 pin:: Pin ,
99 task:: Poll ,
1010} ;
@@ -20,7 +20,7 @@ use libc::open64 as open;
2020use libc:: { pread, preadv, pwrite, pwritev} ;
2121#[ cfg( any( target_os = "linux" , target_os = "android" , target_os = "hurd" ) ) ]
2222use libc:: { pread64 as pread, preadv64 as preadv, pwrite64 as pwrite, pwritev64 as pwritev} ;
23- use socket2:: SockAddr ;
23+ use socket2:: { SockAddr , Socket as Socket2 } ;
2424
2525use super :: { AsRawFd , Decision , OpCode , OpType , sockaddr_storage, socklen_t, syscall} ;
2626pub use crate :: unix:: op:: * ;
@@ -467,15 +467,73 @@ impl OpCode for HardLink {
467467 }
468468}
469469
470+ impl CreateSocket {
471+ unsafe fn call ( self : Pin < & mut Self > ) -> io:: Result < libc:: c_int > {
472+ #[ allow( unused_mut) ]
473+ let mut ty: i32 = self . socket_type ;
474+ #[ cfg( any(
475+ target_os = "android" ,
476+ target_os = "dragonfly" ,
477+ target_os = "freebsd" ,
478+ target_os = "fuchsia" ,
479+ target_os = "hurd" ,
480+ target_os = "illumos" ,
481+ target_os = "linux" ,
482+ target_os = "netbsd" ,
483+ target_os = "openbsd" ,
484+ target_os = "cygwin" ,
485+ ) ) ]
486+ {
487+ ty |= libc:: SOCK_CLOEXEC | libc:: SOCK_NONBLOCK ;
488+ }
489+ let fd = syscall ! ( libc:: socket( self . domain, ty, self . protocol) ) ?;
490+ let socket = Socket2 :: from_raw_fd ( fd) ;
491+ #[ cfg( not( any(
492+ target_os = "android" ,
493+ target_os = "dragonfly" ,
494+ target_os = "freebsd" ,
495+ target_os = "fuchsia" ,
496+ target_os = "hurd" ,
497+ target_os = "illumos" ,
498+ target_os = "linux" ,
499+ target_os = "netbsd" ,
500+ target_os = "openbsd" ,
501+ target_os = "espidf" ,
502+ target_os = "vita" ,
503+ target_os = "cygwin" ,
504+ ) ) ) ]
505+ socket. set_cloexec ( true ) ?;
506+ #[ cfg( any(
507+ target_os = "ios" ,
508+ target_os = "macos" ,
509+ target_os = "tvos" ,
510+ target_os = "watchos" ,
511+ ) ) ]
512+ socket. set_nosigpipe ( true ) ?;
513+ #[ cfg( not( any(
514+ target_os = "android" ,
515+ target_os = "dragonfly" ,
516+ target_os = "freebsd" ,
517+ target_os = "fuchsia" ,
518+ target_os = "hurd" ,
519+ target_os = "illumos" ,
520+ target_os = "linux" ,
521+ target_os = "netbsd" ,
522+ target_os = "openbsd" ,
523+ target_os = "cygwin" ,
524+ ) ) ) ]
525+ socket. set_nonblocking ( true ) ?;
526+ Ok ( socket. into_raw_fd ( ) )
527+ }
528+ }
529+
470530impl OpCode for CreateSocket {
471531 fn pre_submit ( self : Pin < & mut Self > ) -> io:: Result < Decision > {
472532 Ok ( Decision :: Blocking )
473533 }
474534
475535 fn operate ( self : Pin < & mut Self > ) -> Poll < io:: Result < usize > > {
476- Poll :: Ready ( Ok (
477- syscall ! ( libc:: socket( self . domain, self . socket_type, self . protocol) ) ? as _ ,
478- ) )
536+ Poll :: Ready ( Ok ( unsafe { self . call ( ) ? } as _ ) )
479537 }
480538}
481539
@@ -504,11 +562,50 @@ impl OpCode for CloseSocket {
504562impl < S : AsRawFd > Accept < S > {
505563 unsafe fn call ( self : Pin < & mut Self > ) -> libc:: c_int {
506564 let this = self . get_unchecked_mut ( ) ;
507- libc:: accept (
508- this. fd . as_raw_fd ( ) ,
509- & mut this. buffer as * mut _ as * mut _ ,
510- & mut this. addr_len ,
511- )
565+ #[ cfg( any(
566+ target_os = "android" ,
567+ target_os = "dragonfly" ,
568+ target_os = "freebsd" ,
569+ target_os = "fuchsia" ,
570+ target_os = "illumos" ,
571+ target_os = "linux" ,
572+ target_os = "netbsd" ,
573+ target_os = "openbsd" ,
574+ target_os = "cygwin" ,
575+ ) ) ]
576+ {
577+ libc:: accept4 (
578+ this. fd . as_raw_fd ( ) ,
579+ & mut this. buffer as * mut _ as * mut _ ,
580+ & mut this. addr_len ,
581+ libc:: SOCK_NONBLOCK | libc:: SOCK_CLOEXEC ,
582+ )
583+ }
584+ #[ cfg( not( any(
585+ target_os = "android" ,
586+ target_os = "dragonfly" ,
587+ target_os = "freebsd" ,
588+ target_os = "fuchsia" ,
589+ target_os = "illumos" ,
590+ target_os = "linux" ,
591+ target_os = "netbsd" ,
592+ target_os = "openbsd" ,
593+ target_os = "cygwin" ,
594+ ) ) ) ]
595+ {
596+ || -> io:: Result < libc:: c_int > {
597+ let fd = syscall ! ( libc:: accept(
598+ this. fd. as_raw_fd( ) ,
599+ & mut this. buffer as * mut _ as * mut _,
600+ & mut this. addr_len,
601+ ) ) ?;
602+ let socket = Socket2 :: from_raw_fd ( fd) ;
603+ socket. set_cloexec ( true ) ?;
604+ socket. set_nonblocking ( true ) ?;
605+ Ok ( socket. into_raw_fd ( ) )
606+ } ( )
607+ . unwrap_or ( -1 )
608+ }
512609 }
513610}
514611
0 commit comments