o
    f                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dlm	Z	 d dlm
Z
 d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZmZ d dlmZ d dlmZ d dlmZ d dlm Z  ej!G dd de"Z#G dd de#Z$ej!G dd de"Z%G dd de%Z&G dd de&Z'G dd de%Z(G dd de"Z)e) Z)d d! Z*dS )"    N)maxint)as_bytes)	as_string)PY2)asyncore_25)ProcessStates)SupervisorStates)getProcessStateDescription)STOPPED_STATES)decode_wait_status)signame)ProcessException
BadCommand)EventListenerStates)events)RestartUnconditionally)SocketManagerc                   @   sn  e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZdZdZdZdZdZdZdZdd Zdd Zd	d
 Zdd Zdd Zdd Zejejej ej!ej"ej#ej$ej%ej&ej'ej(ej)ej*ej+ej,ej-iZ.d:ddZ/dd Z0dd Z1dd Z2dd Z3dd Z4dd Z5d d! Z6d"d# Z7d$d% Z8d&d' Z9d(d) Z:d*d+ Z;d,d- Z<d.d/ Z=d0d1 Z>d2d3 Z?d4d5 Z@d6d7 ZAd8d9 ZBdS );
SubprocesszA class to manage a subprocess.r   NFc                 C   s   || _ i | _i | _tj| _dS )zDConstructor.

        Argument is a ProcessConfig instance.
        N)configdispatcherspipesr   STOPPEDstateselfr    r   E/var/www/html/venv/lib/python3.10/site-packages/supervisor/process.py__init__;   s   zSubprocess.__init__c                 C   &   | j  D ]}t|dr|  qd S )N
removelogs)r   valueshasattrr   r   
dispatcherr   r   r   r   E   
   
zSubprocess.removelogsc                 C   r   )N
reopenlogs)r   r    r!   r%   r"   r   r   r   r%   J   r$   zSubprocess.reopenlogsc                 C   s4   | j  D ]}| r|  | r|  qd S N)r   r    readablehandle_read_eventwritablehandle_write_eventr"   r   r   r   drainO   s   zSubprocess.drainc                 C   sl   | j r| jrttjd| jd }|d u rttjd| j| }|jr)ttjd| j|7  _|	  d S )NzProcess already closedstdinzProcess has no stdin channelz Process' stdin channel is closed)
pidkillingOSErrorerrnoEPIPEr   r   closedinput_bufferflush)r   charsstdin_fdr#   r   r   r   writeZ   s   

zSubprocess.writec           	   
   C   s  z	t | jj}W n ty! } ztd| jjt|f d}~ww |r)|d }ntdd|v rH|}z	| jj|}W n< t	yG   d}Y n2w | j
 }d}d}|D ]}tj||}z	| jj|}W n	 t	yn   Y qSw  |du rw|}n|}| jj||| ||fS )zInternal: turn a program name into a file name, using $PATH,
        make sure it exists / is executable, raising a ProcessException
        if not zcan't parse command %r: %sNr   zcommand is empty/)shlexsplitr   command
ValueErrorr   stroptionsstatr/   get_pathospathjoincheck_execv_args)	r   commandargseprogramfilenamestrB   founddirr   r   r   get_execv_argsi   sD   

zSubprocess.get_execv_argsTc                 C   sv   | j }||u r	dS || _ |tjkr"t }|  jd7  _|| j | _| j|}|d ur9|| ||}t	| d S d S )NF   )
r   r   BACKOFFtimebackoffdelay	event_mapgetr   notify)r   	new_stateexpected	old_statenowevent_classeventr   r   r   change_state   s   
zSubprocess.change_statec                 G   sF   | j |vr!t| j }dtt|}t| jj}td|||f d S )N z%Assertion failed for %s: %s not in %s)r   r	   rC   mapr   r   nameAssertionError)r   statescurrent_stateallowable_statesprocessnamer   r   r   _assertInState   s   

zSubprocess._assertInStatec                 C   s   || _ | jjjd|  d S )Nzspawnerr: %s)spawnerrr   r>   loggerinfor   msgr   r   r   record_spawnerr   s   zSubprocess.record_spawnerrc           
   
   C   s<  | j j}t| j j}| jrd| }|j| dS d| _d| _d| _	d| _
