diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2016-02-27 21:51:16 +0100 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2016-02-27 21:51:16 +0100 |
commit | 7966bf55740e12844112837b15c9635e0a3a5a30 (patch) | |
tree | a82dae62107d45e4dda01ccb71d46c14f5963303 | |
parent | 8eea7d10e25b8cd3920a5f635791043f85b94184 (diff) | |
download | psutil-7966bf55740e12844112837b15c9635e0a3a5a30.tar.gz |
#777 / linux / open_files(): return file position
-rw-r--r-- | IDEAS | 6 | ||||
-rw-r--r-- | psutil/_pslinux.py | 20 | ||||
-rw-r--r-- | psutil/tests/test_process.py | 34 |
3 files changed, 41 insertions, 19 deletions
@@ -141,3 +141,9 @@ FEATURES - #550: number of threads per core. - Have psutil.Process().cpu_affinity([]) be an alias for "all CPUs"? + +SIMILAR PROJECTS +================ + +- https://github.com/hyperic/sigar (Java) +- zabbix source code: https://zabbix.org/wiki/Get_Zabbix diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 882cfac8..39f5328d 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -237,6 +237,7 @@ sdiskio = namedtuple('sdiskio', ['read_count', 'write_count', 'read_merged_count', 'write_merged_count', 'busy_time']) +popenfile = namedtuple('popenfile', ['path', 'fd', 'position']) pmem = namedtuple('pmem', 'rss vms shared text lib data dirty') pfullmem = namedtuple('pfullmem', pmem._fields + ('uss', 'pss', 'swap')) @@ -1296,7 +1297,7 @@ class Process(object): for fd in files: file = "%s/%s/fd/%s" % (self._procfs_path, self.pid, fd) try: - file = readlink(file) + path = readlink(file) except OSError as err: # ENOENT == file which is gone in the meantime if err.errno in (errno.ENOENT, errno.ESRCH): @@ -1308,12 +1309,17 @@ class Process(object): else: raise else: - # If file is not an absolute path there's no way - # to tell whether it's a regular file or not, - # so we skip it. A regular file is always supposed - # to be absolutized though. - if file.startswith('/') and isfile_strict(file): - ntuple = _common.popenfile(file, int(fd)) + # If path is not an absolute there's no way to tell + # whether it's a regular file or not, so we skip it. + # A regular file is always supposed to be have an + # absolute path though. + if path.startswith('/') and isfile_strict(path): + # Get file position. + file = "%s/%s/fdinfo/%s" % ( + self._procfs_path, self.pid, fd) + with open_binary(file) as f: + pos = int(f.readline().split()[1]) + ntuple = popenfile(path, int(fd), pos) retlist.append(ntuple) if hit_enoent: # raise NSP if the process disappeared on us diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py index f1cc1762..1c7993de 100644 --- a/psutil/tests/test_process.py +++ b/psutil/tests/test_process.py @@ -876,13 +876,20 @@ class TestProcess(unittest.TestCase): p = psutil.Process() files = p.open_files() self.assertFalse(TESTFN in files) - with open(TESTFN, 'w'): + with open(TESTFN, 'wb') as f: + f.write(b'x' * 1024) + f.flush() # give the kernel some time to see the new file - call_until(p.open_files, "len(ret) != %i" % len(files)) - filenames = [x.path for x in p.open_files()] - self.assertIn(TESTFN, filenames) - for file in filenames: - assert os.path.isfile(file), file + files = call_until(p.open_files, "len(ret) != %i" % len(files)) + for file in files: + if file.path == TESTFN: + if LINUX: + self.assertEqual(file.position, 1024) + break + else: + self.fail("no file found; files=%s" % repr(files)) + for file in files: + assert os.path.isfile(file.path), file # another process cmdline = "import time; f = open(r'%s', 'r'); time.sleep(60);" % TESTFN @@ -903,20 +910,20 @@ class TestProcess(unittest.TestCase): @unittest.skipIf(BSD, "broken on BSD, see #595") @unittest.skipIf(APPVEYOR, "can't find any process file on Appveyor") - def test_open_files2(self): + def test_open_files_2(self): # test fd and path fields with open(TESTFN, 'w') as fileobj: p = psutil.Process() - for path, fd in p.open_files(): - if path == fileobj.name or fd == fileobj.fileno(): + for file in p.open_files(): + if file.path == fileobj.name or file.fd == fileobj.fileno(): break else: self.fail("no file found; files=%s" % repr(p.open_files())) - self.assertEqual(path, fileobj.name) + self.assertEqual(file.path, fileobj.name) if WINDOWS: - self.assertEqual(fd, -1) + self.assertEqual(file.fd, -1) else: - self.assertEqual(fd, fileobj.fileno()) + self.assertEqual(file.fd, fileobj.fileno()) # test positions ntuple = p.open_files()[0] self.assertEqual(ntuple[0], ntuple.path) @@ -1694,6 +1701,9 @@ class TestFetchAllProcesses(unittest.TestCase): assert f.fd == -1, f else: self.assertIsInstance(f.fd, int) + if LINUX: + self.assertIsInstance(f.position, int) + self.assertGreaterEqual(f.position, 0) if BSD and not f.path: # XXX see: https://github.com/giampaolo/psutil/issues/595 continue |