a "eq#@sddlmZddlmZddlZddlZddlZddlZddlmZm Z ddl m Z ddl m Z Gdd d eZGd d d eZGd d d eZGddde eeZGdddeZdS))ProcessesCollection)FilenameCleanerN)PIPEPopen)Timer)with_metaclassc@s$eZdZeddZeddZdS) ProcessescCs*z tWSty$tYS0dSN)psutilpidsAttributeErrorZ get_pid_listrr>/usr/lib/python3.9/site-packages/tracer/resources/processes.pyr !s  zProcesses.pidsc CsRt}tD]>}z|t|Wqtjy8YqtjyJYq0q|Sr )rr r appendProcessr Z NoSuchProcess AccessDenied)Z processespidrrrall(s z Processes.allN)__name__ __module__ __qualname__ staticmethodr rrrrrr s r c@seZdZdZd!ddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ d"ddZddZddZd#dd ZdS)$ProcessWrappera Wrapper for ``psutil.Process class`` Library ``psutil`` is not backward compatible from version 2.x.x to 1.x.x. Purpose of this class is cover incompatibility in ``psutil.Process`` class and provide interface of new version. It allows using new interface even with old version of ``psutil``. Note that, for performance reasons, process information is cached at object creation. To force a refresh, invoke the ``rebuild_cache()`` method. NcCst||_|dSr )r r_process rebuild_cacheselfrrrr__init__As zProcessWrapper.__init__cCs t|jSr )boolrrrrr __nonzero__EszProcessWrapper.__nonzero__cCs|jjgdd|_dS)N)nameexecmdlineppidusername create_time)attrs)rZas_dict _procdictr rrrrHszProcessWrapper.rebuild_cachecCs|z\|ddkrZ|d|dvrZt|ddkrZ|dddd}d|WSWntjypYn0|dS) Nr"Zsshdr#r$r@rzssh-{0}-session)_attrlensplitformatr r)rr&rrrr"Ks&zProcessWrapper.namecCs |dS)Nr#r+r rrrr#WszProcessWrapper.execCs |dS)Nr$r/r rrrr$ZszProcessWrapper.cmdlinecCs |dS)Nr%r/r rrrr%]szProcessWrapper.ppidcCs |dS)Nparentr/r rrrr0`szProcessWrapper.parentcCs |dS)Nr&r/r rrrr&cszProcessWrapper.usernamecCs |dS)Nr'r/r rrrr'fszProcessWrapper.create_timeFcCsZd|}||jvrPz|j||j|<Wn$tyN|j||j|<Yn0|j|S)Nz children-{0})r.r)rchildrenr Z get_children)r recursivekeyrrrr1is   zProcessWrapper.childrencCsN||jvrDt|j|}z||j|<WntyB||j|<Yn0|j|Sr )r)getattrr TypeError)rr"attrrrrr+rs   zProcessWrapper._attrcCs t|j|Sr )r4r)ritemrrr __getattr__{szProcessWrapper.__getattr__TcCs^d|}||jvrTz|jj|d|j|<Wn&tyR|jj|d|j|<Yn0|j|S)Nzmemory_maps-{0})grouped)r.r)r memory_mapsr Zget_memory_maps)rr9r3rrrr:s   zProcessWrapper.memory_maps)N)F)T)rrr__doc__rr!rr"r#r$r%r0r&r'r1r+r8r:rrrrr3s    rcs(eZdZdZfddZddZZS) ProcessMetaz Caching metaclass that ensures that only one ``Process`` object is ever instantiated for any given PID. The cache can be cleared by calling ``Process.reset_cache()``. Based on https://stackoverflow.com/a/33458129 cs6tt|||fdd}|td|dS)Ncs i_dSr )_cacherclsrr reset_cachesz)ProcessMeta.__init__..reset_cacher@)superr<rsetattr)r?r"basesZ attributesr@ __class__r>rrs zProcessMeta.__init__cOsV|d}||jvrL|j|g|Ri|}|j|g|Ri|||j|<|j|S)Nr)r=__new__r)r?argskwargsrrrrr__call__s   zProcessMeta.__call__)rrrr;rrI __classcell__rrrDrr<s r<cseZdZdZddZddZddZedd d Ze d d Z d dZ fddZ dfdd Z e fddZe ddZe ddZe ddZe ddZZS) raS Represent the process instance uniquely identifiable through PID For all class properties and methods, please see http://pythonhosted.org/psutil/#process-class Below listed are only reimplemented ones. For performance reasons, instances are cached based on PID, and multiple instantiations of a ``Process`` object with the same PID will return the same object. To clear the cache, invoke ``Process.reset_cache()``. Additionally, as with ``ProcessWrapper``, process information is cached at object creation. To force a refresh, invoke the ``rebuild_cache()`` method on the object. cCs |j|jkS)zBFor our purposes, two processes are equal when they have same name)rrprocessrrr__eq__szProcess.__eq__cCs || Sr )rMrKrrr__ne__szProcess.__ne__cCs t|jSr )hashrr rrr__hash__szProcess.__hash__?cCsTtdd|gttd}t||j}z$|||jdkW|S|0dS)z Process arguments could be referring to files on remote filesystems and os.path.isfile will hang forever if the shared FS is offline. Instead, use a subprocess that we can time out if we can't reach some file. testz-f)stdoutstderrrN)rrrkillstartZ communicate returncodecancel)Z file_pathtimeoutrLZtimerrrr safe_isfiles  zProcess.safe_isfilecCsdg}|D]}|t|jq |ddD]&}tj|sFq4t |r4||q4t |SNr) r:rrstrippathr$osisabsrrZsorted)rfilesZmmapargrrrras    z Process.filescCs|rt|SdS)zGThe parent process casted from ``psutil.Process`` to tracer ``Process``N)r%rr rrrr0s zProcess.parentcs*ztt|WSty$YdS0dS)zcThe user who owns the process. If user was deleted in the meantime, ``None`` is returned instead.N)rArr&KeyErrorr rDrrr&s zProcess.usernameFcs"tt||}tdd|DS)zjThe collection of process's children. Each of them casted from ``psutil.Process`` to tracer ``Process``.cSsg|]}t|jqSr)rr).0childrrr z$Process.children..)rArr1r)rr2r1rDrrr1szProcess.childrencsBtt|}|dr$|dd}d|vr>|d|d}|S)zcThe absolute path to process executable. Cleaned from arbitrary strings which appears on the end.z#newr;)rArr#endswithindex)rr#rDrrr#s   z Process.execCs |dvS)N)Zpython)r"r rrris_interpretedszProcess.is_interpretedcCs8|}|durdS|}|dus0||kr4dSdS)NT)terminalr0)rrmr0rrr is_session s zProcess.is_sessioncCs@|jr8|ddD] }tj|rtj|Sq|Sr[)rlr$r^r]isfilebasenamer")rrbrrr real_names  zProcess.real_namecCstjt}tj|}||}d}|jdkrFt|jd}n`|jdkrhtt|jdd}n>|jdkrtt|jdd}n|jdkrtt|jd}|S) z The time of how long process is running. Returned as string in format ``XX unit`` where unit is one of ``days`` | ``hours`` | ``minutes`` | ``seconds`` rz daysiz hours<z minutesz seconds)datetimeZ fromtimestamptimer'ZdaysstrZsecondsint)rZnowstartedZ started_strrrrstr_started_agos    zProcess.str_started_ago)rQ)F)rrrr;rMrNrPrrZpropertyrar0r&r1r#rlrnrqryrJrrrDrrs*      rc@s&eZdZdZdZdddZddZdS)AffectedProcessNcCs t||t|_t|_dSr )rrsetpackagesrarrrrr9s zAffectedProcess.__init__cCs$|j|j|_|j|j|_dSr )raunionr}rKrrrupdate>szAffectedProcess.update)N)rrrr}rarrrrrrr{5s r{) collectionsrrr rtrur^ subprocessrr threadingrZsixrobjectr rtyper<rr{rrrrs    V