diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2022-01-08 00:05:00 +0100 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2022-01-08 00:05:00 +0100 |
commit | d264efd1734f9324f63f77d19c3e2350d01c41e6 (patch) | |
tree | 9ebeac482ae976f4a0d1e4cd6428bcb8b171eb4c | |
parent | 3937cda869460007742e525ed4af6a68f9af6a09 (diff) | |
download | psutil-d264efd1734f9324f63f77d19c3e2350d01c41e6.tar.gz |
add bcat() utility
Signed-off-by: Giampaolo Rodola <g.rodola@gmail.com>
-rw-r--r-- | psutil/_pslinux.py | 95 |
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 ")". |