
    G                        S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSr	\R                  S:X  a   SSK	r	Sr\R                  \R                  4\R                  \R                   4/r\" 5       r\" 5       r\" 5       r " S S\5      rS rS	 rS
 rS\R6                  4S jrS rSS jrSS jr  SS jr S r!SS jr"S r#S r$SS jr%\r&\%r'\r(\r)S r*\+S:X  a  \*" \RX                  5        gg! \ a    Sr	 Nf = f)ah  Pure python code for finding unused ports on a host.

This module provides a pick_unused_port() function.
It can also be called via the command line for use in shell scripts.
When called from the command line, it takes one optional argument, which,
if given, is sent to portserver instead of portpicker's PID.
To reserve a port for the lifetime of a bash script, use $BASHPID as this
argument.

There is a race condition between picking a port and your application code
binding to it.  The use of a port server to prevent that is recommended on
loaded test hosts running many tests at a time.

If your code can accept a bound socket as input rather than being handed a
port number consider using socket.bind(('localhost', 0)) to bind to an
available port without a race condition rather than using this library.

Typical usage:
  test_port = portpicker.pick_unused_port()
    )print_functionNwin32)bindis_port_freepick_unused_portreturn_portadd_reserved_portget_port_from_port_serverc                       \ rS rSrSrSrg)NoFreePortFoundErrorK   z6Exception indicating that no free port could be found. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       &lib/third_party/portpicker/__init__.pyr   r   K   s    @r   r   c                 .    [         R                  U 5        g)zAAdd a port that was acquired by means other than the port server.N)_free_portsaddports    r   r	   r	   O   s    OODr   c                     U [         ;   a  [         R                  U 5        gU [        ;   a+  [        R                  U 5        [        R	                  U 5        gU [        ;   a  [
        R                  " SU 5        g[
        R                  " SU 5        g)z?Return a port that is no longer being used so it can be reused.z.Returning a port that was already returned: %sz4Returning a port that wasn't given by portpicker: %sN)_random_portsremove_owned_portsr   r   logginginfor   s    r   r   r   T   sc    }T"		D!		EtLK	r   c                     [        XU5      $ )a\  Try to bind to a socket of the specified type, protocol, and port.

This is primarily a helper function for PickUnusedPort, used to see
if a particular port number is available.

For the port to be considered available, the kernel must support at least
one of (IPv6, IPv4), and the port must be available on each supported
family.

Args:
  port: The port number to bind to, or 0 to have the OS pick a free port.
  socket_type: The type of the socket (ex: socket.SOCK_STREAM).
  socket_proto: The protocol of the socket (ex: socket.IPPROTO_TCP).

Returns:
  The port number on success or None on failure.
)_bind)r   socket_typesocket_protos      r   r   r   b   s    $ L11r   c                    Ub  U[         R                  :X  a!  [         R                  [         R                  4nOCU[         R                  :X  a!  [         R                  [         R                  4nO[        SU-  5      eSnU H  n [         R                   " XqU5      nSn UR                  [         R                  [         R                  S5        UR                  SU 45        U[         R                  :X  a  UR                  S5        UR                  5       S   n  Ub  Xt:w  a0   UR                  [         R                  5        UR                  5         Uc  M  Xt:X  d  M  UR!                  U5          O   U(       a  U $ S$ ! [         R                   a     GM  f = f! [         R                   aO     Ub  Xt:w  aC   UR                  [         R                  5        O! [         a     Of = fUR                  5           g  gf = f! [         a     Nf = f! Ub  Xt:w  aB   UR                  [         R                  5        O! [         a     Of = fUR                  5         f f = f)aK  Internal implementation of bind.

Args:
  port, socket_type, socket_proto: see bind().
  return_socket: If supplied, a list that we will append an open bound
      reuseaddr socket on the port in question to.
  return_family: The socket family to return in return_socket.

Returns:
  The port number on success or None on failure.
Nzunknown return_family %sFT    )socketAF_INETAF_INET6
ValueErrorerror
setsockopt
SOL_SOCKETSO_REUSEADDRr   SOCK_STREAMlistengetsocknameshutdown	SHUT_RDWROSErrorcloseappend)	r   r$   r%   return_socketreturn_familysocket_families
got_socketfamilysocks	            r   r#   r#   w   s      ?!??FNN;	&//	)!>>6??;3mCDDJ!	==lCDJ	OOF--v/B/BAFIIr4j!f000A##%a(D $(?
 MM&"2"23 

$)@  &7 "8 4'4'1 || 		 || 	$(?
 MM&"2"23 

 )@	   $(?
 MM&"2"23 

 )@s   E=A:F"G?=FFG<-H7G
G$#G$;G<<H?
HH	IH98I9
I	II	Ic                     [        U 5      $ )zCheck if specified port is free.

Args:
  port: integer, port to check

Returns:
  bool, whether port is free to use for both TCP and UDP.
)_is_port_freer   s    r   r   r      s     r   c                 h    [        U /[        S   Q7SU06=(       a    [        U /[        S   Q7SU06$ )a  Internal implementation of is_port_free.

Args:
  port: integer, port to check
  return_sockets: If supplied, a list that we will append open bound
    sockets on the port in question to rather than closing them.

Returns:
  bool, whether port is free to use for both TCP and UDP.
r   r9   r'   )r#   _PROTOS)r   return_socketss     r   r@   r@      s<     $BB>B C$BB>BDr   c                     [        X5      $ )a  Picks an unused port and reserves it for use by a given process id.

Args:
  pid: PID to tell the portserver to associate the reservation with. If
    None, the current process's PID is used.
  portserver_address: The address (path) of a unix domain socket
    with which to connect to a portserver, a leading '@'
    character indicates an address in the "abstract namespace".  OR
    On systems without socket.AF_UNIX, this is an AF_INET address.
    If None, or no port is returned by the portserver at the provided
    address, the environment will be checked for a PORTSERVER_ADDRESS
    variable.  If that is not set, no port server will be used.

If no portserver is used, no pid based reservation is managed by any
central authority. Race conditions and duplicate assignments may occur.

Returns:
  A port number that is unused on both TCP and UDP.

Raises:
  NoFreePortFoundError: No free port could be found.
)_pick_unused_port)pidportserver_addresss     r   r   r      s    . S55r   c                 .    [         R                  5       n[        R                  U5        U$ ! [         a     Of = fU(       a  [        XS9nU(       a  U$ S[        R                  ;   a$  [        [        R                  S   U S9nU(       a  U$ [        US9$ )a  Internal implementation of pick_unused_port.

Args:
  pid, portserver_address: See pick_unused_port().
  noserver_bind_timeout: If no portserver was used, this is the number of
    seconds we will attempt to keep a child process around with the ports
    returned open and bound SO_REUSEADDR style to help avoid race condition
    port reuse. A non-zero value attempts os.fork(). Do not use it in a
    multithreaded process.
)rF   PORTSERVER_ADDRESS)bind_timeout)	r   popr   r   KeyErrorr
   osenviron _pick_unused_port_without_server)rF   rG   noserver_bind_timeoutr   s       r   rE   rE      s      		   ();EKrzz)(4H)I-02K+9NOOs   - 
::c           	         U(       Ga  US:  a   [         R                  " 5       nUS:X  a   [         R                  " [        R                  R                  5       5        [         R                  " [        R                  R                  5       5        [         R                  " [        R                  R                  5       5        [        R                  " U5        U H  nUR                  5         M     [         R                  " S5        gggg! [         R                  " S5        f = f! [         a%  n[        SU SU[        R                  S9   SnAgSnAff = f)a  If possible, fork()s a daemon process to hold bound_sockets open.

Emits a warning to stderr if it cannot.

Args:
  port: The port number the sockets are bound to (informational).
  bound_sockets: The list of bound sockets our child process will hold
      open. If the list is empty, no action is taken.
  timeout: A positive number of seconds the child should sleep for before
      closing the sockets and exiting.
r   z/WARNING: Cannot timeout unbinding close of portz closing on exit. -fileN)rM   forkr7   sysstdinfilenostdoutstderrtimesleep_exit	Exceptionprint)r   bound_socketstimeoutfork_pidheld_socketerrs         r    _spawn_bound_port_holding_daemonrd     s     1	 wwyH
 1}  HHSYY--/0HHSZZ..01HHSZZ..01JJw''4#))+ (5 HHQK  %}* HHQK%  	?CT'3::?	?s#   D& CD D#&
E0EEc                    SnU S:  a  / OSn[        S5       H  n[        S[        R                  [        R                  U5      nU(       a^  U[
        ;  aT  [        U[        R                  [        R                  U5      (       a%  [
        R                  U5        [        XU 5        Us  $ U(       d  M  U H  nUR                  5         M     USS2	 M     [        R                  " 5       n[        S5       H  n[        UR                  SS5      5      nU[
        ;  d  M*  [        X5      (       a%  [
        R                  U5        [        XU 5        Us  $ U(       d  Mh  U H  nUR                  5         M     USS2	 M     [!        5       e)a9  Pick an available network port without the help of a port server.

This code ensures that the port is available on both TCP and UDP.

This function is an implementation detail of PickUnusedPort(), and
should not be called by code outside of this module.

Args:
  bind_timeout: number of seconds to attempt to keep a child process
      process around bound SO_REUSEADDR style to the port. If we cannot
      do that we emit a warning to stderr.

Returns:
  A port number that is unused on both TCP and UDP.

Raises:
  NoFreePortFoundError: No free port could be found.
Nr   
   i:  ia  )ranger#   r)   r1   IPPROTO_TCPr   
SOCK_DGRAMIPPROTO_UDPr   rd   r7   randomRandomint	randranger@   r   )rJ   r   r_   _rb   rngs         r   rO   rO   &  s9   , D&*BM2YQ**F,>,>NT.$))6+=+=}MMd#,T,OK=,!!#  -a   --/C2Y3==./}$T11!!$'0\;}#0K%%' $1!!$  
  r   c                 h   U S   S:X  a  SU SS  -   n  [        [        S5      (       a4  [        R                  " [        R                  [        R                  5      nO3[        R                  " [        R                  [        R                  5      n UR                  U 5        UR                  SU-  R                  S5      5        UR                  S5      UR                  5         $ ! UR                  5         f = f! [        R                   a#  n[        S	U[        R                  S
9   S nAg S nAff = f)Nr   @ r'   AF_UNIX%d
asciii   z+Socket error when connecting to portserver:rR   )hasattrr)   rt   r1   r*   connectsendallencoderecvr7   r-   r^   rU   rY   )rG   rF   r>   r-   s       r    _posix_get_port_from_port_serverr|   _  s    
 !#!$6qr$::69%%==1C1CDD ==1C1CDD	LL+, LL&3,..w78 99T?JJLDJJL<< ;U::	s1   A<C: AC% C: %C77C: :D1D,,D1c           	         U S   S:X  a  SU SS  -   n  [         R                  " U [         R                  [         R                  -  SS[         R                  SS5      n[         R
                  " USU-  R                  S5      5        [         R                  " USS5      u  p4U$ ! [         a#  n[        SU[        R                  S	9   S nAg S nAff = f)
Nr   rr   z	\\.\pipe\r'   ru   rv      z)File error when connecting to portserver:rR   )_winapi
CreateFileGENERIC_READGENERIC_WRITEOPEN_EXISTING	WriteFilerz   ReadFileFileNotFoundErrorr^   rU   rY   )rG   rF   handledataro   r-   s         r   "_windows_get_port_from_port_serverr     s    !#,/A!"/EE##  7#8#88!! 	&6C<"7"7"@A""61a0 95::	s   BB! !
C+C		Cc                 H   U (       d  gUc  [         R                  " 5       n[        (       a  [        X5      nO[	        X5      nUc  g [        UR                  S5      S   5      n[        R                  U5        U$ ! [         a    [        S[        R                  S9   gf = f)a!  Request a free a port from a system-wide portserver.

This follows a very simple portserver protocol:
The request consists of our pid (in ASCII) followed by a newline.
The response is a port number and a newline, 0 on failure.

This function is an implementation detail of pick_unused_port().
It should not normally be called by code outside of this module.

Args:
  portserver_address: The address (path) of a unix domain socket
    with which to connect to the portserver.  A leading '@'
    character indicates an address in the "abstract namespace."
    On systems without socket.AF_UNIX, this is an AF_INET address.
  pid: The PID to tell the portserver to associate the reservation with.
    If None, the current process's PID is used.

Returns:
  The port number on success or None on failure.
N   
r   z!Portserver failed to find a port.rR   )rM   getpidr   r   r|   rm   splitr,   r^   rU   rY   r   r   )rG   rF   bufr   s       r   r
   r
     s    * 
{iikw01CI./AG
{399U#A&' TK	  1

Cs   A< <"B! B!c                    SU ;   d  SU ;   aG  [        U S   S5        SSKn[        UR                  [        5      5        [        R
                  " S5        [        U 5      S:  a  [        U S   5      O[        R                  " 5       n[        U 5      S:  a  [        U S   5      OSn[        X#S9nU(       d  [        R
                  " S5        [        U5        g)	a  If passed an arg, treat it as a PID, otherwise we use getppid().

A second optional argument can be a bind timeout in seconds that will be
used ONLY if no portserver is found. We attempt to leave a process around
holding the port open and bound with SO_REUSEADDR set for timeout seconds.
If the timeout bind was not possible, a warning is emitted to stderr.

  #!/bin/bash
  port="$(python -m portpicker $$ 1.23)"
  test_my_server "$port"

This will pick a port for your script's PID and assign it to $port, if no
portserver was used, it attempts to keep a socket bound to $port for 1.23
seconds after the portpicker process has exited. This is a convenient hack
to attempt to prevent port reallocation during scripts outside of
portserver managed environments.

Older versions of the portpicker CLI ignore everything beyond the first arg.
Older versions also used getpid() instead of getppid(), so script users are
strongly encouraged to be explicit and pass $$ or your languages equivalent
to associate the port with the PID of the controlling process.
z-hz--helpr   zusage:
Nr'      )rF   rP   )r^   inspectgetdocmainrU   exitlenrm   rM   getppidfloatrE   )argvr   rF   rJ   r   s        r   r   r     s    2 t|x4'd1gz"gnnT"#D	ADG2::<C#&t9q=tAwaLID	$Kr   __main__)N)NN)NNr   )r   )-r   
__future__r   r    rM   rk   r)   rU   rZ   r   platformImportError__all__r1   rh   ri   rj   rB   setr   r   r   r]   r   r	   r   r   r+   r#   r   r@   r   rE   rd   rO   r|   r   r
   BindGetPortFromPortServer
IsPortFreePickUnusedPortr   r   r   r   r   r   <module>r      sF  "0 &  	   
 
<<7
=  2 23v1124
 e u A9 A
2* :>3(l	D64 48+,P@! H6!rB.)\ 1 
!#L zN y  s   C0 0C;:C;