@@ -589,16 +589,65 @@ def fromshare(info):
589
589
return socket (0 , 0 , 0 , info )
590
590
__all__ .append ("fromshare" )
591
591
592
- if hasattr (_socket , "socketpair" ):
592
+ # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
593
+ # This is used if _socket doesn't natively provide socketpair. It's
594
+ # always defined so that it can be patched in for testing purposes.
595
+ def _fallback_socketpair (family = AF_INET , type = SOCK_STREAM , proto = 0 ):
596
+ if family == AF_INET :
597
+ host = _LOCALHOST
598
+ elif family == AF_INET6 :
599
+ host = _LOCALHOST_V6
600
+ else :
601
+ raise ValueError ("Only AF_INET and AF_INET6 socket address families "
602
+ "are supported" )
603
+ if type != SOCK_STREAM :
604
+ raise ValueError ("Only SOCK_STREAM socket type is supported" )
605
+ if proto != 0 :
606
+ raise ValueError ("Only protocol zero is supported" )
607
+
608
+ # We create a connected TCP socket. Note the trick with
609
+ # setblocking(False) that prevents us from having to create a thread.
610
+ lsock = socket (family , type , proto )
611
+ try :
612
+ lsock .bind ((host , 0 ))
613
+ lsock .listen ()
614
+ # On IPv6, ignore flow_info and scope_id
615
+ addr , port = lsock .getsockname ()[:2 ]
616
+ csock = socket (family , type , proto )
617
+ try :
618
+ csock .setblocking (False )
619
+ try :
620
+ csock .connect ((addr , port ))
621
+ except (BlockingIOError , InterruptedError ):
622
+ pass
623
+ csock .setblocking (True )
624
+ ssock , _ = lsock .accept ()
625
+ except :
626
+ csock .close ()
627
+ raise
628
+ finally :
629
+ lsock .close ()
593
630
594
- def socketpair (family = None , type = SOCK_STREAM , proto = 0 ):
595
- """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
631
+ # Authenticating avoids using a connection from something else
632
+ # able to connect to {host}:{port} instead of us.
633
+ # We expect only AF_INET and AF_INET6 families.
634
+ try :
635
+ if (
636
+ ssock .getsockname () != csock .getpeername ()
637
+ or csock .getsockname () != ssock .getpeername ()
638
+ ):
639
+ raise ConnectionError ("Unexpected peer connection" )
640
+ except :
641
+ # getsockname() and getpeername() can fail
642
+ # if either socket isn't connected.
643
+ ssock .close ()
644
+ csock .close ()
645
+ raise
596
646
597
- Create a pair of socket objects from the sockets returned by the platform
598
- socketpair() function.
599
- The arguments are the same as for socket() except the default family is
600
- AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
601
- """
647
+ return (ssock , csock )
648
+
649
+ if hasattr (_socket , "socketpair" ):
650
+ def socketpair (family = None , type = SOCK_STREAM , proto = 0 ):
602
651
if family is None :
603
652
try :
604
653
family = AF_UNIX
@@ -610,61 +659,7 @@ def socketpair(family=None, type=SOCK_STREAM, proto=0):
610
659
return a , b
611
660
612
661
else :
613
-
614
- # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
615
- def socketpair (family = AF_INET , type = SOCK_STREAM , proto = 0 ):
616
- if family == AF_INET :
617
- host = _LOCALHOST
618
- elif family == AF_INET6 :
619
- host = _LOCALHOST_V6
620
- else :
621
- raise ValueError ("Only AF_INET and AF_INET6 socket address families "
622
- "are supported" )
623
- if type != SOCK_STREAM :
624
- raise ValueError ("Only SOCK_STREAM socket type is supported" )
625
- if proto != 0 :
626
- raise ValueError ("Only protocol zero is supported" )
627
-
628
- # We create a connected TCP socket. Note the trick with
629
- # setblocking(False) that prevents us from having to create a thread.
630
- lsock = socket (family , type , proto )
631
- try :
632
- lsock .bind ((host , 0 ))
633
- lsock .listen ()
634
- # On IPv6, ignore flow_info and scope_id
635
- addr , port = lsock .getsockname ()[:2 ]
636
- csock = socket (family , type , proto )
637
- try :
638
- csock .setblocking (False )
639
- try :
640
- csock .connect ((addr , port ))
641
- except (BlockingIOError , InterruptedError ):
642
- pass
643
- csock .setblocking (True )
644
- ssock , _ = lsock .accept ()
645
- except :
646
- csock .close ()
647
- raise
648
- finally :
649
- lsock .close ()
650
-
651
- # Authenticating avoids using a connection from something else
652
- # able to connect to {host}:{port} instead of us.
653
- # We expect only AF_INET and AF_INET6 families.
654
- try :
655
- if (
656
- ssock .getsockname () != csock .getpeername ()
657
- or csock .getsockname () != ssock .getpeername ()
658
- ):
659
- raise ConnectionError ("Unexpected peer connection" )
660
- except :
661
- # getsockname() and getpeername() can fail
662
- # if either socket isn't connected.
663
- ssock .close ()
664
- csock .close ()
665
- raise
666
-
667
- return (ssock , csock )
662
+ socketpair = _fallback_socketpair
668
663
__all__ .append ("socketpair" )
669
664
670
665
socketpair .__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
0 commit comments