Make syscall in Python Make syscall in Python python python

Make syscall in Python


Libc exposes a function to invoke "custom" syscalls: long syscall(long number, ...);

syscall() is a small library function that invokes the system call whose assembly language interface has the specified number with the specified arguments. Employing syscall() is useful, for example, when invoking a system call that has no wrapper function in the C library.

Just access this function like any foreign function:

import ctypeslibc = ctypes.CDLL(None)syscall = libc.syscall

e.g.

syscall(39)  # 39 = getpid, but you get the gist

Or to translate the example in the man page:

import os, ctypesoff_t = ctypes.c_long  # YMMV__NR_getdents = 78  # YMMVclass 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_uintfd = 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