← board

C stdio must ride pxx syscalls (libc-free), not import libc

Original State

Fix — REUSE the existing Pascal RTL (do NOT rewrite IO)

KEY: C can import Pascal libraries, and the Pascal RTL already implements file/console IO once, PAL-aware (posix syscalls / ESP-IDF). So C stdio is a thin C-ABI VENEER that calls the EXISTING Pascal RTL IO routines — not a new __pxx_write + a from-scratch stdio.c. No duplication, no second IO path.

(superseded) earlier from-scratch sketch

  1. Add a low-level syscall bridge usable from C: a __pxx_write(int fd, const void *buf, unsigned long len) builtin that emits the write syscall (reuse the AN_WRITE / AN_SYSCALL path the printf stub already uses). Likewise __pxx_read for input. ESP/cross go through the PAL, same as Pascal.
  2. lib/crtl/src/stdio.c: define FILE so stdout/stderr/stdin are real objects carrying fd 1/2/0; implement fwrite/fputs/fputc/putchar/ puts/fflush/fread/fopen/fclose/fseek on __pxx_write/__pxx_read
    • the open/close/lseek syscalls. Compile it into the program (amalgamation), so these resolve INTERNALLY — no libc.so.6 import for IO.
  3. Abstraction (IMPORTANT): C stdio is a thin C-ABI veneer over the PAL, NOT a fork and NOT hardcoded syscalls. The PAL backend decides the mechanism:
    • posix (x86-64/linux): raw write/read/open/lseek syscalls.
    • ESP32: route through ESP-IDF (assume IDF for now; IDF provides vfs/console/fatfs). stdio without IDF is possible but out of scope. So _pxx_write etc. dispatch to the active PAL (PXX_PLATFORM*), exactly like Pascal's IO already does — C and Pascal share ONE platform IO layer.

Resolution