comparison env/lib/python3.7/site-packages/psutil/_psposix.py @ 2:6af9afd405e9 draft

"planemo upload commit 0a63dd5f4d38a1f6944587f52a8cd79874177fc1"
author shellac
date Thu, 14 May 2020 14:56:58 -0400
parents 26e78fe6e8c4
children
comparison
equal deleted inserted replaced
1:75ca89e9b81c 2:6af9afd405e9
1 # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Routines common to all posix systems."""
6
7 import glob
8 import os
9 import sys
10 import time
11
12 from ._common import memoize
13 from ._common import sdiskusage
14 from ._common import TimeoutExpired
15 from ._common import usage_percent
16 from ._compat import ChildProcessError
17 from ._compat import FileNotFoundError
18 from ._compat import InterruptedError
19 from ._compat import PermissionError
20 from ._compat import ProcessLookupError
21 from ._compat import PY3
22 from ._compat import unicode
23
24
25 __all__ = ['pid_exists', 'wait_pid', 'disk_usage', 'get_terminal_map']
26
27
28 def pid_exists(pid):
29 """Check whether pid exists in the current process table."""
30 if pid == 0:
31 # According to "man 2 kill" PID 0 has a special meaning:
32 # it refers to <<every process in the process group of the
33 # calling process>> so we don't want to go any further.
34 # If we get here it means this UNIX platform *does* have
35 # a process with id 0.
36 return True
37 try:
38 os.kill(pid, 0)
39 except ProcessLookupError:
40 return False
41 except PermissionError:
42 # EPERM clearly means there's a process to deny access to
43 return True
44 # According to "man 2 kill" possible error values are
45 # (EINVAL, EPERM, ESRCH)
46 else:
47 return True
48
49
50 def wait_pid(pid, timeout=None, proc_name=None):
51 """Wait for process with pid 'pid' to terminate and return its
52 exit status code as an integer.
53
54 If pid is not a children of os.getpid() (current process) just
55 waits until the process disappears and return None.
56
57 If pid does not exist at all return None immediately.
58
59 Raise TimeoutExpired on timeout expired.
60 """
61 def check_timeout(delay):
62 if timeout is not None:
63 if timer() >= stop_at:
64 raise TimeoutExpired(timeout, pid=pid, name=proc_name)
65 time.sleep(delay)
66 return min(delay * 2, 0.04)
67
68 timer = getattr(time, 'monotonic', time.time)
69 if timeout is not None:
70 def waitcall():
71 return os.waitpid(pid, os.WNOHANG)
72 stop_at = timer() + timeout
73 else:
74 def waitcall():
75 return os.waitpid(pid, 0)
76
77 delay = 0.0001
78 while True:
79 try:
80 retpid, status = waitcall()
81 except InterruptedError:
82 delay = check_timeout(delay)
83 except ChildProcessError:
84 # This has two meanings:
85 # - pid is not a child of os.getpid() in which case
86 # we keep polling until it's gone
87 # - pid never existed in the first place
88 # In both cases we'll eventually return None as we
89 # can't determine its exit status code.
90 while True:
91 if pid_exists(pid):
92 delay = check_timeout(delay)
93 else:
94 return
95 else:
96 if retpid == 0:
97 # WNOHANG was used, pid is still running
98 delay = check_timeout(delay)
99 continue
100 # process exited due to a signal; return the integer of
101 # that signal
102 if os.WIFSIGNALED(status):
103 return -os.WTERMSIG(status)
104 # process exited using exit(2) system call; return the
105 # integer exit(2) system call has been called with
106 elif os.WIFEXITED(status):
107 return os.WEXITSTATUS(status)
108 else:
109 # should never happen
110 raise ValueError("unknown process exit status %r" % status)
111
112
113 def disk_usage(path):
114 """Return disk usage associated with path.
115 Note: UNIX usually reserves 5% disk space which is not accessible
116 by user. In this function "total" and "used" values reflect the
117 total and used disk space whereas "free" and "percent" represent
118 the "free" and "used percent" user disk space.
119 """
120 if PY3:
121 st = os.statvfs(path)
122 else:
123 # os.statvfs() does not support unicode on Python 2:
124 # - https://github.com/giampaolo/psutil/issues/416
125 # - http://bugs.python.org/issue18695
126 try:
127 st = os.statvfs(path)
128 except UnicodeEncodeError:
129 if isinstance(path, unicode):
130 try:
131 path = path.encode(sys.getfilesystemencoding())
132 except UnicodeEncodeError:
133 pass
134 st = os.statvfs(path)
135 else:
136 raise
137
138 # Total space which is only available to root (unless changed
139 # at system level).
140 total = (st.f_blocks * st.f_frsize)
141 # Remaining free space usable by root.
142 avail_to_root = (st.f_bfree * st.f_frsize)
143 # Remaining free space usable by user.
144 avail_to_user = (st.f_bavail * st.f_frsize)
145 # Total space being used in general.
146 used = (total - avail_to_root)
147 # Total space which is available to user (same as 'total' but
148 # for the user).
149 total_user = used + avail_to_user
150 # User usage percent compared to the total amount of space
151 # the user can use. This number would be higher if compared
152 # to root's because the user has less space (usually -5%).
153 usage_percent_user = usage_percent(used, total_user, round_=1)
154
155 # NB: the percentage is -5% than what shown by df due to
156 # reserved blocks that we are currently not considering:
157 # https://github.com/giampaolo/psutil/issues/829#issuecomment-223750462
158 return sdiskusage(
159 total=total, used=used, free=avail_to_user, percent=usage_percent_user)
160
161
162 @memoize
163 def get_terminal_map():
164 """Get a map of device-id -> path as a dict.
165 Used by Process.terminal()
166 """
167 ret = {}
168 ls = glob.glob('/dev/tty*') + glob.glob('/dev/pts/*')
169 for name in ls:
170 assert name not in ret, name
171 try:
172 ret[os.stat(name).st_rdev] = name
173 except FileNotFoundError:
174 pass
175 return ret