Mercurial > repos > shellac > guppy_basecaller
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 |