d| _t | _| tjtjtjtj | tj z|  \}}W n' tyn } z| |jd  | tj | tj W Y d}~dS d}~ww z| j | \| _| _W n@ ttfy } z2|jd }|tj krd| }nd|tj!"||f }| | | tj | tj W Y d}~dS d}~ww z|# }	W nK ty } z>|jd }|tj$krd| }nd|tj!"||f }| | | tj | tj |%| j |&| j W Y d}~dS d}~ww |	dkr| '|	S | (||S )	zStart the subprocess.  It must not be running already.

        Return the process id.  If the fork() call fails, return None.
        zprocess '%s' already runningNFr   z!too many open files to spawn '%s'z-unknown error making dispatchers for '%s': %sz1Too many processes in process table to spawn '%s'z&unknown error during fork for '%s': %s))r   r>   r   r^   r-   rf   warnr.   re   
exitstatussystem_stopadministrative_stoprO   	laststartrd   r   EXITEDFATALrN   r   r[   STARTINGrL   r   rj   argsmake_dispatchersr   r   r/   IOErrorr0   EMFILE	errorcoderS   forkEAGAINclose_parent_pipesclose_child_pipes_spawn_as_parent_spawn_as_child)
r   r>   rc   ri   rH   argvwhatwhycoder-   r   r   r   spawn   s|   









