@@ -87,6 +87,12 @@ def _set_reuseport(sock):
87
87
'SO_REUSEPORT defined but not implemented.' )
88
88
89
89
90
+ def _copy_and_detach_socket (sock ):
91
+ new_sock = socket .socket (sock .family , sock .type , sock .proto , sock .fileno ())
92
+ sock .detach ()
93
+ return new_sock
94
+
95
+
90
96
# Linux's sock.type is a bitmask that can include extra info about socket.
91
97
_SOCKET_TYPE_MASK = 0
92
98
if hasattr (socket , 'SOCK_NONBLOCK' ):
@@ -768,9 +774,11 @@ def create_connection(self, protocol_factory, host=None, port=None, *,
768
774
raise OSError ('Multiple exceptions: {}' .format (
769
775
', ' .join (str (exc ) for exc in exceptions )))
770
776
771
- elif sock is None :
772
- raise ValueError (
773
- 'host and port was not specified and no sock specified' )
777
+ else :
778
+ if sock is None :
779
+ raise ValueError (
780
+ 'host and port was not specified and no sock specified' )
781
+ sock = _copy_and_detach_socket (sock )
774
782
775
783
transport , protocol = yield from self ._create_connection_transport (
776
784
sock , protocol_factory , ssl , server_hostname )
@@ -827,6 +835,7 @@ def create_datagram_endpoint(self, protocol_factory,
827
835
raise ValueError (
828
836
'socket modifier keyword arguments can not be used '
829
837
'when sock is specified. ({})' .format (problems ))
838
+ sock = _copy_and_detach_socket (sock )
830
839
sock .setblocking (False )
831
840
r_addr = None
832
841
else :
@@ -1024,6 +1033,7 @@ def create_server(self, protocol_factory, host=None, port=None,
1024
1033
else :
1025
1034
if sock is None :
1026
1035
raise ValueError ('Neither host/port nor sock were specified' )
1036
+ sock = _copy_and_detach_socket (sock )
1027
1037
sockets = [sock ]
1028
1038
1029
1039
server = Server (self , sockets )
@@ -1045,6 +1055,7 @@ def connect_accepted_socket(self, protocol_factory, sock, *, ssl=None):
1045
1055
This method is a coroutine. When completed, the coroutine
1046
1056
returns a (transport, protocol) pair.
1047
1057
"""
1058
+ sock = _copy_and_detach_socket (sock )
1048
1059
transport , protocol = yield from self ._create_connection_transport (
1049
1060
sock , protocol_factory , ssl , '' , server_side = True )
1050
1061
if self ._debug :
0 commit comments