我想用Python制作syscall
,函数不是在libc
中,有什么方法可以在Python中实现吗?
更确切地说,我想打电话给getdents
,它的手册上写着
注意:这些系统调用没有glibc包装器;
我在网上找到的所有现有的相关解决方案都使用ctypes
和libc.so
:for 示例。
请不要问我为什么要直接使用getdents
,我有一个非常具体的理由去做,在这个问题中讨论会让人分心。谢谢。
发布于 2016-05-04 15:55:45
Libc公开一个函数来调用“自定义”syscalls:long syscall(long number, ...);
syscall()
是一个小型库函数,它调用系统调用,其汇编语言接口具有具有指定参数的指定number
。例如,当调用C库中没有包装器功能的系统调用时,使用syscall()
是很有用的。
只需像任何外部函数一样访问该函数:
import ctypes
libc = ctypes.CDLL(None)
syscall = libc.syscall
例如:
syscall(39) # 39 = getpid, but you get the gist
或者翻译手册页中的示例:
import os, ctypes
off_t = ctypes.c_long # YMMV
__NR_getdents = 78 # YMMV
class linux_dirent(ctypes.Structure):
_fields_ = [
('d_ino', ctypes.c_long),
('d_off', off_t),
('d_reclen', ctypes.c_ushort),
('d_name', ctypes.c_char)
]
_getdents = ctypes.CDLL(None).syscall
_getdents.restype = ctypes.c_int
_getdents.argtypes = ctypes.c_long, ctypes.c_uint, ctypes.POINTER(ctypes.c_char), ctypes.c_uint
fd = os.open('/tmp/', os.O_RDONLY | os.O_DIRECTORY)
buf = ctypes.ARRAY(ctypes.c_char, 1024)()
while True:
nread = _getdents(__NR_getdents, fd, buf, len(buf))
if nread == -1:
raise OSError('getdents')
elif nread == 0:
break
pos = 0
while pos < nread:
d = linux_dirent.from_buffer(buf, pos)
name = buf[pos + linux_dirent.d_name.offset : pos + d.d_reclen]
name = name[:name.index('\0')]
print 'name:', name
pos += d.d_reclen
https://stackoverflow.com/questions/37032203
复制相似问题