From 9a4e0e3712e99121f7b0141de239c89a2fa4bdea Mon Sep 17 00:00:00 2001 From: cnc Date: Fri, 5 Jun 2026 15:29:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E7=A4=BA=E8=AF=8D=EF=BC=9A=E8=A1=A5?= =?UTF-8?q?=E9=BD=90=20rtapi=5Fvsnprintf=20WASM=20shim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 结论:按 LinuxCNC src/rtapi/uspace_common.h 和 src/rtapi/rtapi.h,将 userspace rtapi_vsnprintf 适配为 vsnprintf 包装,并在 WASM runtime probe 覆盖 snprintf、va_list 和截断返回值。 检查:./test-native.sh 通过;./test-linuxcnc-source-link.sh 通过。 --- .../cnc_sim_wasm_runtime_probe_main.cc | 34 +++++++++++++++++++ core/wasm_shims/rtapi_compat.cc | 7 +++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/core/wasm_shims/cnc_sim_wasm_runtime_probe_main.cc b/core/wasm_shims/cnc_sim_wasm_runtime_probe_main.cc index 8fdf44c..61c4c9f 100644 --- a/core/wasm_shims/cnc_sim_wasm_runtime_probe_main.cc +++ b/core/wasm_shims/cnc_sim_wasm_runtime_probe_main.cc @@ -4,6 +4,7 @@ #include "libnml/nml/stat_msg.hh" #include +#include #include #include #include @@ -16,6 +17,8 @@ extern "C" { extern PyObject *PyInit_interpreter(void); extern PyObject *PyInit_emccanon(void); extern struct _inittab builtin_modules[]; +extern int rtapi_snprintf(char *buf, unsigned long size, const char *fmt, ...); +extern int rtapi_vsnprintf(char *buf, unsigned long size, const char *fmt, va_list ap); } // LinuxCNC source basis: src/emc/rs274ngc/rs274ngc_pre.cc provides read(), @@ -155,6 +158,34 @@ bool builtin_modules_match_linuxcnc_preview_runtime() { builtin_modules[2].initfunc == nullptr; } +int call_rtapi_vsnprintf(char *buffer, unsigned long size, const char *format, ...) { + va_list args; + va_start(args, format); + const int result = rtapi_vsnprintf(buffer, size, format, args); + va_end(args); + return result; +} + +bool rtapi_formatting_matches_linuxcnc_userspace() { + // LinuxCNC source basis: src/rtapi/uspace_common.h implements both + // rtapi_snprintf() and rtapi_vsnprintf() as userspace vsnprintf() wrappers. + char formatted[32]{}; + if (rtapi_snprintf(formatted, sizeof(formatted), "HAL_%s_%d", "probe", 7) != 11 || + std::strcmp(formatted, "HAL_probe_7") != 0) { + return false; + } + + char via_va_list[32]{}; + if (call_rtapi_vsnprintf(via_va_list, sizeof(via_va_list), "%s.%02d", "axis", 3) != 7 || + std::strcmp(via_va_list, "axis.03") != 0) { + return false; + } + + char truncated[5]{}; + return rtapi_snprintf(truncated, sizeof(truncated), "abcdef") == 6 && + std::strcmp(truncated, "abcd") == 0; +} + } // namespace int main() { @@ -176,6 +207,9 @@ int main() { if (!builtin_modules_match_linuxcnc_preview_runtime()) { return 10; } + if (!rtapi_formatting_matches_linuxcnc_userspace()) { + return 11; + } std::vector events; CncSimHandle *sim = cnc_sim_create(); diff --git a/core/wasm_shims/rtapi_compat.cc b/core/wasm_shims/rtapi_compat.cc index e1de0ef..9437c71 100644 --- a/core/wasm_shims/rtapi_compat.cc +++ b/core/wasm_shims/rtapi_compat.cc @@ -2,7 +2,8 @@ #include // LinuxCNC source basis: src/rtapi/uspace_common.h provides rtapi_snprintf() -// for userspace RTAPI formatting; src/rtapi/rtapi.h declares the API. +// and rtapi_vsnprintf() for userspace RTAPI formatting; src/rtapi/rtapi.h +// declares both APIs. extern "C" int rtapi_snprintf(char *buf, unsigned long size, const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -10,3 +11,7 @@ extern "C" int rtapi_snprintf(char *buf, unsigned long size, const char *fmt, .. va_end(ap); return rc; } + +extern "C" int rtapi_vsnprintf(char *buf, unsigned long size, const char *fmt, va_list ap) { + return std::vsnprintf(buf, static_cast(size), fmt, ap); +}