zSubprocess.spawnc                 C   s\   || _ | jj}|| j |jdt| jj|f  d | _	t

 | jj | _| |j|< |S )Nzspawned: '%s' with pid %s)r-   r   r>   r{   r   rf   rg   r   r^   re   rO   	startsecsrQ   
pidhistory)r   r-   r>   r   r   r   r|     s   
zSubprocess._spawn_as_parentc                 C   sz   | j j}|| jd d || jd d | j jr$|| jd d n	|| jd d td|jD ]}|| q3d S )Nchild_stdinr   child_stdoutrM      child_stderr   )r   r>   dup2r   redirect_stderrrangeminfdsclose_fd)r   r>   ir   r   r   _prepare_child_fds  s   zSubprocess._prepare_child_fdsc              
   C   s  | j j}zE|  |   |  }|r4| j j}d||f }|dd|  W |dd |d d S tj	
 }d|d< | j j}|d u rJ| j jj}|rP||d< | j j|d	< | jr`| jj j|d
< | j jd urm|| j j | j j}	z|	d ur{||	 W n: ty }
 z.tj|
jd |
jd }d|	|f }|dd|  W Y d }
~
W |dd |d d S d }
~
ww z| j jd ur|| j j |||| W na ty }
 z#tj|
jd |
jd }d|d |f }|dd|  W Y d }
~
nEd }
~
w   t \\}}}}}}d||||f }d||f }|dd|  Y W |dd |d d S W |dd |d d S W |dd |d d S |dd |d w )Nzcouldn't setuid to %s: %s
r   zsupervisor: z*supervisor: child process was not spawned
   1SUPERVISOR_ENABLEDSUPERVISOR_SERVER_URLSUPERVISOR_PROCESS_NAMESUPERVISOR_GROUP_NAMEr   zcouldn't chdir to %s: %s
zcouldn't exec %s: %s
z%s, %s: file: %s line: %s)r   r>   setpgrpr   set_uiduidr7   _exitrA   environcopy	serverurlr^   groupenvironmentupdate	directorychdirr/   r0   rw   rS   rs   umasksetumaskexecveasyncorecompact_traceback)r   rH   r~   r>   
setuid_msgr   ri   envr   cwdr   r   filefunlinetvtbinfoerrorr   r   r   r}     s|   	.


zSubprocess._spawn_as_childc                 C   s(  | j tjkr)|| jk r|| _| jdkr%|| j| jj k r'|| jj | _dS dS dS | j tjkrJ|| jkrF|| j| jj k rH|| jj | _dS dS dS | j tjkrs|| j	k rX|| _	| jdkro|| j| jj
 k rq|| jj
 | _dS dS dS | j tjkr| jdkr|| j| j k r|| j | _dS dS dS dS )z
        Check if system clock has rolled backward beyond test_time. If so, set
        affected timestamps to test_time.
        r   N)r   r   rr   ro   rQ   r   r   RUNNINGSTOPPINGlaststopreportstopwaitsecsrN   rP   )r   	test_timer   r   r   +_check_and_adjust_for_system_clock_rollbacke  s*   

z6Subprocess._check_and_adjust_for_system_clock_rollbackc                 C   s   d| _ d| _| | jjS )z Administrative stop Tr   )rn   r   killr   
stopsignalr   r   r   r   stop{  s   zSubprocess.stopc                 C   sZ   | j tjkr)t }| | || jd kr+| jjj	dt
| jj  || _dS dS dS )z8 Log a 'waiting for x to stop' message with throttling. r   zwaiting for %s to stopN)r   r   r   rO   r   r   r   r>   rf   rg   r   r^   )r   rX   r   r   r   stop_report  s   


zSubprocess.stop_reportc                 C   s.   d| _ d| _d| _| tj | tj d S )Nr   T)rQ   rP   rm   rd   r   rN   r[   rq   r   r   r   r   give_up  s
   zSubprocess.give_upc              
   C   s  t   }| jj}t| jj}| jtjkr&d| }|j	| | 
tj dS | js9d|t|f }|j	| |S | jtjkrD| jj}n| jj}d}|rNd}|j	d|| j|t|f  d| _|| jj | _| tjtjtj | 
tj | j}|r| j }z6z
||| W W dS  ty }	 z|	jtjkrd|| jt|	f }|j	| W Y d}	~	W dS  d}	~	ww    t }
d	|| j|
f }|j| | 
tj d
| _d| _| Y S )a  Send a signal to the subprocess with the intention to kill
        it (to make it exit).  This may or may not actually kill it.

        Return None if the signal was sent, or an error message string
        if an error occurred or if the subprocess is not running.
        z0Attempted to kill %s, which is in BACKOFF state.Nz6attempted to kill %s with sig %s but it wasn't running zprocess group z$killing %s (pid %s) %swith signal %sTzDunable to signal %s (pid %s), it probably just exited on its own: %sz"unknown problem killing %s (%s):%sFr   ) rO   r   r>   r   r^   r   r   rN   rf   debugr[   r   r-   r   r   killasgroupstopasgroupr.   r   rQ   rd   r   rr   r   r/   r0   ESRCHr=   	traceback
format_exccriticalUNKNOWN)r   sigrX   r>   rc   ri   r   as_groupr-   exctbr   r   r   r     s~   

	zSubprocess.killc              
   C   s  | j j}t| j j}| jsd|t|f }|j| |S |jd|| jt|f  | t	j
t	jt	j z7z|| j| W W dS  tyl } z|jtjkrgd|| jt|f }|j| W Y d}~W dS  d}~ww    t }d|| j|f }|j| | t	j | Y S )zSend a signal to the subprocess, without intending to kill it.

        Return None if the signal was sent, or an error message string
        if an error occurred or if the subprocess is not running.
        z1attempted to send %s sig %s but it wasn't runningzsending %s (pid %s) sig %szHunable to signal %s (pid %s), it probably just now exited on its own: %sNz&unknown problem sending sig %s (%s):%s)r   r>   r   r^   r-   r   rf   r   rd   r   r   rr   r   r   r/   r0   r   r=   r   r   r   r[   r   )r   r   r>   rc   ri   r   r   r   r   r   signal  sT   

zSubprocess.signalc           	      C   s$  |    t|\}}t }| | || _t| jj}|| jkr+|| j | jj	k }nd}| jj
jd|| jf  || jjv }| jrrd| _d| _|| _d||f }| tj | tj |ri| jj
j| n| jj
j| nx|rd| _d| _d||d f }| tj | tj | jj
j| nSd| _d| _|| _| jtjkr| tj | tj |rd||d	 f }| jtjd
d | jj
j| nd| | _d||d f }| jtjdd | jj
j| d| _| jj
| j  i | _ i | _!| j"durt#$t#%| | j" d| _"dS dS )zK The process was reaped and we need to report and manage its state
        Fzprocess '%s' (%s) laststart time is in the future, don't know how long process was running so assuming it did not exit too quicklyr   zstopped: %s (%s)Nz1Exited too quickly (process log may have details)zexited: %s (%s)z; not expectedz
; expectedT)rV   zBad exit code %s)&r+   r   rO   r   laststopr   r   r^   ro   r   r>   rf   rk   r-   	exitcodesr.   rQ   rl   rd   r   r   r[   r   rg   re   rr   rN   rP   r   r   rp   rz   r   r   rZ   r   rT   EventRejectedEvent)	r   r-   stsesri   rX   rc   too_quicklyexit_expectedr   r   r   finish  sl   




zSubprocess.finishc                 C   s&   | j jd u rd S | j j| j j}|S r&   )r   r   r>   drop_privilegesrh   r   r   r   r   u  s   zSubprocess.set_uidc                 C      | j j|j jk S r&   r   priorityr   otherr   r   r   __lt__{     zSubprocess.__lt__c                 C      | j j|j jkS r&   r   r   r   r   r   __eq__~  s   zSubprocess.__eq__c                 C   s4   | j j}trt|d}dt| |t|  f S )Nunicode-escapez+<Subprocess at %s with name %s in state %s>)r   r^   r   r   encodeidr	   	get_stater   r^   r   r   r   __repr__  s   
zSubprocess.__repr__c                 C   s   | j S r&   )r   r   r   r   r   r     s   zSubprocess.get_statec                 C   s  t   }| j}| | | jjj}| jjjtjkr_|t	j
kr9| jjr8| jjtu r-|   n2| j| jjvr8|   n&|t	jkrJ| jsJ| jjrI|   n|t	jkr_| j| jjkr_|| jkr_|   t| jj}|t	jkr|| j | jjkrd| _d| _| t	j | t	j d| jj }|d||f  |t	jkr| j| jjkr|   d}|d||f  d S d S |t	j kr| j| }|dkr| jjj!d|| j"f  | #t$j% d S d S d S )Nr   zNentered RUNNING state, process has stayed up for > than %s seconds (startsecs)zsuccess: %s %sz7entered FATAL state, too many start retries too quicklyzgave up: %s %szkilling '%s' (%s) with SIGKILL)&rO   r   r   r   r>   rf   moodr   
RESTARTINGr   rp   autorestartr   r   rl   r   r   ro   	autostartrN   rP   startretriesrQ   r   r^   rr   r   rd   r[   r   rg   r   r   rk   r-   r   r   SIGKILL)r   rX   r   rf   rc   ri   	time_leftr   r   r   
transition  sb   










zSubprocess.transition)T)C__name__
__module____qualname____doc__r-   r   r   listener_staterZ   ro   r   r   rQ   rn   rm   r.   rP   r   r   rl   re   r   r   r   r%   r+   r7   rL   r   rN   r   ProcessStateBackoffEventrq   ProcessStateFatalEventr   ProcessStateUnknownEventr   ProcessStateStoppedEventrp   ProcessStateExitedEventr   ProcessStateRunningEventrr   ProcessStateStartingEventr   ProcessStateStoppingEventrR   r[   rd   rj   r   r|   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   !   sn    
/
IGU/]r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )FastCGISubprocessz7Extends Subprocess class to handle FastCGI subprocessesc                 C   s   t | | d | _d S r&   )r   r   	fcgi_sockr   r   r   r   r     s   
zFastCGISubprocess.__init__c                 C   sH   | j du r	tdt| j dstd| j t| j f | j j | _dS )zU
        The FastCGI socket needs to be created by the parent before we fork
        Nz"No group set for FastCGISubprocesssocket_managerzNo SocketManager set for %s:%s)r   NotImplementedErrorr!   rK   r   
get_socketr   r   r   r   r   before_spawn  s   
zFastCGISubprocess.before_spawnc                 C   s$   |    t| }|du rd| _|S )zR
        Overrides Subprocess.spawn() so we can hook in before it happens
        N)r   r   r   r   )r   r-   r   r   r   r     s
   
zFastCGISubprocess.spawnc                 C   s
   d| _ dS )zM
        Releases reference to FastCGI socket when process is reaped
        N)r   r   r   r   r   after_finish  s   
zFastCGISubprocess.after_finishc                 C   s   t | ||}|   |S )zR
        Overrides Subprocess.finish() so we can hook in after it happens
        )r   r   r   )r   r-   r   retvalr   r   r   r     s   zFastCGISubprocess.finishc                 C   s~   | j  }| jj}||d || jd d | jjr&|| jd d n	|| jd d td|jD ]}|	| q5dS )z
        Overrides Subprocess._prepare_child_fds()
        The FastCGI socket needs to be set to file descriptor 0 in the child
        r   r   rM   r   r   r   N)
r   filenor   r>   r   r   r   r   r   r   )r   sock_fdr>   r   r   r   r   r     s   
z$FastCGISubprocess._prepare_child_fdsN)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s    r   c                   @   s\   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd ZdS )ProcessGroupBasec                 C   s0   || _ i | _| j jD ]}|| | j|j< q
d S r&   )r   	processesprocess_configsmake_processr^   )r   r   pconfigr   r   r   r     s
   zProcessGroupBase.__init__c                 C   r   r&   r   r   r   r   r   r     r   zProcessGroupBase.__lt__c                 C   r   r&   r   r   r   r   r   r     r   zProcessGroupBase.__eq__c                 C   s.   | j j}trt|d}d| jt| |f S )Nr   z<%s instance at %s named %s>)r   r^   r   r   r   	__class__r   r   r   r   r   r     s   zProcessGroupBase.__repr__c                 C      | j  D ]}|  qd S r&   )r  r    r   r   processr   r   r   r   %     
zProcessGroupBase.removelogsc                 C   r	  r&   )r  r    r%   r
  r   r   r   r%   )  r  zProcessGroupBase.reopenlogsc                 C   sn   t | j }|  |  |D ]#}| }|tjkr!|  q|tj	kr+|  q|tj
kr4|  qd S r&   )listr  r    sortreverser   r   r   r   rr   rN   r   )r   r  procr   r   r   r   stop_all-  s   




zProcessGroupBase.stop_allc                 C   s   dd | j  D S )z@ Processes which aren't in a state that is considered 'stopped' c                 S   s   g | ]
}|  tvr|qS r   )r   r
   ).0xr   r   r   
<listcomp>@  s    z<ProcessGroupBase.get_unstopped_processes.<locals>.<listcomp>)r  r    r   r   r   r   get_unstopped_processes>  s   z(ProcessGroupBase.get_unstopped_processesc                 C   s$   i }| j  D ]}||j q|S r&   )r  r    r   r   )r   r   r  r   r   r   get_dispatchersC  s   z ProcessGroupBase.get_dispatchersc                 C   s   d S r&   r   r   r   r   r   before_removeI  s   zProcessGroupBase.before_removeN)r   r   r   r   r   r   r   r   r%   r  r  r  r  r   r   r   r   r    s    	r  c                   @      e Zd Zdd ZdS )ProcessGroupc                 C   r	  r&   )r  r    r   )r   r  r   r   r   r   M  r  zProcessGroup.transitionN)r   r   r   r   r   r   r   r   r  L      r  c                   @   r  )FastCGIProcessGroupc              
   K   sl   t | | |dt}||j|jjd| _z| j  W d S  t	y5 } zt
d| j |f d }~ww )NsocketManager)rf   z&Could not create FastCGI socket %s: %s)r  r   rS   r   socket_configr>   rf   r   r   	Exceptionr<   r   )r   r   kwargssockManagerKlassrF   r   r   r   r   S  s   
zFastCGIProcessGroup.__init__Nr   r   r   r   r   r   r   r   r  Q  s    r  c                   @   s^   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdddZdd Z	dd Z
dd Zdd ZdS )EventListenerPoolc                 C   s0   t | | g | _d| _d| _d| _|   d S )Nr   )r  r   event_bufferseriallast_dispatchdispatch_throttle
_subscriber   r   r   r   r   c  s   zEventListenerPool.__init__c                 C   s0   |j }| j }||v r| j|jdd d S d S )NThead)r  r  r    _acceptEventrZ   )r   rZ   r  procsr   r   r   handle_rejectedk  s
   
z!EventListenerPool.handle_rejectedc                 C   s   | j  }d}|D ]}|  |jtjkr|jtjkrd}q	|r?| j	r9t

 }|| jk r/|| _|| j | j	k r9d S |   d S d S )NFT)r  r    r   r   r   r   r   r   READYr'  rO   r&  dispatch)r   r  dispatch_capabler  rX   r   r   r   r   r  s"   

zEventListenerPool.transitionc                 C   s   |    d S r&   )_unsubscriber   r   r   r   r    s   zEventListenerPool.before_removec                 C   sD   | j r| j d}| |}|s| j|dd n| j st | _d S )Nr   Tr)  )r$  pop_dispatchEventr+  rO   r&  )r   rZ   okr   r   r   r/    s   
	zEventListenerPool.dispatchFc                 C   s   t | jj}t|dstt|_t|dsi |_| jj|jvr)t| |j| jj< n| jjj	
d|j|t| j| jjf  t| j| jjkr\| jr\| jd}| jjj	d||jf  |rg| jd| d S | j| d S )Nr%  pool_serialsz6rebuffering event %s for pool %s (buf size=%d, max=%d)r   z4pool %s event buffer overflowed, discarding event %s)r   r   r^   r!   
new_serialGlobalSerialr%  r5  r>   rf   r   lenr$  buffer_sizer2  r   insertappend)r   rZ   r*  rc   discarded_eventr   r   r   r+    s2   




zEventListenerPool._acceptEventc           
      C   s   |j | jj }| j D ]p}|jtjkrq|jt	j
kr|t|jj}| }z|j}|j}| ||||}|t| W n( tyd }	 z|	jd tjkrM | jjjd|j|f  W Y d }	~	qd }	~	ww t	j|_||_| jjjd|j|f   dS qdS )Nr   zNepipe occurred while sending event %s to listener %s, listener state unchangedzevent %s sent to listener %sTF)r5  r   r^   r  r    r   r   r   r   r   r.  r   payloadr  r%  _eventEnveloper7   r   r/   rs   r0   r1   r>   rf   r   BUSYrZ   )
r   rZ   pool_serialr  rc   r=  
event_typer%  enveloper   r   r   r   r3    sH   


z EventListenerPool._dispatchEventc              	   C   s:   t |}t|}d| jjj|| jj||||d}d| S )Nz3.0)versidr%  	pool_namer@  
event_namer8  r=  zver:%(ver)s server:%(sid)s serial:%(serial)s pool:%(pool_name)s poolserial:%(pool_serial)s eventname:%(event_name)s len:%(len)s
%(payload)s)r   getEventNameByTyper8  r   r>   
identifierr^   )r   rA  r%  r@  r=  rF  payload_lenDr   r   r   r>    s   

z EventListenerPool._eventEnvelopec                 C   0   | j jD ]	}t|| j qttj| j d S r&   )r   pool_eventsr   	subscriber+  r   r-  r   rA  r   r   r   r(       zEventListenerPool._subscribec                 C   rK  r&   )r   rL  r   unsubscriber+  r   r-  rN  r   r   r   r1    rO  zEventListenerPool._unsubscribeN)F)r   r   r   r   r-  r   r  r/  r+  r3  r>  r(  r1  r   r   r   r   r"  b  s    
"r"  c                   @   r  )r7  c                 C   s
   d| _ d S )Nr#  )r%  r   r   r   r   r     s   
zGlobalSerial.__init__Nr!  r   r   r   r   r7    r  r7  c                 C   s$   | j tkrd| _ |  j d7  _ | j S )Nr#  rM   )r%  r   )instr   r   r   r6    s   
r6  )+r0   	functoolsrA   r   r9   rO   r   supervisor.compatr   r   r   r   supervisor.medusar   r   supervisor.statesr   r   r	   r
   supervisor.optionsr   r   r   r   supervisor.dispatchersr   
supervisorr   supervisor.datatypesr   supervisor.socket_managerr   total_orderingobjectr   r   r  r  r  r"  r7  r6  r   r   r   r   <module>   sP         3=> 