summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2022-01-08 00:05:00 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2022-01-08 00:05:00 +0100
commitd264efd1734f9324f63f77d19c3e2350d01c41e6 (patch)
tree9ebeac482ae976f4a0d1e4cd6428bcb8b171eb4c
parent3937cda869460007742e525ed4af6a68f9af6a09 (diff)
downloadpsutil-d264efd1734f9324f63f77d19c3e2350d01c41e6.tar.gz
add bcat() utility
Signed-off-by: Giampaolo Rodola <g.rodola@gmail.com>
-rw-r--r--psutil/_pslinux.py95
1 files changed, 53 insertions, 42 deletions
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index ab1b6f1b..60959871 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -283,20 +283,33 @@ def set_scputimes_ntuple(procfs_path):
scputimes = namedtuple('scputimes', fields)
-def cat(fname, fallback=_DEFAULT, binary=True):
- """Return file content.
- fallback: the value returned in case the file does not exist or
- cannot be read
- binary: whether to open the file in binary or text mode.
+def cat(fname, fallback=_DEFAULT):
+ """Return file content. File is opened in text mode.
+ If specified, `fallback` is the value returned in case of error,
+ either if the file does not exist or cannot be read().
"""
- try:
- with open_binary(fname) if binary else open_text(fname) as f:
- return f.read().strip()
- except (IOError, OSError):
- if fallback is not _DEFAULT:
+ if fallback is _DEFAULT:
+ with open_text(fname) as f:
+ return f.read()
+ else:
+ try:
+ with open_text(fname) as f:
+ return f.read()
+ except (IOError, OSError):
+ return fallback
+
+
+def bcat(fname, fallback=_DEFAULT):
+ """Same as above but in binary mode."""
+ if fallback is _DEFAULT:
+ with open_binary(fname) as f:
+ return f.read()
+ else:
+ try:
+ with open_binary(fname) as f:
+ return f.read()
+ except (IOError, OSError):
return fallback
- else:
- raise
try:
@@ -751,17 +764,17 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \
# https://github.com/giampaolo/psutil/issues/1851
curr = cpuinfo_freqs[i] * 1000
else:
- curr = cat(pjoin(path, "scaling_cur_freq"), fallback=None)
+ curr = bcat(pjoin(path, "scaling_cur_freq"), fallback=None)
if curr is None:
# Likely an old RedHat, see:
# https://github.com/giampaolo/psutil/issues/1071
- curr = cat(pjoin(path, "cpuinfo_cur_freq"), fallback=None)
+ curr = bcat(pjoin(path, "cpuinfo_cur_freq"), fallback=None)
if curr is None:
raise NotImplementedError(
"can't find current frequency file")
curr = int(curr) / 1000
- max_ = int(cat(pjoin(path, "scaling_max_freq"))) / 1000
- min_ = int(cat(pjoin(path, "scaling_min_freq"))) / 1000
+ max_ = int(bcat(pjoin(path, "scaling_max_freq"))) / 1000
+ min_ = int(bcat(pjoin(path, "scaling_min_freq"))) / 1000
ret.append(_common.scpufreq(curr, min_, max_))
return ret
@@ -1349,9 +1362,9 @@ def sensors_temperatures():
for base in basenames:
try:
path = base + '_input'
- current = float(cat(path)) / 1000.0
+ current = float(bcat(path)) / 1000.0
path = os.path.join(os.path.dirname(base), 'name')
- unit_name = cat(path, binary=False)
+ unit_name = cat(path).strip()
except (IOError, OSError, ValueError):
# A lot of things can go wrong here, so let's just skip the
# whole entry. Sure thing is Linux's /sys/class/hwmon really
@@ -1363,9 +1376,9 @@ def sensors_temperatures():
# https://github.com/giampaolo/psutil/issues/1323
continue
- high = cat(base + '_max', fallback=None)
- critical = cat(base + '_crit', fallback=None)
- label = cat(base + '_label', fallback='', binary=False)
+ high = bcat(base + '_max', fallback=None)
+ critical = bcat(base + '_crit', fallback=None)
+ label = cat(base + '_label', fallback='').strip()
if high is not None:
try:
@@ -1388,9 +1401,9 @@ def sensors_temperatures():
for base in basenames:
try:
path = os.path.join(base, 'temp')
- current = float(cat(path)) / 1000.0
+ current = float(bcat(path)) / 1000.0
path = os.path.join(base, 'type')
- unit_name = cat(path, binary=False)
+ unit_name = cat(path).strip()
except (IOError, OSError, ValueError) as err:
debug(err)
continue
@@ -1402,13 +1415,13 @@ def sensors_temperatures():
high = None
for trip_point in trip_points:
path = os.path.join(base, trip_point + "_type")
- trip_type = cat(path, fallback='', binary=False)
+ trip_type = cat(path, fallback='').strip()
if trip_type == 'critical':
- critical = cat(os.path.join(base, trip_point + "_temp"),
- fallback=None)
+ critical = bcat(os.path.join(base, trip_point + "_temp"),
+ fallback=None)
elif trip_type == 'high':
- high = cat(os.path.join(base, trip_point + "_temp"),
- fallback=None)
+ high = bcat(os.path.join(base, trip_point + "_temp"),
+ fallback=None)
if high is not None:
try:
@@ -1446,13 +1459,12 @@ def sensors_fans():
basenames = sorted(set([x.split('_')[0] for x in basenames]))
for base in basenames:
try:
- current = int(cat(base + '_input'))
+ current = int(bcat(base + '_input'))
except (IOError, OSError) as err:
debug(err)
continue
- unit_name = cat(os.path.join(os.path.dirname(base), 'name'),
- binary=False)
- label = cat(base + '_label', fallback='', binary=False)
+ unit_name = cat(os.path.join(os.path.dirname(base), 'name'))
+ label = cat(base + '_label', fallback='')
ret[unit_name].append(_common.sfan(label, current))
return dict(ret)
@@ -1467,12 +1479,12 @@ def sensors_battery():
"""
null = object()
- def multi_cat(*paths):
+ def multi_bcat(*paths):
"""Attempt to read the content of multiple files which may
not exist. If none of them exist return None.
"""
for path in paths:
- ret = cat(path, fallback=null)
+ ret = bcat(path, fallback=null)
if ret != null:
try:
return int(ret)
@@ -1490,16 +1502,16 @@ def sensors_battery():
root = os.path.join(POWER_SUPPLY_PATH, sorted(bats)[0])
# Base metrics.
- energy_now = multi_cat(
+ energy_now = multi_bcat(
root + "/energy_now",
root + "/charge_now")
- power_now = multi_cat(
+ power_now = multi_bcat(
root + "/power_now",
root + "/current_now")
- energy_full = multi_cat(
+ energy_full = multi_bcat(
root + "/energy_full",
root + "/charge_full")
- time_to_empty = multi_cat(root + "/time_to_empty_now")
+ time_to_empty = multi_bcat(root + "/time_to_empty_now")
# Percent. If we have energy_full the percentage will be more
# accurate compared to reading /capacity file (float vs. int).
@@ -1517,13 +1529,13 @@ def sensors_battery():
# Note: AC0 is not always available and sometimes (e.g. CentOS7)
# it's called "AC".
power_plugged = None
- online = multi_cat(
+ online = multi_bcat(
os.path.join(POWER_SUPPLY_PATH, "AC0/online"),
os.path.join(POWER_SUPPLY_PATH, "AC/online"))
if online is not None:
power_plugged = online == 1
else:
- status = cat(root + "/status", fallback="", binary=False).lower()
+ status = cat(root + "/status", fallback="").strip().lower()
if status == "discharging":
power_plugged = False
elif status in ("charging", "full"):
@@ -1700,8 +1712,7 @@ class Process(object):
The return value is cached in case oneshot() ctx manager is
in use.
"""
- with open_binary("%s/%s/stat" % (self._procfs_path, self.pid)) as f:
- data = f.read()
+ data = bcat("%s/%s/stat" % (self._procfs_path, self.pid))
# Process name is between parentheses. It can contain spaces and
# other parentheses. This is taken into account by looking for
# the first occurrence of "(" and the last occurence of ")".