summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2016-02-27 21:51:16 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2016-02-27 21:51:16 +0100
commit7966bf55740e12844112837b15c9635e0a3a5a30 (patch)
treea82dae62107d45e4dda01ccb71d46c14f5963303
parent8eea7d10e25b8cd3920a5f635791043f85b94184 (diff)
downloadpsutil-7966bf55740e12844112837b15c9635e0a3a5a30.tar.gz
#777 / linux / open_files(): return file position
-rw-r--r--IDEAS6
-rw-r--r--psutil/_pslinux.py20
-rw-r--r--psutil/tests/test_process.py34
3 files changed, 41 insertions, 19 deletions
diff --git a/IDEAS b/IDEAS
index 26a9ce25..b8b3a17b 100644
--- a/IDEAS
+++ b/IDEAS
@@ -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