Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/psutil/_psposix.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
| author | shellac |
|---|---|
| date | Mon, 01 Jun 2020 08:59:25 -0400 |
| parents | 79f47841a781 |
| children |
comparison
equal
deleted
inserted
replaced
| 4:79f47841a781 | 5:9b1c78e6ba9c |
|---|---|
| 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 |
