def mountinfo(self): """ Parses /proc/<pid>/mountinfo and returns a list of AttrDict's """ fields = ('mnt_id', 'parent_id', 'major', 'minor', 'root', 'mount', 'options', 'optional', 'fstype', 'source', 'super_options') with open("mountinfo", opener=self._opener) as file: lines = file.read().splitlines() regex = r'(\S+) (\S+) (\d+):(\d+) (\S+) (\S+) (\S+) (.*? - )(\S+) (\S+) (\S+)' entries = [ AttrDict(zip(fields, re.findall(regex, _)[0])) for _ in lines ] for entry in entries: entry.update( mount=Pathname(entry.mount), optional=AttrDict([ _.split(':') for _ in entry.optional[:-len(" - ")].split() ]), options=AttrDict({ k: try_int(v[0]) if v else None for k, *v in [_.split('=', 1) for _ in entry.options.split(',')] }), super_options=AttrDict({ k: try_int(v[0]) if v else None for k, *v in [_.split('=', 1) for _ in entry.super_options.split(',')] })) return entries
def status(self): """ Parses /proc/<pid>/status and returns an AttrDict """ fields = ('real', 'effective', 'saved_set', 'filesystem') with open("status", opener=self._opener) as file: lines = file.read().splitlines() status = AttrDict( {k: try_int(v) for k, v in [_.split(':\t', 1) for _ in lines]}) status.update({ 'Uid': AttrDict(zip(fields, map(Uid, status.Uid.split()))), 'Gid': AttrDict(zip(fields, map(Gid, status.Gid.split()))), 'Groups': list(map(Gid, str(status.Groups).split())) }) status.update({ k: int(status[k].replace('kB', '').strip()) for k in ('HugetlbPages', 'RssAnon', 'RssFile', 'RssShmem', 'VmData', 'VmExe', 'VmHWM', 'VmLck', 'VmLib', 'VmPeak', 'VmPin', 'VmPMD', 'VmPTE', 'VmRSS', 'VmSize', 'VmStk', 'VmSwap') if k in status }) return status
def smaps(self): """ Parses /proc/<pid>/smaps and returns a list of AttrDict's """ with open("smaps", opener=self._opener) as file: lines = file.read().replace('kB\n', '\n').splitlines() step = int(len(lines) / len(self.maps)) maps = [{ k: try_int(v.strip()) if k != "VmFlags" else v.strip().split() for k, v in [_.split(':') for _ in lines[i + 1:i + step]] } for i in range(0, len(lines), step)] return [AttrDict(**a, **b) for a, b in zip(maps, self.maps)]
def _numa_maps(self): # pylint: disable=star-needs-assignment-target # Make Pylint happy on Python 3.4 """ Parses /proc/<pid>/numa_maps and returns an AttrDict """ with open("numa_maps", opener=self._opener, encoding="utf-8") as file: lines = file.read().splitlines() entry = AttrDict({ address: AttrDict({ k: try_int(v[0]) if v else None for k, *v in [_.split('=', 1) for _ in ['policy=%s' % policy] + values]}) for line in lines for address, policy, *values in [line.split()]}) for key in entry: if 'file' in entry[key]: entry[key].update(file=Pathname(entry[key].file)) return entry
def _mounts(self): """ Parses /proc/<pid>/mounts and returns a list of AttrDict's """ fields = ('spec', 'file', 'vfstype', 'mntops', 'freq', 'passno') with open("mounts", opener=self._opener, encoding="utf-8") as file: lines = file.read().splitlines() entries = [ AttrDict(zip(fields, re.findall(r'^(\S+) (.*?) (\S+) (\S+) (\d+) (\d+)$', _)[0])) for _ in lines] for entry in entries: entry.update( file=Pathname(entry.file), mntops=AttrDict({ k: try_int(v[0]) if v else None for k, *v in [_.split('=', 1) for _ in entry.mntops.split(',')]})) return entries
def test_try_int(self): self.assertEqual(try_int("0"), 0) self.assertEqual(try_int("00"), "00") self.assertEqual(try_int("2"), 2) self.assertEqual(try_int("c"), "c")