Skip to content

Commit 2f3212b

Browse files
committed
CLI: Add support for mapping stdin to a host file in syscall emulation
1 parent e4470d5 commit 2f3212b

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

src/cli/main.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ void create_parser(QCommandLineParser &p) {
8686
p.addOption(
8787
{ { "serial-out", "serout" }, "File connected to the serial port output.", "FNAME" });
8888
p.addOption({ { "os-emulation", "osemu" }, "Operating system emulation." });
89+
p.addOption({ { "std-in", "stdin" }, "File connected to the syscall standard input.", "FNAME" });
8990
p.addOption({ { "std-out", "stdout" }, "File connected to the syscall standard output.", "FNAME" });
9091
p.addOption({ { "os-fs-root", "osfsroot" }, "Emulated system root/prefix for opened files", "DIR" });
9192
p.addOption({ { "isa-variant", "isavariant" }, "Instruction set to emulate (default RV32IMA)", "STR" });
@@ -409,8 +410,13 @@ void configure_serial_port(QCommandLineParser &p, SerialPort *ser_port) {
409410

410411
void configure_osemu(QCommandLineParser &p, MachineConfig &config, Machine *machine) {
411412
CharIOHandler *std_out = nullptr;
413+
QScopedPointer<QString> std_in_path;
412414
int siz;
413415

416+
siz = p.values("std-in").size();
417+
if (siz >= 1) {
418+
std_in_path.reset(new QString(p.values("std-in").at(siz - 1)));
419+
}
414420
siz = p.values("std-out").size();
415421
if (siz >= 1) {
416422
auto *qf = new QFile(p.values("std-out").at(siz - 1));
@@ -427,6 +433,12 @@ void configure_osemu(QCommandLineParser &p, MachineConfig &config, Machine *mach
427433
auto *osemu_handler = new osemu::OsSyscallExceptionHandler(
428434
config.osemu_known_syscall_stop(), config.osemu_unknown_syscall_stop(),
429435
config.osemu_fs_root());
436+
if (!std_in_path.isNull() && !std_in_path->isEmpty()) {
437+
if (!osemu_handler->map_stdin_to_hostfile(*std_in_path)) {
438+
fprintf(stderr, "Failed to map stdin to host file '%s'\n", std_in_path->toLatin1().data());
439+
exit(EXIT_FAILURE);
440+
}
441+
}
430442
if (std_out) {
431443
machine::Machine::connect(
432444
osemu_handler, &osemu::OsSyscallExceptionHandler::char_written,

src/os_emulation/ossyscall.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,25 @@ bool OsSyscallExceptionHandler::handle_exception(
624624
return true;
625625
}
626626

627+
bool OsSyscallExceptionHandler::map_stdin_to_hostfile(const QString &hostpath) {
628+
if (hostpath.isEmpty()) return false;
629+
int hostfd = open(hostpath.toLatin1().data(), O_RDONLY);
630+
if (hostfd < 0) {
631+
fprintf(stderr, "map_stdin_to_hostfile: failed to open host file '%s' errno=%d", hostpath.toLatin1().data(), errno);
632+
return false;
633+
}
634+
if (fd_mapping.size() <= 0) {
635+
fd_mapping.push_back(FD_UNUSED);
636+
}
637+
// If there is an existing host fd mapped at target fd 0, close it (but don't close FD_TERMINAL/FD_UNUSED/FD_INVALID)
638+
int prev = fd_mapping[0];
639+
if (prev >= 0 && prev != FD_TERMINAL && prev != FD_UNUSED && prev != FD_INVALID) {
640+
close(prev);
641+
}
642+
fd_mapping[0] = hostfd;
643+
return true;
644+
}
645+
627646
int32_t OsSyscallExceptionHandler::write_mem(
628647
machine::FrontendMemory *mem,
629648
Address addr,

src/os_emulation/ossyscall.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ class OsSyscallExceptionHandler : public machine::ExceptionHandler {
3535
machine::Address next_addr,
3636
machine::Address jump_branch_pc,
3737
machine::Address mem_ref_addr) override;
38+
/**
39+
* Map target fd 0 (stdin) to a host file opened from @hostpath.
40+
* Returns true on success (host file opened and mapped), false on error.
41+
*
42+
* Notes:
43+
* - Existing mapping at target fd 0 is closed if it refers to a host fd.
44+
* - Uses filepath_to_host() to resolve @hostpath into host file path respecting fs_root.
45+
*/
46+
bool map_stdin_to_hostfile(const QString &hostpath);
3847
OSSYCALL_HANDLER_DECLARE(syscall_default_handler);
3948
OSSYCALL_HANDLER_DECLARE(do_sys_exit);
4049
OSSYCALL_HANDLER_DECLARE(do_sys_set_thread_area);

0 commit comments

Comments
 (0)