
    9i1Q                    0	   S 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SK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SKJr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJ r   SSKJ!r!  SSKJ"r"  SSKJ#r#  SSKJ$r$  SSKJ%r%  SSKJ&r&  SSKJ'r'  SSKJ(r(  SSKJ)r)  / SQr*Sr+\RX                  R[                  S \R\                  " 5        S!35      r/\RX                  R[                  S \R\                  " 5        S"35      r0\1" \S#5      r2\1" \S$5      r3\Rh                  " S%5      r5\Rl                  " 5       r7\Rp                  S&:H  r9\:" 5       r;S'r<\Rz                  " S(S)\>" \
R~                  5      05      r@\@R                  rA " S* S+\Rz                  5      rB\C" 5       R                  \BR                  5        \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  S,.rQ\R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  S-.r]\" S./ S/Q5      r^\" S0/ S1Q5      r_\" S2/ S3Q5      r`\" S4S55      ra\" S6\aR                  S7-   5      rc\" S8/ S9Q5      rd\" S:S;S<R                  \dR                  5      -   5      rf\" S=/ S>Q5      rg\" S?/ S@Q5      rhSA riSB rjSC rk\"SD 5       rl \l" SE5        SJ rpSK rqSL rrSM rsSN rtSO ruSP rvSQ rwSR rx\RX                  R[                  SS5      (       d   \RX                  R[                  ST5      (       a  SU ryOSV ry\R                  rz " SW SX\m5      r{ " SY SZ5      r|\|" 5       r}SmS[ jr~S\ rS] r\GR                  rSnS^ jr " S_ S`5      rSnSa jrSb rSc rSd rSe rSf rSg rSh rSi rSj r " Sk Sl5      rg! \m a(  rn\" SF\n< 35        \" SGSH5      " SISISI5      qo SrnCnGNSrnCnff = f)ozLinux platform implementation.    N)defaultdict)
namedtuple   )_common)_psposix)_psutil_linux)ENCODING)NIC_DUPLEX_FULL)NIC_DUPLEX_HALF)NIC_DUPLEX_UNKNOWN)AccessDenied)NoSuchProcess)ZombieProcess)bcat)cat)debug)decode)get_procfs_path)isfile_strict)memoize)memoize_when_activated)open_binary)	open_text)parse_environ_block)path_exists_strict)supports_ipv6)usage_percent)PROCFS_PATHIOPRIO_CLASS_NONEIOPRIO_CLASS_RTIOPRIO_CLASS_BEIOPRIO_CLASS_IDLECONN_ESTABLISHEDCONN_SYN_SENTCONN_SYN_RECVCONN_FIN_WAIT1CONN_FIN_WAIT2CONN_TIME_WAIT
CONN_CLOSECONN_CLOSE_WAITCONN_LAST_ACKCONN_LISTENCONN_CLOSINGz/sys/class/power_supply/proc//smaps/smaps_rollupproc_ioprio_getproc_cpu_affinity_get
SC_CLK_TCKlittlei   AddressFamilyAF_LINKc                   $    \ rS rSrSrSrSrSrSrg)
IOPriorityd   r   r          N)	__name__
__module____qualname____firstlineno__r   r    r!   r"   __static_attributes__r<       O/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/psutil/_pslinux.pyr8   r8   d   s    OOrB   r8   )RSDTtZXxKWIP)0102030405060708090A0Bsvmem)total	availablepercentusedfreeactiveinactivebufferscachedsharedslabsdiskio)	
read_countwrite_count
read_byteswrite_bytes	read_time
write_timeread_merged_countwrite_merged_count	busy_time	popenfile)pathfdpositionmodeflagspmemz"rss vms shared text lib data dirtypfullmem)usspssswappmmap_grouped)rr   rsssizerz   shared_cleanshared_dirtyprivate_cleanprivate_dirty
referenced	anonymousr{   	pmmap_extzaddr perms  pio)rh   ri   rj   rk   
read_charswrite_chars	pcputimes)usersystemchildren_userchildren_systemiowaitc                     [        U [        5      (       d   U 5       e[        R                  " U 5      n U R	                  S5      S   n U R                  S5      (       a  [        U 5      (       d  U SS n U $ )zWrapper around os.readlink(). r   
 (deleted)N)
isinstancestrosreadlinksplitendswithr   )rr   s    rC   r   r      si    dC  &$& ;;tD ::fa D }}\""+=d+C+CDSzKrB   c                 R   [         R                  S[         R                  S[         R                  S0nX[         R                  [         R                  -  [         R                  -  -     nU [         R                  -  (       a  UR                  SSS5      nUR                  SS5      nU$ )zRConvert file's open() flags into a readable string.
Used by Process.open_files().
rwzw+ar   zr+)r   O_RDONLYO_WRONLYO_RDWRO_APPENDreplace)rv   	modes_mapru   s      rC   file_flags_to_moder      sx     c2;;RYYEIbkkBKK7"))CDEDr{{||Ca(<<d#DKrB   c                     U R                  SS5      n SnU(       a  SU  3nOSU  S3n[        R                  " U[        R                  5      $ )zReturn True if the given name refers to a root device (e.g.
"sda", "nvme0n1") as opposed to a logical partition (e.g.  "sda1",
"nvme0n1p1"). If name is a virtual device (e.g. "loop1", "ram")
return True.
/!Tz/sys/block/z/device)r   r   accessF_OK)nameincluding_virtualrr   s      rC   is_storage_devicer      sL     <<S!DTF#TF'*99T277##rB   c                 V   [        U  S35       nUR                  5       R                  5       SS nSSS5        / SQn[        W5      nUS:  a  UR	                  S5        US:  a  UR	                  S5        US	:  a  UR	                  S
5        [        SU5      qg! , (       d  f       No= f)zSet a namedtuple of variable fields depending on the CPU times
available on this Linux kernel version which may be:
(user, nice, system, idle, iowait, irq, softirq, [steal, [guest,
 [guest_nice]]])
Used by cpu_times() function.
/statr   N)r   nicer   idler   irqsoftirq   steal	   guest
   
guest_nice	scputimes)r   readliner   lenappendr   r   )procfs_pathfvaluesfieldsvlens        rC   set_scputimes_ntupler      s     
}E*	+q##%ab) 
,KFv;Dqygqygrzl#;/I 
,	+s   "B
B(/proczignoring exception on import: r   zuser system idle        c                 v   U S   nXR                  SS5      -   n U S   nU S   nU S   n [	        [        5        S	35      nSnU   U HJ  n	U	R                  5       n	U	R                  S
5      (       d  M+  U[        U	R                  5       S   5      -  nML     SSS5        U[        -  nX-
  n
X4-   nU[        US-  U5      -  nX-  n
X[        US-  U5      -
  -  n
[        U
5      $ ! [         a'  n[        UR                  S    S35        Us SnA$ SnAff = f! [         a    Us $ f = f! , (       d  f       N= f)a9  Fallback for kernels < 3.14 where /proc/meminfo does not provide
"MemAvailable", see:
https://blog.famzah.net/2014/09/24/.

This code reimplements the algorithm outlined here:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/
    commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773

We use this function also when "MemAvailable" returns 0 (possibly a
kernel bug, see: https://github.com/giampaolo/psutil/issues/1915).
In that case this routine matches "free" CLI tool result ("available"
column).

XXX: on recent kernels this calculation may differ by ~1.5% compared
to "MemAvailable:", as it's calculated slightly differently.
It is still way more realistic than doing (free + cached) though.
See:
* https://gitlab.com/procps-ng/procps/issues/42
* https://github.com/famzah/linux-memavailable-procfs/issues/2
   MemFree:   Cached:r   s   Active(file):s   Inactive(file):   SReclaimable:zW is missing from /proc/meminfo; using an approximation for calculating available memoryNz	/zoneinfos   lowr   r:   g       @)getKeyErrorr   argsr   r   OSErrorstrip
startswithintr   PAGESIZEmin)memsr`   fallbacklru_active_filelru_inactive_fileslab_reclaimableerrr   watermark_lowlineavail	pagecaches               rC   calculate_avail_vmemr     sa   < Dhhz1--H	/0 !34 01?,-Y78 M	
D::<Dv&&TZZ\!_!55  

 XM E3IY]M22I	E	$4s$:M JJJEu:1  xx{m > >	
    
s@   C$ D *D*3#D*$
D.D
DDD'&D'*
D8c                     / n 0 n[        [        5        S35       nU H)  nUR                  5       n[        US   5      S-  XS   '   M+     SSS5        US   nUS   n US   n US
   nXR                  SS5      -  n US   n	 US   n
 US   n US   n US   nUS:X  a  [        U5      nUS:  a  SnU R                  S5        OX:  a  UnX]-
  n[        X]-
  USS9nU (       aL  SR                  SR                  U 5      [        U 5      S:X  a  SOS5      n[        R                  " U[        SS 9  [        UUUUUU
UUUU	U5      $ ! , (       d  f       GN= f! [         a    SnU R                  S	5         GNf = f! [         a    SnU R                  S5         GNf = f! [         a/     US   n	 GN0! [         a    Sn	U R                  S5          GNQf = ff = f! [         a    Sn
U R                  S5         GNsf = f! [         a;     US   US   -   US   -   n GN! [         a    SnU R                  S5          GNf = ff = f! [         a    Sn GNf = f! [         a    [        U5      n GNf = f)!a  Report virtual memory stats.
This implementation mimics procps-ng-3.3.12, aka "free" CLI tool:
https://gitlab.com/procps-ng/procps/blob/
    24fd2605c51fccc375ab0287cec33aa767f06718/proc/sysinfo.c#L778-791
The returned values are supposed to match both "free" and "vmstat -s"
CLI tools.
/meminfor      r   Ns	   MemTotal:r   s   Buffers:rc   r   r   rd   s   Shmem:s
   MemShared:re   s   Active:ra   s	   Inactive:s   Inact_dirty:s   Inact_clean:s   Inact_laundry:rb   s   Slab:s   MemAvailable:r]   round_z6{} memory stats couldn't be determined and {} set to 0z, waswerer:   
stacklevel)r   r   r   r   r   r   r   r   r   formatjoinr   warningswarnRuntimeWarningr[   )missing_fieldsr   r   r   r   r\   r`   rc   rd   re   ra   rb   rf   r   r_   r^   msgs                    rC   virtual_memoryr   Y  s    ND	)*(3	4DZZ\F!&)nt3DO  
5 ED){#
0j! 	((+Q//,i(j!
.%H~
/%& A:
 ).Eqyk*	 =DU]U1=G FMMIIn%(A-E6
 	c>a8 Q 
5	4  )i()  (h'(  ,	,-(F 	,F!!(++	,,  (h'(  	.	._%'(()* 
  	.H!!*--	.	.    +$T*+s   0EE $E< >F  G 
H  I I 
EE98E9<FF 
G+F33GGGGG=<G= 
IHI<I IIIII43I4c                     0 n [        [        5        S35       nU H)  nUR                  5       n[        US   5      S-  XS   '   M+     SSS5         U S   nU S   nXE-
  n[        XSS9n	 [        [        5        S	35      nU   S=pU H  nUR                  S
5      (       a$  [        UR                  S5      S   5      S-  S-  n
O9UR                  S5      (       a#  [        UR                  S5      S   5      S-  S-  nU
c  M{  Uc  M    O&   SnUS-  n[        R                  " U[        SS9  S=pSSS5        [        R                  " XHXYW
W5      $ ! , (       d  f       GN= f! [         a'    [
        R                  " 5       u        pdpWXG-  nXW-  n GN8f = f! , (       d  f       Nm= f! [         a-  nSU S3n[        R                  " U[        SS9  S=p SnANSnAff = f)zReturn swap memory metrics.r   r   r   r   Ns
   SwapTotal:s	   SwapFree:r   z/vmstats   pswpin       s   pswpoutz,'sin' and 'sout' swap memory stats couldn't zbe determined and were set to 0r:   r   zM'sin' and 'sout' swap memory stats couldn't be determined and were set to 0 ())r   r   r   r   r   cextlinux_sysinfor   r   r   r   r   r   r   sswap)r   r   r   r   r\   r`   _unit_multiplierr_   r^   sinsoutr   r   s                 rC   swap_memoryr     s   D	)*(3	4DZZ\F!&)nt3DO  
5 ]#L! <DD2G?,-W56 C ??9--djj.q12Q6=C__Z00tzz$/23a7$>D?t'7  E88c>a@% & ==dS$??c 
5	4   373E3E3G01a4  & Q  003uA7 	 	c>a8dsN   0E
E$ +F) A=FF	(F
E!$-FF
F&)
G 3#GG c                  T   [        5       n [        U 5        [        U  S35       nUR                  5       R	                  5       nSSS5        WS[        [        R                  5      S-    nU Vs/ s H  n[        U5      [        -  PM     nn[        U6 $ ! , (       d  f       NW= fs  snf )zReturn a named tuple representing the following system-wide
CPU times:
(user, nice, system, idle, iowait, irq, softirq [steal, [guest,
 [guest_nice]]])
Last 3 fields may not be available on all Linux kernel versions.
r   Nr   )
r   r   r   r   r   r   r   _fieldsfloatCLOCK_TICKS)r   r   r   r   rK   s        rC   	cpu_timesr     s     "#K%	}E*	+q##% 
,AI--.23F.45feAh$fF5f	 
,	+ 6s   B.B%
B"c                     [        5       n [        U 5        / n[        U  S35       nUR                  5         U H  nUR	                  S5      (       d  M  UR                  5       nUS[        [        R                  5      S-    nU Vs/ s H  n[        U5      [        -  PM     nn[        U6 nUR                  U5        M     UsSSS5        $ s  snf ! , (       d  f       g= f)z^Return a list of namedtuple representing the CPU times
for every CPU available on the system.
r   s   cpur   N)r   r   r   r   r   r   r   r   r   r   r   r   )r   cpusr   r   r   r   rK   entrys           rC   per_cpu_timesr  &  s     "#K%D	}E*	+q	

Dv&&C	(9(9$:Q$>?:@A&Q%([0&A!6*E"   
,	+ B 
,	+s#   *C3CC# CC
C c                  @    [         R                  " S5      $ ! [         a    Sn [        [	        5        S35       nU H.  nUR                  5       R                  S5      (       d  M)  U S-  n M0     SSS5        O! , (       d  f       O= fU S:X  a  [        R                  " S5      n[        [	        5        S35       nU H4  nUR                  S	5      S   nUR                  U5      (       d  M/  U S-  n M6     SSS5        O! , (       d  f       O= fU S:X  a   gU s $ f = f)
z0Return the number of logical CPUs in the system.SC_NPROCESSORS_ONLNr   /cpuinfos	   processorr   Nzcpu\dr   r   )r   sysconf
ValueErrorr   r   lowerr   recompiler   r   match)numr   r   searchs       rC   cpu_count_logicalr  :  s    zz/00 O-.h78A::<**<881HC  988 !8ZZ)Fo/0671D::c?1-D||D))q  877 !8
-sP    "D(A8&	A8/	D8
B	9D;.C?-	C?6	D?
D		DDDc                     [        5       n SnSn[        R                  " U5      =(       d    [        R                  " U5       HD  n[        U5       nU R                  UR	                  5       R                  5       5        SSS5        MF     [        U 5      nUS:w  a  U$ 0 n0 n[        [        5        S35       nU Hp  nUR                  5       R                  5       nU(       d   US   XgS   '   0 nM7  UR                  S5      (       d  MO  UR                  S	S
5      u  p[        U
5      Xy'   Mr     SSS5        [        UR                  5       5      nU=(       d    S$ ! , (       d  f       GM(  = f! [         a     Nf = f! , (       d  f       NU= f)z-Return the number of CPU cores in the system.z9/sys/devices/system/cpu/cpu[0-9]*/topology/core_cpus_listz?/sys/devices/system/cpu/cpu[0-9]*/topology/thread_siblings_listNr   r  	   cpu cores   physical id)r  r  s   	:r   )setglobr   addreadr   r   r   r  r   r   r   r   sumr   )lsp1p2rr   r   resultmappingcurrent_infor   keyvalues              rC   cpu_count_coresr  W  sT    
B 
EB	JB		".2.!FF1668>>#$  / WF{ GL	)*(3	4D::<%%'D<H$=G89
  "!?@@!ZZ2
$'J!  
5" !"F>T7 $    
5	4sB   .E7+E=#
E--E=	%E=
E*	-
E:7E=9E::E==
Fc                     [        [        5        S35       n SnSnSnU  H  nUR                  S5      (       a  [        UR	                  5       S   5      nOeUR                  S5      (       a  [        UR	                  5       S   5      nO2UR                  S5      (       a  [        UR	                  5       S   5      nUc  M  Uc  M  Uc  M    O   SSS5        Sn[
        R                  " WWWU5      $ ! , (       d  f       N)= f)z*Return various CPU stats as a named tuple.r   Ns   ctxtr   s   intrs   softirqr   )r   r   r   r   r   r   	scpustats)r   ctx_switches
interruptssoft_interruptsr   syscallss         rC   	cpu_statsr&    s    	)*%0	1Q
Dw''"4::<?3)) a1
,,"%djjl1o"6(#/* 	 
2" Hj/8 % 
2	1s   B%C1 C1C1
C11
C?c            
         [        [        5        S35       n U  Vs/ s HG  nUR                  5       R                  S5      (       d  M)  [	        UR                  SS5      S   5      PMI     snsSSS5        $ s  snf ! , (       d  f       g= f)z7Return current CPU frequency from cpuinfo if available.r  s   cpu mhz   :r   N)r   r   r  r   r   r   )r   r   s     rC   _cpu_get_cpuinfo_freqr)    su    	)*(3	4 
zz|&&z2 *E$**T1%a()
 
5	4
 
5	4s"   A;(A6"A6*A;6A;;
B	z'/sys/devices/system/cpu/cpufreq/policy0z$/sys/devices/system/cpu/cpu0/cpufreqc            	         [        5       n [        R                  " S5      =(       d    [        R                  " S5      nUR                  S S9  / n[        R                  R
                  n[        U5       GH  u  pE[        U5      [        U 5      :X  a  X   S-  nO[        U" US5      SS9nUc^  [        U" US	5      SS9nUcJ  S
U S3n[        USS9S:X  a)  UR                  [        R                  " SSS5      5        M  Sn[        U5      e[        U5      S-  n[        [        U" US5      5      5      S-  n	[        [        U" US5      5      5      S-  n
UR                  [        R                  " XjU	5      5        GM     U$ )zjReturn frequency metrics for all CPUs.
Contrarily to other OSes, Linux updates these values in
real-time.
z,/sys/devices/system/cpu/cpufreq/policy[0-9]*z)/sys/devices/system/cpu/cpu[0-9]*/cpufreqc                 ^    [        [        R                  " SU 5      R                  5       5      $ )Nz[0-9]+)r   r	  r  grouprK   s    rC   <lambda>cpu_freq.<locals>.<lambda>  s    RYYy!%<%B%B%D!ErB   )r  i  scaling_cur_freqNr   cpuinfo_cur_freqz/sys/devices/system/cpu/cpuz/onlinez0
r   z!can't find current frequency filescaling_max_freqscaling_min_freq)r)  r  sortr   rr   r   	enumerater   r   r   r   r   scpufreqNotImplementedErrorr   )cpuinfo_freqspathsretpjoinirr   curronline_pathr   max_min_s              rC   cpu_freqrB    sl   
 ./		:
 DYYBC 	 	

E
F 'GA5zS// %'$.E$(:;dK| E$(:;dK<$?s'"JK;6%?

7#3#3Cc#BC =C-c22t9t#DtE$(:;<=DDtE$(:;<=DDJJw''D9:- (. 
rB   c                  n    [        5        V s/ s H  n [        R                  " U SS5      PM     sn $ s  sn f )zmAlternate implementation using /proc/cpuinfo.
min and max frequencies are not available and are set to None.
r   )r)  r   r7  r-  s    rC   rB  rB    s1     8M7NO7N!  C-7NOOOs   "2c                       \ rS rSrSrg)_Ipv6UnsupportedErrori  r<   N)r=   r>   r?   r@   rA   r<   rB   rC   rE  rE    s    rB   rE  c                   l    \ rS rSrSrS rS rS r\S 5       r	\SS j5       r
\SS	 j5       rSS
 jrSrg)NetConnectionsi  a[  A wrapper on top of /proc/net/* files, retrieving per-process
and system-wide open connections (TCP, UDP, UNIX) similarly to
"netstat -an".

Note: in case of UNIX sockets we're only able to determine the
local endpoint/path, not the one it's connected to.
According to [1] it would be possible but not easily.

[1] http://serverfault.com/a/417946
c                    S[         R                  [         R                  4nS[         R                  [         R                  4nS[         R                  [         R                  4nS[         R                  [         R                  4nS[         R
                  S 4nXX4U4X4U4U4X44U4U4U4XX44X4X$4S.U l        S U l        g )Ntcptcp6udpudp6unix)allrI  tcp4rJ  rK  udp4rL  rM  inetinet4inet6)socketAF_INETSOCK_STREAMAF_INET6
SOCK_DGRAMAF_UNIXtmap_procfs_path)selfrO  rJ  rP  rL  rM  s         rC   __init__NetConnections.__init__  s     v~~v'9'9:););<v~~v'8'89):):;-D1<GG<GGG,\\
	 !rB   c                 &   [        [        5      n[        R                  " U R                   SU S35       H_  n [        U R                   SU SU 35      nUR                  S5      (       a(  USS  S S nX$   R                  U[        U5      45        M_  Ma     U$ ! [        [        4 a     Mx  [         aY  nUR                  [        R                  :X  a   S nAM  UR                  [        R                  :X  a  [        U5         S nAM  e S nAff = f)Nr   /fd/fd/zsocket:[r   )r   listr   listdirr[  r   r   r   r   FileNotFoundErrorProcessLookupErrorr   errnoEINVALENAMETOOLONGr   )r\  pidinodesrs   inoder   s         rC   get_proc_inodesNetConnections.get_proc_inodes  s    T"** 1 12!C5<=B9 D$5$5#6auD!EF  ##J//!!"IcrNEM((#s2w8 0% >, ' &'9:   99,99 2 22#Js)   BD.	D7D)D
DDc                     0 n[        5        H$  n UR                  U R                  U5      5        M&     U$ ! [        [        [
        4 a     MB  f = fN)pidsupdaterm  re  rf  PermissionError)r\  rk  rj  s      rC   get_all_inodesNetConnections.get_all_inodes  sT    6C
d22378   &'9?K  s    7AAc           
      f   U R                  S5      u  p#[        US5      nU(       d  gUR                  S5      nU[        R                  :X  ai  [
        (       a2  [        R                  " U[        R                  " U5      SSS2   5      nO[        R                  " U[        R                  " U5      5      nO[        R                  " U5      n [
        (       aP  [        R                  " [        R                  [        R                  " S/[        R                  " SU5      Q76 5      nOP[        R                  " [        R                  [        R                  " S/[        R                  " SU5      Q76 5      n [         R"                  " X#5      $ ! [         a    [        5       (       d  [        See f = f)	a.  Accept an "ip:port" address as displayed in /proc/net/*
and convert it into a human readable form, like:

"0500000A:0016" -> ("10.0.0.5", 22)
"0000000000000000FFFF00000100007F:9E49" -> ("::ffff:127.0.0.1", 40521)

The IP address portion is a little or big endian four-byte
hexadecimal number; that is, the least significant byte is listed
first, so we need to reverse the order of the bytes to convert it
to an IP address.
The port is represented as a two-byte hexadecimal number.

Reference:
http://linuxdevcenter.com/pub/a/linux/2000/11/16/LinuxAdmin.html
:   r<   asciiNrb  z>4Iz<4I)r   r   encoderT  rU  LITTLE_ENDIAN	inet_ntopbase64	b16decoderW  structpackunpackr  r   rE  r   addr)r  familyipports       rC   decode_addressNetConnections.decode_address/  s>   " ::c?4} YYwV^^#}%%ff.>.>r.B4R4.HI%%ff.>.>r.BC!!"%B =))EEFMM%,DEB
  ))EEFMM%,DEB ||B%%  $/T9	s   AF (AF "F0Nc              #     #    U R                  S5      (       a%  [        R                  R                  U 5      (       d  g[	        U 5       nUR                  5         [        US5       H  u  pg UR                  5       SS u
  pp        pX;   a
  X<   S   u  pOS	u  pUb  XN:w  a  M>  U[        R                  :X  a
  [        U   nO[        R                  n [        R!                  X5      n	[        R!                  X5      n
XX)XU4v   M     SSS5        g! [         a    SU  SU SU< 3n[        U5      Sef = f! ["         a     M  f = f! , (       d  f       g= f7f)
z.Parse /proc/net/tcp* and /proc/net/udp* files.6Nr   r   error while parsing ; malformed line r   r   Nrb  )r   r   rr   existsr   r   r6  r   r  RuntimeErrorrT  rV  TCP_STATUSESr   	CONN_NONErG  r  rE  )filer  type_rk  
filter_pidr   linenor   r   laddrraddrstatusrl  r   rj  rs   s                   rC   process_inetNetConnections.process_inetb  sc     ==bggnnT&:&:t_JJL )!Q	6

Sb) BAeQ1a ? %mA.GC&GC)j.? 2 22!-f!5!(!2!2! . = =e L . = =e L uUCHHC !0 _ " 6.tf 5"81TH.  's+564 1 ! !C _s[   AE	"E	,DAE	*D8=E			E#D55E	8
EE	EE		
EEc           
   #     #    [        U 5       nUR                  5         U H  nUR                  5       n USS u        pxpyX;   a  X)   nOS/nU H_  u  pUb  X<:w  a  M  [        U5      S:X  a  US	   OS
n[        R                  " [        U5      5      nS
n[        R                  nXXUUU4v   Ma     M     SSS5        g! [         a    SU;  a   M  SU  SU< 3n
[	        U
5      ef = f! , (       d  f       g= f7f)zParse /proc/net/unix files.r      r   r  r  r  Nr   rb   )
r   r   r   r  r  r   r   socktype_to_enumr   r  )r  r  rk  r  r   r   tokensr   r  rl  r   pairsrj  rs   rr   r  r  s                    rC   process_unixNetConnections.process_unix  s     t_JJL	,281+/Aq!Qq ? #ME'LE$GC!-*2C -0[A-=vbz2 ' 8 8U D !#!(!2!2!5vsKK  %%  _ " ,$ .tf4EdXN  's++, _s@   C;&C*B? A6C*6	C;?C'C*C''C**
C84C;c                 6   [        5       U l        Ub  U R                  U5      nU(       d  / $ OU R                  5       n[	        5       nU R
                  U    H  u  pVnU R                   SU 3nU[        R                  [        R                  1;   a  U R                  XXsUS9n	OU R                  XX2S9n	U	 HR  u  pp{pnU(       a  [        R                  " XX{X5      nO[        R                  " XX{XU5      nUR                  U5        MT     M     [        U5      $ )Nz/net/)r  )r   r[  rm  rt  r  rZ  rT  rU  rW  r  r  r   pconnsconnr  rc  )r\  kindrj  rk  r;  
proto_namer  r  rr   r  rs   r  r  r  	bound_pidconns                   rC   retrieveNetConnections.retrieve  s   +-?))#.F	  ((*Fe)-4%J''(j\:D&..&//::&&%C '  &&tV&LFHBE%"==E%D #==E%D  GI *9$ CyrB   )r[  rZ  rp  )r=   r>   r?   r@   __doc__r]  rm  rt  staticmethodr  r  r  r  rA   r<   rB   rC   rG  rG    s^    	!.4  0& 0&d (I (IT !L !LFrB   rG  c                 ,    [         R                  U 5      $ )z$Return system-wide open connections.)_net_connectionsr  )r  s    rC   net_connectionsr    s    $$T**rB   c                     [        [        5        S35       n U R                  5       nSSS5        0 nWSS  H  nUR                  S5      nUS:  d   [	        U5      5       eUSU R                  5       nX4S-   S R                  5       R                  5       n[        [        U5      u  nnn	n
nnnnnnnnnnnnUUUUU	UU
U4X%'   M     U$ ! , (       d  f       N= f)zkReturn network I/O statistics for every network interface
installed on the system as a dict of raw tuples.
z/net/devNr:   rw  r   r   )	r   r   	readlinesrfindreprr   r   mapr   )r   linesretdictr   colonr   r   
bytes_recvpackets_recverrindropin_fifoin_framein_compressedin_multicastin
bytes_sentpackets_senterroutdropout_fifoout_collisionsout_carrierout_compressedouts                          rC   net_io_countersr    s
    
o'(1	2a 
3Gab	

3qy$$t*$yFU|!!#aik"((*002* V'	
 	
7 J NQ 
3	2s   C


Cc                  <   [         R                  [        [         R                  [        [         R
                  [        0n [        5       R                  5       n0 nU H{  n [         R                  " U5      n[         R                  " U5      n[         R                  " U5      u  pgSR                  U5      nSU;   n	[        R                  " XU   XtU5      X#'   M}     U$ ! [         a5  n
U
R                   [         R"                  :w  a  e [%        U
5         Sn
A
M  Sn
A
ff = f)z)Get NIC stats (isup, duplex, speed, mtu).,runningN)r   DUPLEX_FULLr
   DUPLEX_HALFr   DUPLEX_UNKNOWNr   r  keys
net_if_mtunet_if_flagsnet_if_duplex_speedr   r   	snicstatsr   rg  ENODEVr   )
duplex_mapnamesr;  r   mturv   duplexspeedoutput_flagsisupr   s              rC   net_if_statsr    s     	///J
 ""$E
C	//$'C%%d+E 44T:MF 88E?L%D))(%lCI   J  	yyELL(#JJ		s   AC
D&*DDc                    S nS n[         R                  R                  [        5        S35      (       a  U" 5       nOD[         R                  R                  S5      (       a  U" 5       nO[        5        S3n[	        U5      e0 nU H@  nUu
  pxpppnnU (       d  [        U5      (       d  M%  U
[        -  n
U[        -  nXXXXU4	XW'   MB     U$ )z[Return disk I/O statistics for every disk installed on the
system as a dict of raw tuples.
c               3      #    [        [        5        S35       n U R                  5       nS S S 5        W H  nUR                  5       n[	        U5      nUS:X  a.  US   n[        US   5      n[        [
        USS 5      u
  pxpnppnOhUS:X  d  US:  a   US   n[        [
        USS 5      u  pgppppnO<US:X  a%  US   n[        [
        USS  5      u  phpS	=n	=n=n=pOS
U< 3n[        U5      eXVXXUX{U4
v   M     g ! , (       d  f       N= f7f)N
/diskstats   r;   r:   r         r  r   znot sure how to interpret line )r   r   r  r   r   r   r  r  )r   r  r   r   flenr   readsreads_mergedrbytesrtimewriteswrites_mergedwbyteswtimer   rp   r   s                    rC   read_procfs%disk_io_counters.<locals>.read_procfs0  s7    " /+,J78AKKME 9DZZ\Fv;DrzayF1I69#va|6L4um1trzay69#va|6L4fV1ay03C0D-vKLLLLL}y7x@ o%u	; ;/  98s   DC=CD=
DDc               3   2  #    [         R                  " S5       H  n [         R                  " [         R                  R	                  SU 5      5       H  u  pnSU;  a  M  [        [         R                  R	                  US5      5       nUR                  5       R                  5       R                  5       nS S S 5        [         R                  R                  U5      n[        [        WS S 5      u
  pxpppp/XgXXXX4
v   M     M     g ! , (       d  f       NX= f7f)N
/sys/blockstatr   )r   rd  walkrr   r   r   r  r   r   basenamer  r   )blockrootr   filesr   r   r   r  r  r  r  r  r  r  r  rp   s                   rC   
read_sysfs$disk_io_counters.<locals>.read_sysfs^  s     ZZ-E"$''"'',,|U*K"L&rww||D&9:aVVX^^-335F ;ww''- 47sF3BK3H1fV1FFMF F #M . ;:s   BD-D4AD
DDr  r  z6/diskstats nor /sys/block are available on this system)r   rr   r  r   r8  r   DISK_SECTOR_SIZE)perdiskr  r  genr   r  r  r   r  r  r  r  r  r  r  r  rp   s                    rC   disk_io_countersr  +  s    
+;\F 
ww~~*+:677m		%	%l  ! "  	 "#&&G ).	&ffU9066 """"%iA) 0 NrB   c                   >    \ rS rSrSrSS/rS rS rS rS r	S	 r
S
rg)RootFsDeviceFinderi  a2  disk_partitions() may return partitions with device == "/dev/root"
or "rootfs". This container class uses different strategies to try to
obtain the real device path. Resources:
https://bootlin.com/blog/find-root-device/
https://www.systutorials.com/how-to-find-the-disk-where-root-is-on-in-bash-on-linux/.
majorminorc                     [         R                  " S5      R                  n[         R                  " U5      U l        [         R                  " U5      U l        g Nr   )r   r  st_devr  r  )r\  devs     rC   r]  RootFsDeviceFinder.__init__  s3    ggcl!!XXc]
XXc]
rB   c                    [        [        5        S35       nUR                  5       SS   H  nUR                  5       n[	        U5      S:  a  M$  US   R                  5       (       a  [        US   5      OS nUS   R                  5       (       a  [        US   5      OS nUS   nX@R                  :X  d  M  XPR                  :X  d  M  U(       d  M  SU 3s  sS S S 5        $    S S S 5        g ! , (       d  f       g = f)Nz/partitionsr:   r   r   r   r;   /dev/)	r   r   r  r   r   isdigitr   r  r  )r\  r   r   r   r  r  r   s          rC   ask_proc_partitions&RootFsDeviceFinder.ask_proc_partitions  s    /+,K89Qab)v;?*0)*;*;*=*=F1I4*0)*;*;*=*=F1I4ayJJ&5JJ+>t!&tf~- :9) :99s$   BC*5C*C*C*C**
C8c                 <   SU R                    SU R                   S3n[        U5       nU HT  nUR                  S5      (       d  M  UR	                  5       R                  S5      S   nU(       d  MF  SU 3s  sS S S 5        $    S S S 5        g ! , (       d  f       g = f)Nz/sys/dev/block/rw  z/ueventzDEVNAME=r:   r  )r  r  r   r   r   
rpartition)r\  rr   r   r   r   s        rC   ask_sys_dev_block$RootFsDeviceFinder.ask_sys_dev_block  s{     Adjj\At_??:..::<22:>qADt!&tf~- _ __s   B'B2BB
Bc                    U R                    SU R                   3n[        R                  " S5      nU H  n [	        U5      nU   UR                  5       R                  5       nXQ:X  aL  [        R                  R                  [        R                  R                  U5      5      nSU 3sS S S 5        s  $  S S S 5        M     g ! , (       d  f       M  = f! [         a     M  f = f)Nrw  z/sys/class/block/*/devr  )r  r  r  iglobr   r  r   r   rr   r  dirnamere  )r\  needler  r  r   datar   s          rC   ask_sys_class_block&RootFsDeviceFinder.ask_sys_class_block  s    JJ<q-

34D	.dO 668>>+D~!ww//0EF!&tf~	 Q% Q  Q % s   CA$C
C	
C#"C#c                    S nUc   U R                  5       nUc   U R                  5       nUc   U R	                  5       nUb'  [
        R                  R                  U5      (       a  U$ g g ! [         a  n[        U5         S nANmS nAff = f! [         a  n[        U5         S nAN{S nAff = f! [         a  n[        U5         S nANS nAff = frp  )r  r   r   r  r  r   rr   r  )r\  rr   r   s      rC   findRootFsDeviceFinder.find  s    <//1 <--/ <//1
 t 4 4K !5  c


  c


  c

sE   A* B B. *
B	4BB	
B+B&&B+.
C8CC)r  r  N)r=   r>   r?   r@   r  	__slots__r]  r  r  r  r  rA   r<   rB   rC   r  r    s,     '"I#
...rB   r  c                    [        5       n[        5       nU (       d  [        U S35       nU Hw  nUR                  5       nUR	                  S5      (       d!  UR                  UR                  5       5        MJ  UR                  S5      S   nUS:X  d  Mf  UR                  S5        My     SSS5        US:X  aD  [        R                  R                  S5      (       a   [        R                  R                  S5      nO"[        R                  R                  U S	35      n/ n[        R                  " U5      nU Ht  n	U	u  pp\U
S
:X  a  Sn
U
S;   a!  [        5       R                  5       =(       d    U
n
U (       d  U
(       a  XQ;  a  ML  [        R                   " XX\5      nUR#                  U5        Mv     U$ ! , (       d  f       GN= f)z8Return mounted disk partitions as a list of namedtuples.z/filesystemsnodev	r   zfsNr   z	/etc/mtabz/self/mountsnoner  >   rootfs	/dev/root)r  r   r   r   r   r  r   r   rr   isfilerealpathr   disk_partitionsr  r  r   	sdiskpartr   )rN  fstypesr   r   r   fstypemounts_pathretlist
partitions	partitiondevice
mountpointoptsntuples                 rC   r"  r"    sd   eG!#K+l34zz|w//KK

- "ZZ-a0FE*  5 g"''.."="=gg&&{3gg&&+l'CDG%%k2J	+4(FVF,,')..0:FFV2""6vDv   N? 54s   A%F0F00
F?c            	         [         R                  " [        5      n [        R                  " S5      nUR	                  [        R                  " S5      5        [        U Vs1 s H  o"R                  S5      S   iM     sn5      n[        R                  " S5      n[        R                  " S5      nU H-  nUR                  SU5      nXa;  d  M  UR                  U5        M/     U H  n US-   n[        [        U5      5      S	-  n	[        R                  R                  [        R                  R!                  U5      S
5      n[#        U5      R%                  5       n
[        US-   SS9n[        US-   SS9n[#        US-   SS9R%                  5       nUb   [        U5      S	-  nUb   [        U5      S	-  nX
   R                  XX45        M     U(       Gd  [        R                  " S5      n[        [+        U5      5      nU GH  n [        R                  R                  US5      n[        [        U5      5      S	-  n	[        R                  R                  US5      n[#        U5      R%                  5       n
[        R                  " US-   5      nU Vs1 s HC  nSR                  [        R                  R/                  U5      R                  S5      SS 5      iME     nnSnSnU H  n[        R                  R                  UUS-   5      n[#        USS9R%                  5       nUS:X  a,  [        [        R                  R                  UUS-   5      SS9nO1US:X  a+  [        [        R                  R                  UUS-   5      SS9nUb   [        U5      S	-  nUc  M   [        U5      S	-  nM     X
   R                  SXU45        GM     [1        U 5      $ s  snf ! [&        [(        4 a     GM
  f = f! [(         a    Sn GN`f = f! [(         a    Sn GNaf = f! [&        [(        4 a  n[-        U5         SnAGM:  SnAff = fs  snf ! [(         a    Sn Nf = f! [(         a    Sn GM  f = f)a  Return hardware (CPU and others) temperatures as a dict
including hardware name, label, current, max and critical
temperatures.

Implementation notes:
- /sys/class/hwmon looks like the most recent interface to
  retrieve this info, and this implementation relies on it
  only (old distros will probably use something else)
- lm-sensors on Ubuntu 16.04 relies on /sys/class/hwmon
- /sys/class/thermal/thermal_zone* is another one but it's more
  difficult to parse
z/sys/class/hwmon/hwmon*/temp*_*z&/sys/class/hwmon/hwmon*/device/temp*_*r   r   z5/sys/devices/platform/coretemp.*/hwmon/hwmon*/temp*_*z'/sys/devices/platform/coretemp.*/hwmon/z/sys/class/hwmon/_inputg     @@r   _maxNr1  _crit_labelr  z /sys/class/thermal/thermal_zone*temptypez/trip_point*r;   _typecritical_temphigh)collectionsr   rc  r  extendsortedr   r	  r
  subr   r   r   r   rr   r   r  r   r   r   r  r  r   r  dict)r;  	basenamesrK   
basenames2replr   altnamebaserr   current	unit_namer8  r6  labelr   
trip_pathsptrip_points
trip_point	trip_types                       rC   sensors_temperaturesrK    s	    
!
!$
'C		;<I TYYGHI;AQ;<I ?J ::@AD((.5#T" 
 	(?DDJ'&0G77<< 5v>DD	)I D6MD1w6D8Ob1779T{V+   ?V3 	ut>?A F II@A	3y>*	Dww||D&1T
+f4ww||D&1IOO-	
 4.#89J $#A ))!,2237!<=#   HD)
ww||D*w*>?r288:	
*#T:+?@4 H &(T:+?@4D #$$T{V3 '(#(?V#;' *. N!!2wh"?@Q T 9A <* $ 		 		$  
      Z( c

* & $#$
 & (#'(s   O(A2OO2%PA0PA
Q	QQO/.O/2PPPPP?(P::P?QQQ*)Q*c                     [         R                  " [        5      n [        R                  " S5      nU(       d  [        R                  " S5      n[	        U Vs1 s H  o"R                  S5      S   iM     sn5      nU H  n [        [        US-   5      5      n[        [        R                  R                  [        R                  R                  U5      S5      5      R                  5       n[        US-   S	S
9R                  5       nX   R!                  ["        R$                  " Xt5      5        M     ['        U 5      $ s  snf ! [         a  n[        U5         SnAM  SnAff = f)ak  Return hardware fans info (for CPU and other peripherals) as a
dict including hardware label and current speed.

Implementation notes:
- /sys/class/hwmon looks like the most recent interface to
  retrieve this info, and this implementation relies on it
  only (old distros will probably use something else)
- lm-sensors on Ubuntu 16.04 relies on /sys/class/hwmon
z/sys/class/hwmon/hwmon*/fan*_*z%/sys/class/hwmon/hwmon*/device/fan*_*r   r   r/  Nr   r2  r  r1  )r9  r   rc  r  r;  r   r   r   r   r   r   r   rr   r   r  r   r   r   sfanr=  )r;  r>  rK   rB  rC  r   rD  rE  s           rC   sensors_fansrN    s    
!
!$
'C		:;I IIEF	;AQ;<I	$th/0G RWW__T%:FCDJJL	D8Ob1779gll5:;  9 <  	#J	s   D=E
E"EE"c                    ^ [        5       mU4S jn [        R                  " [        5       Vs/ s H1  nUR	                  S5      (       d  SUR                  5       ;   d  M/  UPM3     nnU(       d  g[        R                  R                  [        [        U5      5      nU " US-   US-   5      nU " US-   US-   5      nU " US	-   US
-   5      nU " US-   5      nUb  Ub
   SU-  U-  nO[        [        US-   SS95      nUS:X  a  gSn	U " [        R                  R                  [        S5      [        R                  R                  [        S5      5      n
U
b  U
S:H  n	O:[        US-   SS9R                  5       R                  5       nUS:X  a  Sn	OUS;   a  Sn	U	(       a  [        R                  nOZUb  Ub   [        U[        U5      -  S-  5      nO8Ub%  [        US-  5      nUS:  a  [        R                   nO[        R                   n[        R"                  " XU	5      $ s  snf ! [         a    Sn GN/f = f! [         a    [        R                   n NKf = f)zReturn battery information.
Implementation note: it appears /sys/class/power_supply/BAT0/
directory structure may vary and provide files with the same
meaning but under different names, see:
https://github.com/giampaolo/psutil/issues/966.
c                     > U  H!  n[        UTS9nUT:w  d  M   [        U5      s  $    g! [         a    UR                  5       s s  $ f = f)zfAttempt to read the content of multiple files which may
not exist. If none of them exist return None.
r1  N)r   r   r  r   )r:  rr   r;  nulls      rC   
multi_bcat#sensors_battery.<locals>.multi_bcat  sR     Dtd+Cd{'s8O	   " '99;&'s   
*A	A	BATbatteryNz/energy_nowz/charge_nowz
/power_nowz/current_nowz/energy_fullz/charge_fullz/time_to_empty_nowg      Y@r   z	/capacityrb  r1  z
AC0/onlinez	AC/onliner   /statusr  dischargingF>   fullchargingTi  <   r   )objectr   rd  POWER_SUPPLY_PATHr   r  rr   r   r   ZeroDivisionErrorr   r   r   r   POWER_TIME_UNLIMITEDabsPOWER_TIME_UNKNOWNsbattery)rR  rK   batsr  
energy_now	power_nowenergy_fulltime_to_emptyr^   power_pluggedonliner  secsleftrQ  s                @rC   sensors_batteryrj    sQ    8D -..A<<)qwwy"8 	
. 	 
  77<<)3t95D D=0$2FGJ4,.~0EFITN2D>4IJKt&::;M :#9	j(;6G c$,r:;b=
 M
&5
&4F !TI%399;AAC]"!M++ M //		I$9	2:I6=>H 
	"}r)*a<11H--G}==C. ! 	G	B ! 	211H	2s/   .H HH" 3H5 "H21H25IIc                      / n [         R                  " 5       nU H;  nUu  p4pVn[        R                  " X4=(       d    SXVU5      nU R	                  U5        M=     U $ )z:Return currently connected users as a list of namedtuples.N)r   usersr   suserr   )	r'  rawlistitemr   ttyhostnametstamprj  nts	            rC   rl  rl    sQ    GjjlG+/(8S]]4hDr  NrB   c                     [        5        S3n [        U 5       nU HN  nUR                  S5      (       d  M  [        UR	                  5       R                  5       S   5      s  sSSS5        $    SU  3n[        U5      e! , (       d  f       g= f)zAReturn the system boot time expressed in seconds since the epoch.r   s   btimer   Nzline 'btime' not found in )r   r   r   r   r   r   r  )rr   r   r   r   s       rC   	boot_timeru  
  s|     &D	T	aDx((TZZ\//1!455 
	 +4&13 
	s   A>+A>,A>>
Bc                      [        5       R                  [        5      n [        R                  " U 5       Vs/ s H$  oR                  5       (       d  M  [        U5      PM&     sn$ s  snf )z7Returns a list of PIDs currently running on the system.)r   rz  r	   r   rd  r  r   )rr   rK   s     rC   rq  rq    sD    ##H-DJJt,<,q		FCF,<<<s   A$A$c                    [         R                  " U 5      (       d  g [        5        SU  S3n[        U5       nU HD  nUR	                  S5      (       d  M  [        UR                  5       S   5      nX@:H  s  sSSS5        $    SU 3n[        U5      e! , (       d  f       g= f! [        [        4 a    U [        5       ;   s $ f = f)z[Check for the existence of a unix PID. Linux TIDs are not
supported (always return False).
Fr   rV  s   Tgid:r   Nz'Tgid' line not found in )
r   
pid_existsr   r   r   r   r   r  r   rq  )rj  rr   r   r   tgidr   s         rC   rx  rx     s     s##	! &'(#g6DT"aDx00"4::<?3  ${* #" 2$8 o% #" $ 	!$&= 	!s:   B% B!B8	B% B
B"B% "B% %CCc                     0 n [        5       n[        5        Hf  n [        U SU S35       nUR                  5       nSSS5        WR	                  S5      nXES-   S R                  5       n[        US   5      nXpU'   Mh     U $ ! , (       d  f       NL= f! [        [        4 a     M  [         a  n[        U5      UeSnAff = f)zkObtain a {pid: ppid, ...} dict for all running processes in
one shot. Used to speed up Process.children().
r   r   N   )r:   r   )r   rq  r   r  r  r   r   re  rf  rs  r   )	r;  r   rj  r   r  rpardsetppidr   s	            rC   ppid_mapr  A  s     C!#Kv	}AcU%89Qvvx : ::d#Dq
#))+DtAw<DH  J :9!#56 	 	-s#,	-s3   BBB
B	BC'	C0B<<Cc                 F   ^  [         R                  " T 5      U 4S j5       nU$ )zdDecorator which translates bare OSError and OSError exceptions
into NoSuchProcess and AccessDenied.
c                   > U R                   U R                  pC T" U /UQ70 UD6$ ! [         a  n[        X45      UeS nAf[         a!  nU R                  5         [        X45      UeS nAf[         aV  nU R                  5         [        R                  R                  U R                   SU S35      (       d  [        X45      Uee S nAff = f)Nr   r   )rj  _namers  r   rf  _raise_if_zombier   re  r   rr   r  r[  )r\  r   kwargsrj  r   r   funs         rC   wrapper wrap_exceptions.<locals>.wrapper\  s    HHdjjT	t-d-f-- 	3s)s2! 	4!!#*3  	!!# 77>>T%6%6$7qU"CDD#C.C7	s+   & 
C<C	A%%C2ACC)	functoolswraps)r  r  s   ` rC   wrap_exceptionsr  W  s'    
 __S $ NrB   c                      \ rS rSrSr/ SQrS rS rS rS r	\
4S jr\\S	 5       5       r\\S
 5       5       r\\S 5       5       rS rS r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\R2                  R5                  S\R6                  " 5        S35      (       a  \S 5       r\S 5       r\S 5       r\S=S j5       r\S>S j5       r \S 5       r!\"(       d  \#(       aI  S r$\\%RL                  " S5      \%RL                  " S5      \%RL                  " S5      4S  j5       r'\S! 5       r(O\!r(\#(       a  \S" 5       r)\S# 5       r*\\%RL                  " S$5      4S% j5       r+\\%RL                  " S&5      4S' j5       r,\S( 5       r-\S) 5       r.\S* 5       r/\0(       a&  \S+ 5       r1\%RL                  " S,5      4S- jr2\S. 5       r3\4(       a  \S/ 5       r5\S0 5       r6\7" \8S15      (       a
  \S=S2 j5       r9\S3 5       r:\S4 5       r;\S?S5 j5       r<\S6 5       r=\S7 5       r>\\%RL                  " S85      4S9 j5       r?\\%RL                  " S:5      4S; j5       r@S<rAg)@Processir  zLinux process implementation.)_cache_ctimer  _ppidr[  rj  c                 X    Xl         S U l        S U l        S U l        [	        5       U l        g rp  )rj  r  r  r  r   r[  )r\  rj  s     rC   r]  Process.__init__~  s'    

+-rB   c                      [        U R                   SU R                   S35      nUR                  S5      nXS-   US-    nUS:H  $ ! [         a     gf = f)Nr   r   r{  r:   r;      ZF)r   r[  rj  r  r   )r\  r  r|  r  s       rC   
_is_zombieProcess._is_zombie  si    	"4,,-Qtxxj>?D ::d#D(TAX.FT>!  		s   %A 
AAc                     U R                  5       (       a+  [        U R                  U R                  U R                  5      eg rp  )r  r   rj  r  r  r\  s    rC   r  Process._raise_if_zombie  s/    ??$**djjAA rB   c                 b    [         R                  " U R                   SU R                   35        g)z+Raise NSP if the process disappeared on us.r   N)r   r  r[  rj  r  s    rC   _raise_if_not_aliveProcess._raise_if_not_alive  s&     	4$$%Qtxxj12rB   c                      [        U5      $ ! [        [        4 a\    [        R                  R                  U R                   SU R                   35      (       a  U R                  5         U[        La  Us $ e f = fr  )
r   re  rf  r   rr   lexistsr[  rj  r  UNSET)r\  rr   r   s      rC   	_readlinkProcess._readlink  sk    	D>!!#56 	ww$"3"3!4AdhhZ@AA%%'5(#O	s   
 A(A97A9c                    [        U R                   SU R                   S35      nUR                  S5      nXR	                  S5      S-   U nXS-   S R                  5       n0 nX5S'   US	   US
'   US   US'   US   US'   US   US'   US   US'   US   US'   US   US'   US   US'   US   US'    US   US'   U$ ! [         a    [        S5        S	US'    U$ f = f)a!  Parse /proc/{pid}/stat file and return a dict with various
process info.
Using "man proc" as a reference: where "man proc" refers to
position N always subtract 3 (e.g ppid position 4 in
'man proc' == position 1 in here).
The return value is cached in case oneshot() ctx manager is
in use.
r   r   r{     (r   r:   Nr   r   r  r~  r   ttynr   utime   stime   children_utimer  children_stime   create_time$   cpu_num'   blkio_ticksz&can't get blkio_ticks, set iowait to 0)r   r[  rj  r  r  r   
IndexErrorr   )r\  r  r|  r   r   r;  s         rC   _parse_stat_fileProcess._parse_stat_file  s-    t(()488*E:; zz$IIdOa'$/Qhj!'')Fq	HQiFayGbzGbzG &r
 &r
#BZMI	#!'C 
  	#:;!"C
	#s   1B; ;CCc                     [        U R                   SU R                   S35       nUR                  5       sSSS5        $ ! , (       d  f       g= f)zwRead /proc/{pid}/stat file and return its content.
The return value is cached in case oneshot() ctx manager is
in use.
r   rV  N)r   r[  rj  r  r\  r   s     rC   _read_status_fileProcess._read_status_file  s<     D--.azABa668 CBBs   A  
Ac                     [        U R                   SU R                   S35       nUR                  5       R	                  5       sS S S 5        $ ! , (       d  f       g = f)Nr   r/   )r   r[  rj  r  r   r  s     rC   _read_smaps_fileProcess._read_smaps_file  sC     D--.az@AQ668>># BAAs   A
Ac                     U R                   R                  U 5        U R                  R                  U 5        U R                  R                  U 5        g rp  )r  cache_activater  r  r  s    rC   oneshot_enterProcess.oneshot_enter  s>    ,,T2--d3,,T2rB   c                     U R                   R                  U 5        U R                  R                  U 5        U R                  R                  U 5        g rp  )r  cache_deactivater  r  r  s    rC   oneshot_exitProcess.oneshot_exit  s>    ..t4//5..t4rB   c                 :    [        U R                  5       S   5      $ )Nr   )r   r  r  s    rC   r   Process.name  s     d++-f566rB   c                 V    U R                  U R                   SU R                   S3SS9$ )Nr   z/exer  r1  r  r[  rj  r  s    rC   exeProcess.exe  5    ~~  !488*D1B  
 	
rB   c                    [        U R                   SU R                   S35       nUR                  5       nS S S 5        W(       d  U R	                  5         / $ UR                  S5      (       a  SOSnUR                  U5      (       a  US S nUR                  U5      nUS:X  a&  [        U5      S:X  a  SU;   a  UR                  S5      nU$ ! , (       d  f       N= f)Nr   z/cmdliner   r   rb  r   )r   r[  rj  r  r  r   r   r   )r\  r   r  sepcmdlines        rC   r  Process.cmdline  s    $++,AdhhZx@AQ668D B!!#I f--f3==9D**S/ &=S\Q.3$;jjoG- BAs   C
Cc                     [        U R                   SU R                   S35       nUR                  5       nS S S 5        [	        W5      $ ! , (       d  f       N= f)Nr   z/environ)r   r[  rj  r  r   )r\  r   r  s      rC   environProcess.environ  sJ    $++,AdhhZx@AQ668D B"4(( BAs   A


Ac                     [        U R                  5       S   5      n[        R                  " 5       n X!   $ ! [         a     g f = f)Nr  )r   r  r   get_terminal_mapr   )r\  tty_nrrZ  s      rC   terminalProcess.terminal  sG    T**,W56((*	< 		s   7 
AAr.   /ioc           	         U R                    SU R                   S3n0 n[        U5       nU H=  nUR                  5       nU(       d  M   UR	                  S5      u  pV[        U5      X%'   M?     S S S 5        U(       d  U S3n[        U5      e [        US   US   US   US   US	   US
   5      $ ! [         a     M  f = f! , (       d  f       NY= f! [         a*  nUR                  S   < SU SU< 3n[        U5      S eS nAff = f)Nr   r  s   : z file was emptys   syscrs   syscws
   read_bytess   write_bytess   rchars   wcharr   z field was not found in z; found fields are )r[  rj  r   r   r   r   r  r  r   r   r   )	r\  fnamer   r   r   r   r  r   r   s	            rC   io_countersProcess.io_counters'  s2   (()488*C8EFU#qD::<Dt6*.**U*;KD
 ,/u:FL  $ /"3''08$8$=)>*8$8$   * %$% $#0  0xx{o%=eW E##)*.  !o4/0sG   C
B0C!C 0
B>:C=B>>C
C
D%DDc                    U R                  5       n[        US   5      [        -  n[        US   5      [        -  n[        US   5      [        -  n[        US   5      [        -  n[        US   5      [        -  n[        X#XEU5      $ )Nr  r  r  r  r  )r  r   r   r   )r\  r   r  r  r  r  r   s          rC   r   Process.cpu_timesJ  s    &&(fWo&4fWo&4v&678;Fv&678;Fvm,-;~vNNrB   c                 :    [        U R                  5       S   5      $ )zWhat CPU the process is on.r  r   r  r  s    rC   r  Process.cpu_numT  s     4((*9566rB   Nc                 X    [         R                  " U R                  XR                  5      $ rp  )r   wait_pidrj  r  )r\  timeouts     rC   waitProcess.waitY  s      7JJ??rB   c                     U R                   c(  [        U R                  5       S   5      [        -  U l         U(       a  U R                   $ U R                   [	        5       -   $ )Nr  )r  r   r  r   ru  )r\  	monotonics     rC   r  Process.create_time]  sR     ;;d++-m<=K K ;; {{Y[((rB   c           	          [        U R                   SU R                   S35       nS UR                  5       R	                  5       S S  5       u  p#pEpgnS S S 5        [        WWWWWWW5      $ ! , (       d  f       N= f)Nr   z/statmc              3   F   #    U  H  n[        U5      [        -  v   M     g 7frp  )r   r   ).0rK   s     rC   	<genexpr>&Process.memory_info.<locals>.<genexpr>|  s      8+CaA!+Cs   !r  )r   r[  rj  r   r   rw   )	r\  r   vmsr}   re   textlibr  dirtys	            rC   memory_infoProcess.memory_infon  s}     D--.az@AQ8+,::<+=+=+?+C84CfCu B CfdCu==	 BAs   .A--
A;c                    S=n=p#[        U R                   SU R                   S35       nU H  nUR                  S5      (       a$  U[	        UR                  5       S   5      S-  -  nM=  UR                  S5      (       a!  [	        UR                  5       S   5      S-  nMt  UR                  S5      (       d  M  [	        UR                  5       S   5      S-  nM     S S S 5        XU4$ ! , (       d  f       N= f)	Nr   r   r0   s   Private_r   r      Pss:   Swap:)r   r[  rj  r   r   r   )r\  ry   rz   r{   r   r   s         rC   _parse_smaps_rollupProcess._parse_smaps_rollup  s      ! C #$$%Qtxxj>D{33s4::<?3d::11!$**,q/2T922"4::<?3d:  d## s   BC):#C))
C7s   \nPrivate.*:\s+(\d+)s   \nPss\:\s+(\d+)s   \nSwap\:\s+(\d+)c                 ,   U R                  5       n[        [        [        UR	                  U5      5      5      S-  n[        [        [        UR	                  U5      5      5      S-  n[        [        [        UR	                  U5      5      5      S-  nXVU4$ )Nr   )r  r  r  r   findall)r\  _private_re_pss_re_swap_re
smaps_datary   rz   r{   s           rC   _parse_smapsProcess._parse_smaps  s    * ..0J c#{22:>?@4GCc#wz:;<tCCs3 0 0 <=>EDd##rB   c                     [         (       a   U R                  5       u  pnOU R	                  5       u  pnU R                  5       n[        XAX#4-   6 $ ! [        [        4 a    U R	                  5       u  pn NAf = frp  )HAS_PROC_SMAPS_ROLLUPr  rf  re  r  r  rx   )r\  ry   rz   r{   	basic_mems        rC   memory_full_infoProcess.memory_full_info  s}    $$9%)%=%=%?NCd "&!2!2!4$((*IYs)99:: +,=> 9%)%6%6%8NCd9s   A #A65A6c                 ~   S nU R                  5       nU(       d  U R                  5         / $ UR                  S5      n/ nUR                  S5      nU/nU" X65       GHA  u  prUR                  SS5      n Uu  pppU(       d  SnOF[        U5      nUR                  5       nUR                  S5      (       a  [        U5      (       d  USS	 n[        U	5      [        U
5      UUR                  S
S5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      4nUR                  U5        GMD     U$ ! [         a    US/-   u  ppp GN@f = f)a  Return process's mapped memory regions as a list of named
tuples. Fields are explained in 'man proc'; here is an updated
(Apr 2012) version: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt?id=b76437579d1344b612cf1851ae610c636cec7db0.

/proc/{PID}/smaps does not exist on kernels < 2.6.14 or if
CONFIG_MMU kernel configuration option is not enabled.
c              3     #    0 nU  Hl  nUR                  S S5      nUS   R                  S5      (       d'  UR                  5       U4v   UR                  U5        MU   [	        US   5      S-  X$S   '   Mn     UR                  5       U4v   g ! [
        [        4 a/    US   R                  S5      (       a   M  SU< 3n[        U5      S ef = f7f)N   r   r(  r   r   s   VmFlags:z!don't know how to interpret line )r   r   popr   r   r  r  r   )r  current_blockr  r   r   r   s         rC   
get_blocks'Process.memory_maps.<locals>.get_blocks  s     !D!ZZa0F!!9--d33,002D99%,,T2<.1&)nt.CDO " %((*D11 !+J7 <%ay33K@@ ($EdX"NC",S/t;<s*   ACB3C)C5C8CC   
r   Nr  r  z[anon]r   r   s   Rss:s   Size:r  s   Shared_Clean:s   Shared_Dirty:s   Private_Clean:s   Private_Dirty:s   Referenced:s
   Anonymous:r  )r  r  r   r  r  r   r   r   r   r   r   )r\  r
  r  r  r  
first_liner	  headerhfieldsr  perms_offset_dev_inoderr   ro  s                   rC   memory_mapsProcess.memory_maps  s   2& ((*D %%'	JJu%EB1J'LM *5 @ ,,tQ/N?F<D #D!$<D::<D}}\22;M< <  $DSz4L5MHHWa(HHXq)HHWa(HH-q1HH-q1HH.2HH.2HH^Q/HH]A.HHXq) 		$= !A> I7 " N?F"~<DNs   5F$$F<;F<c                 V    U R                  U R                   SU R                   S3SS9$ )Nr   z/cwdr  r1  r  r  s    rC   cwdProcess.cwd  r  rB   s   ctxt_switches:\t(\d+)c                     U R                  5       nUR                  U5      nU(       d(  SU R                   SU R                   S3n[	        U5      e[
        R                  " [        US   5      [        US   5      5      $ )NzR'voluntary_ctxt_switches' and 'nonvoluntary_ctxt_switches'lines were not found in r   z1/status; the kernel is probably older than 2.6.23r   r   )r  r  r[  rj  r8  r   pctxswr   )r\  	_ctxsw_rer  ctxswr   s        rC   num_ctx_switchesProcess.num_ctx_switches  s}     %%'!!$'%%&az 2..  &c**~~c%(mSq];;rB   s   Threads:\t(\d+)c                 \    U R                  5       n[        UR                  U5      S   5      $ Nr   )r  r   r  )r\  _num_threads_rer  s      rC   num_threadsProcess.num_threads&  s-     %%'?**40344rB   c                    [         R                  " U R                   SU R                   S35      nUR	                  5         / nSnU H  nU R                   SU R                   SU S3n [        U5       nUR                  5       R                  5       nS S S 5        WUR                  S5      S-   S  nUR                  S	5      n[        US
   5      [        -  n	[        US   5      [        -  n
[        R                  " [!        U5      X5      nUR#                  U5        M     U(       a  U R%                  5         U$ ! , (       d  f       N= f! [        [        4 a    Sn GM  f = f)Nr   z/taskFz/task/r   Tr{  r:   r   r  r  )r   rd  r[  rj  r5  r   r  r   re  rf  r  r   r   r   r   pthreadr   r   r  )r\  
thread_idsr'  
hit_enoent	thread_idr  r   str   r  r  r-  s               rC   threadsProcess.threads,  s;   ZZ4#4#4"5Qtxxj FG

#I(()488*F9+UKE '1)B ( BGGDMA%'(BXXd^F&*%3E&*%3E__S^UBFNN6"! $" $$&! ('%'9:  "
	s0   *E5D<E<
E
	E
EE$#E$c                 B    [         R                  " U R                  5      $ rp  )r   proc_priority_getrj  r  s    rC   nice_getProcess.nice_getG  s     %%dhh//rB   c                 D    [         R                  " U R                  U5      $ rp  )r   proc_priority_setrj  )r\  r  s     rC   nice_setProcess.nice_setP  s    %%dhh66rB   c                 B    [         R                  " U R                  5      $ rp  )r   r2   rj  r  s    rC   cpu_affinity_getProcess.cpu_affinity_getW  s    --dhh77rB   s   Cpus_allowed_list:\t(\d+)-(\d+)c           	         U R                  5       nUR                  U5      nU(       a6  [        [        [	        US   S   5      [	        US   S   5      S-   5      5      $ [        [        [        [        5       5      5      5      $ )Nr   r   )r  r  rc  ranger   r   r  )r\  _rer  r  s       rC   _get_eligible_cpusProcess._get_eligible_cpus[  sk     ))+DKK%EE#eAhqk"2Ca4Dq4HIJJE#mo"6788rB   c           	          [         R                  " U R                  U5        g ! [        [        4 a  n[        U[        5      (       d  UR                  [        R                  :X  ar  U R                  5       n[        [        [        [        5       5      5      5      nU H7  nXT;  a  SU< SU< 3n[	        U5      S eXS;  d  M%  SU SU 3n[	        U5      Ue   e S nAff = f)Nzinvalid CPU z; choose between zCPU number z! is not eligible; choose between )r   proc_cpu_affinity_setrj  r   r  r   rg  rh  r:  tupler8  r   r  )r\  r   r   eligible_cpusall_cpuscpur   s          rC   cpu_affinity_setProcess.cpu_affinity_setf  s    **488T:Z( c:..#))u||2K$($;$;$=M$U3}+?%@AH#.".sg 6$$1#4!6   #-S/t;3"-cU 3,,9?!<   #-S/s:  $ #s   !$ CBCCCc                     [         R                  " U R                  5      u  p[        U5      n[        R
                  " X5      $ rp  )r   r1   rj  r8   r   pionice)r\  ioclassr  s      rC   
ionice_getProcess.ionice_get  s1    !11$((;NG )G??722rB   c                     Uc  SnU(       a5  U[         R                  [         R                  1;   a  U< S3n[        U5      eUS:  d  US:  a  Sn[        U5      e[        R
                  " U R                  X5      $ )Nr   z ioclass accepts no valuer  zvalue not in 0-7 range)r8   r"   r   r  r   proc_ioprio_setrj  )r\  rF  r  r   s       rC   
ionice_setProcess.ionice_set  sy    },,,,%  !#<= o%qyEAI. o%'''AArB   prlimitc                    U R                   S:X  a  Sn[        U5      e Uc!  [        R                  " U R                   U5      $ [	        U5      S:w  a  SU< 3n[        U5      e[        R                  " U R                   X5        g ! [
         a4  nUR                  [        R                  :X  a  U R                  5         e S nAff = f)Nr   z)can't use prlimit() against PID 0 processr:   z2second argument must be a (soft, hard) tuple, got )	rj  r  resourcerM  r   r   rg  ENOSYSr  )r\  	resource_limitsr   r   s        rC   rlimitProcess.rlimit  s    
 xx1}A o%>#++DHHi@@ 6{a'**05  )o-$$TXXyA 99, ))+s   #B AB 
C/B>>Cc                 t    U R                  5       S   nUR                  5       n[        R                  US5      $ )Nr  ?)r  r   PROC_STATUSESr   )r\  letters     rC   r  Process.status  s3    &&(2  --rB   c                 6   / n[         R                  " U R                   SU R                   S35      nSnU GH  nU R                   SU R                   SU 3n [	        U5      nUR                  S5      (       a  [        U5      (       a  U R                   SU R                   SU 3n [        U5       n[        UR                  5       R                  5       S   5      n[        UR                  5       R                  5       S   S5      n	S S S 5        [        W	5      n
[        U[        U5      [        W5      X5      nUR                  U5        GM  GM  GM!     U(       a  U R+                  5         U$ ! , (       d  f       Nn= f! [        [        4 a    Sn GMc  f = f! [        [        4 a    Sn GM}  [          a[  nUR"                  ["        R$                  :X  a   S nAGM  UR"                  ["        R&                  :X  a  [)        U5         S nAGM  e S nAff = f)	Nr   r`  Fra  z/fdinfo/r   r   T)r   rd  r[  rj  r   r   r   r   r   r   r   r   rq   r   re  rf  r   rg  rh  ri  r   r  )r\  r'  r  r'  rs   r  rr   r   posrv   ru   r-  r   s                rC   
open_filesProcess.open_files  s   

d//0$((3?@
B''($((4t<D$/~& ??3''M$,?,?"//0$((8B4HD/(.!"%ajjl&8&8&:1&=">C$'

(:(:(<Q(?$CE /  2%8!* #b'3s8T"  v.! -@'- N $$& /. ./AB * &*
*3 &'9: !
 99,99 2 22#JsU   F*F5AE3F3
F	=FFFH4	H=H")HHHc                 d    [         R                  XR                  5      nU R                  5         U$ rp  )r  r  rj  r  )r\  r  r;  s      rC   r  Process.net_connections  s'    ''hh7  "
rB   c                 t    [        [        R                  " U R                   SU R                   S35      5      $ )Nr   r`  )r   r   rd  r[  rj  r  s    rC   num_fdsProcess.num_fds  s.    2::!2!2 31TXXJcBCDDrB   c                 :    [        U R                  5       S   5      $ )Nr~  r  r  s    rC   r~  Process.ppid  s    4((*6233rB   s   Uid:\t(\d+)\t(\d+)\t(\d+)c                     U R                  5       nUR                  U5      S   u  p4n[        R                  " [	        U5      [	        U5      [	        U5      5      $ r   )r  r  r   puidsr   )r\  _uids_rer  real	effectivesaveds         rC   uidsProcess.uids  I    %%'!)!1!1$!7!:}}SYIE
CCrB   s   Gid:\t(\d+)\t(\d+)\t(\d+)c                     U R                  5       nUR                  U5      S   u  p4n[        R                  " [	        U5      [	        U5      [	        U5      5      $ r   )r  r  r   pgidsr   )r\  _gids_rer  rh  ri  rj  s         rC   gidsProcess.gids  rm  rB   )r  r  r  r[  rj  rp  FrQ  )Br=   r>   r?   r@   r  r  r]  r  r  r  r  r  r  r   r  r  r  r  r  r   r  r  r  r  r   rr   r  getpidr  r   r  r  r  r  r  HAS_PROC_SMAPSr  r	  r
  r  r  r  r  r  r"  r*  r.  r2  HAS_CPU_AFFINITYr5  r:  rB  HAS_PROC_IO_PRIORITYrG  rK  hasattrrO  rS  r  r\  r  ra  r~  rk  rq  rA   r<   rB   rC   r  r  r  s   'I." B3 (-   #  #J    $  $3
5
 7 7 
 

  2 ) )
   
ww~~ryy{m3/00	 	0 
 	0D O O 7 7 @ @ ) )  > >$ 	$. 
 

#;<JJ23ZZ 45	$ 
	$8 
		; 
		; '	E	 
E	N 
 

 

#<=< < *,**5H*I 5 5
  4 0 0 7 7 		8 
	8 jj!DE		9 
	 
	. 		3 
	3
 
	B 
	B x##		 
	6 . . - -^  
 E E 4 4 JJ'DE D D
 JJ'DE D DrB   r  rt  rs  )r  r}  r9  enumrg  r  r  r   r	  rO  rT  r  sysr   r   r   r  r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __extra__all__r\  rr   r  ru  rv  r  ry  rx  rw  r  r   getpagesizer   	byteorderr{  r[  r  r  IntEnumr   	AF_PACKETr5   r6   r8   globalsrr  __members__STATUS_RUNNINGSTATUS_SLEEPINGSTATUS_DISK_SLEEPSTATUS_STOPPEDSTATUS_TRACING_STOPSTATUS_ZOMBIESTATUS_DEADSTATUS_WAKE_KILLSTATUS_WAKINGSTATUS_IDLESTATUS_PARKEDrW  r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r  r[   rg   rq   rw   r   rx   r|   r   r   r   r   r   r   r   r   	Exceptionr   r   r   r   r   r   r  r  r  r&  r)  rB  net_if_addrsrE  rG  r  r  r  r  
disk_usager  r  r"  rK  rN  rj  rl  ru  rq  rx  r  r  r  r<   rB   rC   <module>r     s  
 %       	 	    
  # "   #  $ $ ' ! " "     $ "  +    ( ' " "	$ . &V <=		}M'JK t%67 4!89  jj&)  iV%5%5!67 

  	  '' ( 
				 	 		"	"					$	$											!	!									" 
"
"







 
 

 
 

 
 




!
!








, 	 K	L   <>	 &>?j$,,1G"GHJK
 -*?*?!@@B	  6 7 {"#	(
$& 	0 	00K!<~~B4@x (:'T2
 77>>;<<*A A#NP   	I 	k k\ "# +
,^B   
fRH HV$Xsl>W>~  =!B,6P
D P
DG+  K	*3'
23;(:;CcJIKs   Q' 'R-RR