Skip to content

Commit e2c5eb2

Browse files
committed
Add proper duplicates of stdin/stdout/stderr
1 parent 3641d49 commit e2c5eb2

File tree

3 files changed

+21
-12
lines changed

3 files changed

+21
-12
lines changed

lib/tinykvm/linux/fds.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,16 @@ namespace tinykvm
3232
: m_machine(machine),
3333
m_current_working_directory_fd(AT_FDCWD)
3434
{
35-
// XXX: TODO: Create proper redirects for stdout/stderr by
36-
// for example providing a pipe to stdout/stderr.
37-
m_fds[0] = Entry{ .real_fd = 0, .is_writable = false }; // stdin
38-
m_fds[1] = Entry{ .real_fd = 1, .is_writable = true }; // stdout
39-
m_fds[2] = Entry{ .real_fd = 2, .is_writable = true }; // stderr
35+
// Create proper redirects for stdin/stdout/stderr
36+
const int stdin_fd = dup(0);
37+
const int stdout_fd = dup(1);
38+
const int stderr_fd = dup(2);
39+
if (stdin_fd < 0 || stdout_fd < 0 || stderr_fd < 0) {
40+
throw std::runtime_error("TinyKVM: Failed to duplicate stdin/stdout/stderr");
41+
}
42+
m_fds[0] = Entry{ .real_fd = stdin_fd, .is_writable = false }; // stdin
43+
m_fds[1] = Entry{ .real_fd = stdout_fd, .is_writable = true }; // stdout
44+
m_fds[2] = Entry{ .real_fd = stderr_fd, .is_writable = true }; // stderr
4045
}
4146

4247
FileDescriptors::~FileDescriptors()
@@ -166,7 +171,8 @@ namespace tinykvm
166171

167172
int FileDescriptors::manage(int fd, bool is_socket, bool is_writable)
168173
{
169-
if (fd < 0) {
174+
(void)is_socket; // Unused
175+
if (fd <= 2) {
170176
throw std::runtime_error("TinyKVM: Invalid file descriptor in FileDescriptors::add()");
171177
}
172178
if (this->m_max_total_fds_opened != 0 && this->m_total_fds_opened >= this->m_max_total_fds_opened) {
@@ -213,7 +219,7 @@ namespace tinykvm
213219
FileDescriptors::Entry& FileDescriptors::manage_as(int vfd, int fd, bool is_socket, bool is_writable)
214220
{
215221
(void)is_socket; // Unused
216-
if (fd < 0) {
222+
if (fd <= 2) {
217223
throw std::runtime_error("TinyKVM: Invalid fd in FileDescriptors::manage_as()");
218224
}
219225
if (this->m_max_total_fds_opened != 0 &&

lib/tinykvm/linux/fds.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ namespace tinykvm
183183
/// @brief Get the number of sockets that are currently open.
184184
/// @return The number of sockets that are currently open.
185185
uint16_t get_current_sockets_opened() const noexcept {
186-
return m_fds.size() - m_stdout_redirects.size();
186+
return m_fds.size();
187187
}
188188

189189
/// @brief Set a callback for connecting a socket. This is used to check if a
@@ -295,7 +295,6 @@ namespace tinykvm
295295
Machine& m_machine;
296296
std::map<int, Entry> m_fds;
297297
int m_next_fd = VFD_START;
298-
std::array<int, 3> m_stdout_redirects { 0, 1, 2 };
299298
std::string m_current_working_directory;
300299
int m_current_working_directory_fd = -1;
301300
bool m_verbose = false;

lib/tinykvm/linux/system_calls.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
102102
if (UNLIKELY(bytes > 1024*64)) {
103103
regs.rax = -1;
104104
cpu.set_registers(regs);
105-
SYSPRINT("write(fd=%d (%d), data=0x%llX, size=%zu) = %lld\n",
105+
SYSPRINT("write(fd=%d (%d), data=0x%llX, size=%zu) = %lld (overflow)\n",
106106
vfd, vfd, regs.rsi, bytes, regs.rax);
107107
return;
108108
}
@@ -138,6 +138,8 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
138138
cpu.machine().print(buffer.begin(), buffer.size());
139139
});
140140
regs.rax = bytes;
141+
SYSPRINT("write(fd=%d (%d), data=0x%llX, size=%zu) = %lld (stdio)\n",
142+
vfd, vfd, regs.rsi, bytes, regs.rax);
141143
}
142144
cpu.set_registers(regs);
143145
});
@@ -2516,7 +2518,7 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
25162518
const int fd = cpu.machine().fds().translate(vfd);
25172519
const uint64_t g_event = regs.r10;
25182520
struct epoll_event event {};
2519-
if (epollfd > 0 && fd >= 0)
2521+
if (epollfd > 0 && fd >= 0 && epollfd != fd)
25202522
{
25212523
if (g_event != 0x0) {
25222524
cpu.machine().copy_from_guest(&event, g_event, sizeof(event));
@@ -2534,8 +2536,10 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
25342536
}
25352537
regs.rax = 0;
25362538
}
2539+
} else if (epollfd < 0 || fd < 0) {
2540+
regs.rax = -EBADF;
25372541
} else {
2538-
regs.rax = -ENOENT;
2542+
regs.rax = -EINVAL;
25392543
}
25402544
cpu.set_registers(regs);
25412545
if (UNLIKELY(cpu.machine().m_verbose_system_calls))

0 commit comments

Comments
 (0)