Python=でsyscall
を作成し、関数がlibc
にない場合、Pythonでそれを行う方法はありますか?
より具体的には、私は getdents
を呼び出したい、そのマンページには
注:これらのシステムコールにはglibcラッパーはありません。
私がWebで見つけた既存の関連ソリューションはすべて、ctypes
とlibc.so
:を example で使用しています。
getdents
を直接使用する理由を質問しないでください。使用する非常に具体的な理由があり、この質問で議論するのは面倒です。ありがとうございました。
Libcは、「カスタム」システムコールを呼び出すための関数を公開します。 long syscall(long number, ...);
syscall()
は、アセンブリ言語インターフェイスが指定されたnumber
を指定された引数で持つシステムコールを呼び出す小さなライブラリ関数です。syscall()
を使用すると、Cライブラリにラッパー関数のないシステムコールを呼び出す場合などに便利です。
外部関数のようにこの関数にアクセスするだけです:
import ctypes
libc = ctypes.CDLL(None)
syscall = libc.syscall
例えば.
syscall(39) # 39 = getpid, but you get the Gist
または、manページの例を翻訳するには:
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