Forcrat: Automatic I/O API Translation from C to Rust via Origin and Capability Analysis
Jaemin Hong, Sukyoung Ryu
TL;DR
The paper tackles the challenge of safely translating C to Rust by focusing on replacing the libc stdio I/O API with Rust std equivalents. It introduces origin and capability analysis to resolve differences in stream origins and capabilities, and error source analysis to propagate errors consistently, implementing these as the Forcrat tool. Empirical evaluation on 62 real-world C programs shows that 32 test suites pass after transformation, 422k lines of code are analyzed in 14 seconds, and 82% of libc I/O API calls are replaced, indicating strong correctness, efficiency, and applicability. The work advances practical C-to-Rust translation by improving safety and reducing manual effort, with notes on limitations, potential security benefits, and directions for reducing verbosity and handling complex error propagation.
Abstract
Translating C to Rust is a promising way to enhance the reliability of legacy system programs. Although the industry has developed an automatic C-to-Rust translator, C2Rust, its translation remains unsatisfactory. One major reason is that C2Rust retains C standard library (libc) function calls instead of replacing them with functions from the Rust standard library (Rust std). However, little work has been done on replacing library functions in C2Rust-generated code. In this work, we focus on replacing the I/O API, an important subset of library functions. This poses challenges due to the semantically different designs of I/O APIs in libc and Rust std. First, the two APIs offer different sets of types that represent the origins (e.g., standard input, files) and capabilities (e.g., read, write) of streams used for I/O. Second, they use different error-checking mechanisms: libc uses internal indicators, while Rust std uses return values. To address these challenges, we propose two static analysis techniques, origin and capability analysis and error source analysis, and use their results to replace the I/O API. Our evaluation shows that the proposed approach is (1) correct, with all 32 programs that have test suites passing the tests after transformation, (2) efficient, analyzing and transforming 422k LOC in 14 seconds, and (3) widely applicable, replacing 82% of I/O API calls.
