/pypags/psutil-0.7.1/psutil/_psposix.py
Python | 121 lines | 93 code | 9 blank | 19 comment | 17 complexity | 057b9d548738c592c1996da35f8e2817 MD5 | raw file
- #!/usr/bin/env python
- # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """Routines common to all posix systems."""
- import os
- import errno
- import psutil
- import sys
- import time
- import glob
- from psutil._error import TimeoutExpired
- from psutil._common import nt_diskinfo, usage_percent, memoize
- def pid_exists(pid):
- """Check whether pid exists in the current process table."""
- if pid < 0:
- return False
- try:
- os.kill(pid, 0)
- except OSError:
- e = sys.exc_info()[1]
- return e.errno == errno.EPERM
- else:
- return True
- def wait_pid(pid, timeout=None):
- """Wait for process with pid 'pid' to terminate and return its
- exit status code as an integer.
- If pid is not a children of os.getpid() (current process) just
- waits until the process disappears and return None.
- If pid does not exist at all return None immediately.
- Raise TimeoutExpired on timeout expired.
- """
- def check_timeout(delay):
- if timeout is not None:
- if timer() >= stop_at:
- raise TimeoutExpired(pid)
- time.sleep(delay)
- return min(delay * 2, 0.04)
- timer = getattr(time, 'monotonic', time.time)
- if timeout is not None:
- waitcall = lambda: os.waitpid(pid, os.WNOHANG)
- stop_at = timer() + timeout
- else:
- waitcall = lambda: os.waitpid(pid, 0)
- delay = 0.0001
- while 1:
- try:
- retpid, status = waitcall()
- except OSError:
- err = sys.exc_info()[1]
- if err.errno == errno.EINTR:
- delay = check_timeout(delay)
- continue
- elif err.errno == errno.ECHILD:
- # This has two meanings:
- # - pid is not a child of os.getpid() in which case
- # we keep polling until it's gone
- # - pid never existed in the first place
- # In both cases we'll eventually return None as we
- # can't determine its exit status code.
- while 1:
- if pid_exists(pid):
- delay = check_timeout(delay)
- else:
- return
- else:
- raise
- else:
- if retpid == 0:
- # WNOHANG was used, pid is still running
- delay = check_timeout(delay)
- continue
- # process exited due to a signal; return the integer of
- # that signal
- if os.WIFSIGNALED(status):
- return os.WTERMSIG(status)
- # process exited using exit(2) system call; return the
- # integer exit(2) system call has been called with
- elif os.WIFEXITED(status):
- return os.WEXITSTATUS(status)
- else:
- # should never happen
- raise RuntimeError("unknown process exit status")
- def get_disk_usage(path):
- """Return disk usage associated with path."""
- st = os.statvfs(path)
- free = (st.f_bavail * st.f_frsize)
- total = (st.f_blocks * st.f_frsize)
- used = (st.f_blocks - st.f_bfree) * st.f_frsize
- percent = usage_percent(used, total, _round=1)
- # NB: the percentage is -5% than what shown by df due to
- # reserved blocks that we are currently not considering:
- # http://goo.gl/sWGbH
- return nt_diskinfo(total, used, free, percent)
- @memoize
- def _get_terminal_map():
- ret = {}
- ls = glob.glob('/dev/tty*') + glob.glob('/dev/pts/*')
- for name in ls:
- assert name not in ret
- try:
- ret[os.stat(name).st_rdev] = name
- except OSError:
- err = sys.exc_info()[1]
- if err.errno != errno.ENOENT:
- raise
- return ret