
    `gjo	                        d Z ddlmZ ddlZddlZddlZddlZddlmZ d
dZ	ddZ
dddZddZed	k(  r ej                   e              yy)u  SIGKILL any process left in this systemd unit's cgroup.

Runs as ``ExecStopPost=`` so it only fires after the gateway's main process
has exited. The gateway already reaps its own tool subprocesses on a clean
shutdown; this is the safety net for long-lived helpers it doesn't track
(``adb``, platform bridges, etc.) that would otherwise be orphaned in the
cgroup and block ``Restart=always`` — issue #37454.

We deliberately iterate ``cgroup.procs`` and send per-PID SIGKILLs instead
of writing ``1`` to ``cgroup.kill``: the original failure mode in #37454
was the kernel returning ``EINVAL`` on the cgroup-wide kill, while per-PID
signal delivery uses a separate code path that still works.
    )annotationsN)Pathc                     	 t        d      j                  d      } t        j                  d| t        j
                        }|sy|j                  d      j                         S # t        $ r Y yw xY w)z;Return the cgroup v2 path for the calling process, or None.z/proc/self/cgrouputf-8encodingNz	^0::(.+)$   )r   	read_textOSErrorresearch	MULTILINEgroupstrip)textmatchs     I/root/.hermes/venv/lib/python3.12/site-packages/gateway/cgroup_cleanup.py_own_cgroup_pathr      si    '(22G2D IIlD",,7E;;q>!!  s   A$ $	A0/A0c                   t        d|  d      }	 |j                  d      }g }|j                         D ]0  }|j	                         }|s	 |j                  t        |             2 |S # t        $ r g cY S w xY w# t        $ r Y Qw xY w)Nz/sys/fs/cgroupz/cgroup.procsr   r   )r   r
   r   
splitlinesr   appendint
ValueError)cgroup_path
procs_filerawpidslines        r   _read_cgroup_pidsr   $   s    {m=ABJ""G"4 D  zz|	KKD	" K  	  		s#   A* A;*A87A8;	BBc                   | 
t               } | syt        j                         }d}t        |       D ]2  }||k(  r		 t        j                  |t
        j                         |dz  }4 |S # t        $ r Y Bt        $ r Y Lw xY w)zPSIGKILL every PID in the cgroup other than the caller. Returns the count killed.r   r	   )	r   osgetpidr   killsignalSIGKILLProcessLookupErrorPermissionError)r   ownkilledpids       r   reap_cgroupr+   6   s    &(
))+CF - 	#:	GGC(aKF	 M	 " 	 		s   )A((	A>3A>=A>c                     t                y)Nr   )r+        r   mainr/   K   s
    Mr.   __main__)return
str | None)r   strr1   z	list[int])N)r   r2   r1   r   )r1   r   )__doc__
__future__r   r!   r   r$   syspathlibr   r   r   r+   r/   __name__exitr-   r.   r   <module>r:      sQ    # 	 	  
 	"$*
 zCHHTV r.   