blob: 2e6e76f8e6df93f528753db6cb0ce2caa8dbcfba [file] [log] [blame]
# HG changeset patch
# User Victor Stinner <victor.stinner@gmail.com>
# Date 1417423044 -3600
# Mon Dec 01 09:37:24 2014 +0100
# Node ID eba1a6dba205559d724d32c80d955a65e078505e
# Parent e6fef4231a8a28ef91c1feaf3bfbcbd29822c939
Issue #17: syscall parser now supports O_CLOEXEC and SOCK_CLOEXEC, fix unit
tests on Python 3.4 and newer
diff --git a/doc/changelog.rst b/doc/changelog.rst
--- a/doc/changelog.rst
+++ b/doc/changelog.rst
@@ -3,6 +3,12 @@
Changelog
=========
+python-ptrace 0.8.2
+-------------------
+
+* Issue #17: syscall parser now supports O_CLOEXEC and SOCK_CLOEXEC, fix unit
+ tests on Python 3.4 and newer
+
python-ptrace 0.8.1 (2014-10-30)
--------------------------------
diff --git a/ptrace/syscall/posix_arg.py b/ptrace/syscall/posix_arg.py
--- a/ptrace/syscall/posix_arg.py
+++ b/ptrace/syscall/posix_arg.py
@@ -24,7 +24,7 @@
return formatBits(argument.value, ACCESS_MODE_BITMASK, "F_OK")
# From /usr/include/bits/fcntl.h (Ubuntu Feisty, i386)
-OPEN_MODE_BITMASK = (
+OPEN_MODE_BITMASK = [
(0o1, "O_WRONLY"),
(0o2, "O_RDWR"),
(0o100, "O_CREAT"),
@@ -40,10 +40,17 @@
(0o200000, "O_DIRECTORY"),
(0o400000, "O_NOFOLLOW"),
(0o1000000, "O_NOATIME"),
-)
+]
+O_CLOEXEC = 0o02000000
def formatOpenMode(argument):
- return formatBits(int(argument.value), OPEN_MODE_BITMASK, "O_RDONLY", oct)
+ value = argument.value
+ cloexec = bool(value & O_CLOEXEC)
+ value = value & ~O_CLOEXEC
+ text = formatBits(int(value), OPEN_MODE_BITMASK, "O_RDONLY", oct)
+ if cloexec:
+ text += '|O_CLOEXEC'
+ return text
CLONE_FLAGS_BITMASK = (
(0x00000100, "CLONE_VM"),
diff --git a/ptrace/syscall/posix_constants.py b/ptrace/syscall/posix_constants.py
--- a/ptrace/syscall/posix_constants.py
+++ b/ptrace/syscall/posix_constants.py
@@ -1,5 +1,5 @@
from ptrace.syscall.socketcall_constants import (
- SOCKET_FAMILY, SOCKET_TYPE, SOCKET_PROTOCOL,
+ SOCKET_FAMILY, SOCKET_PROTOCOL,
SETSOCKOPT_LEVEL, SETSOCKOPT_OPTNAME)
SYSCALL_ARG_DICT = {
@@ -51,7 +51,6 @@
},
"socket": {
"domain": SOCKET_FAMILY,
- "type": SOCKET_TYPE,
"protocol": SOCKET_PROTOCOL,
},
"getsockopt": {
diff --git a/ptrace/syscall/socketcall_constants.py b/ptrace/syscall/socketcall_constants.py
--- a/ptrace/syscall/socketcall_constants.py
+++ b/ptrace/syscall/socketcall_constants.py
@@ -1,3 +1,5 @@
+import socket
+
SOCKETCALL = {
1: "socket",
2: "bind",
@@ -56,6 +58,19 @@
10: "SOCK_PACKET",
}
+def formatSocketType(argument):
+ value = argument.value
+ text = []
+ if hasattr(socket, 'SOCK_CLOEXEC'):
+ cloexec = value & socket.SOCK_CLOEXEC
+ value &= ~socket.SOCK_CLOEXEC
+ else:
+ cloexec = False
+ text = SOCKET_TYPE.get(value, value)
+ if cloexec:
+ text += '|SOCK_CLOEXEC'
+ return text
+
SOCKET_PROTOCOL = {
1: "IPPROTO_ICMP",
58: "IPPROTO_ICMPV6",
diff --git a/ptrace/syscall/syscall_argument.py b/ptrace/syscall/syscall_argument.py
--- a/ptrace/syscall/syscall_argument.py
+++ b/ptrace/syscall/syscall_argument.py
@@ -22,6 +22,7 @@
from ptrace.syscall.freebsd_constants import SYSCALL_ARG_DICT
else:
SYSCALL_ARG_DICT = {}
+from ptrace.syscall.socketcall_constants import formatSocketType
KNOWN_STRUCTS = []
if RUNNING_LINUX:
@@ -35,6 +36,7 @@
"mmap": {"prot": formatMmapProt},
"mmap2": {"prot": formatMmapProt},
"clone": {"flags": formatCloneFlags},
+ "socket": {"type": formatSocketType},
"setsockopt": {"optval": formatOptVal},
}
diff --git a/tests/test_strace.py b/tests/test_strace.py
--- a/tests/test_strace.py
+++ b/tests/test_strace.py
@@ -39,10 +39,19 @@
expected = os.fsencode(expected)
self.assertEqual(match.group(1), expected)
+ def test_open(self):
+ if PY3:
+ code = 'open(%a).close()' % __file__
+ else:
+ code = 'open(%r).close()' % __file__
+ stdout = self.strace(sys.executable, '-c', code)
+ pattern = re.compile(br"^open\(.*test_strace\.py', O_RDONLY(\|O_CLOEXEC)?\)", re.MULTILINE)
+ self.assertTrue(pattern.search(stdout), stdout)
+
def test_socket(self):
code = 'import socket; socket.socket(socket.AF_INET, socket.SOCK_STREAM).close()'
stdout = self.strace(sys.executable, '-c', code)
- pattern = re.compile(b'^socket\\(AF_INET, SOCK_STREAM, ', re.MULTILINE)
+ pattern = re.compile(br'^socket\(AF_INET, SOCK_STREAM(\|SOCK_CLOEXEC)?, ', re.MULTILINE)
self.assertTrue(pattern.search(stdout), stdout)
if __name__ == "__main__":