This actually follows the footsteps of Lua's "ljsyscall" library, which I always thought was cool. But actually as you learn that it's done using the helper function from libc, the spell of magic disappears. Beyond that, it's just boring details of inconsistent syscall maps across different architectures of the same OS (Linux), and a bunch of structures to define. MicroPython can deal with all this, and as you learn the details, "developing libc in MicroPython" is much less useful, given that libc is already around. It still may be useful at times, for example Android's Bionic libc probably doesn't provide a lot of more advanced functions, and if they needed, knowing that there's a way to go directly to kernel for them is helpful. (Caveat: but does Bionic provide syscall() itself? D'oh!)
Code: Select all
# This demonstrates calling Linux syscalls "directly" (well, using libc
# proxy, but that appears to be "recommended" method anyway).
import ffilib
import uos
C = ffilib.libc()
# Different Linux archs have different syscall values (not like every one
# is different, but there're few "pattern", plus potentially any may add
# minor glitches on top of common pattern).
# Below are the numbers for x86_64, etc., but not for i386!
SYS_write = 1
SYS_getpid = 39
# Different syscalls have different signatures
syscall0 = C.func("l", "syscall", "i")
syscall_write = C.func("l", "syscall", "iiPi")
print("pid:", syscall0(SYS_getpid))
res = syscall_write(SYS_write, 1, "hello\n", 6)
print(res)
if res == -1:
print("errno:", uos.errno())