Skip to content

Commit 26fc4c4

Browse files
authored
Merge 0975fe3 into 043a506
2 parents 043a506 + 0975fe3 commit 26fc4c4

8 files changed

Lines changed: 62 additions & 3 deletions

File tree

src/main/bindings/c/bindings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ SysCallReg memorymanager_handleMprotect(MemoryManager *memory_manager,
135135

136136
SysCallReturn rustsyscallhandler_close(SysCallHandler *sys, const SysCallArgs *args);
137137

138+
SysCallReturn rustsyscallhandler_dup(SysCallHandler *sys, const SysCallArgs *args);
139+
138140
SysCallReturn rustsyscallhandler_read(SysCallHandler *sys, const SysCallArgs *args);
139141

140142
SysCallReturn rustsyscallhandler_write(SysCallHandler *sys, const SysCallArgs *args);

src/main/bindings/rust/wrapper.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,9 @@ extern "C" {
678678
args: *const SysCallArgs,
679679
) -> SysCallReturn;
680680
}
681+
extern "C" {
682+
pub fn syscallhandler_dup(sys: *mut SysCallHandler, args: *const SysCallArgs) -> SysCallReturn;
683+
}
681684
extern "C" {
682685
pub fn syscallhandler_getpid(
683686
sys: *mut SysCallHandler,

src/main/host/syscall/unistd.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,12 @@ SysCallReturn syscallhandler_close(SysCallHandler* sys,
296296
return (SysCallReturn){.state = SYSCALL_DONE, .retval.as_i64 = errorCode};
297297
}
298298

299+
SysCallReturn syscallhandler_dup(SysCallHandler* sys,
300+
const SysCallArgs* args) {
301+
warning("Cannot dup legacy descriptors");
302+
return (SysCallReturn){.state = SYSCALL_DONE, .retval.as_i64 = -EOPNOTSUPP};
303+
}
304+
299305
SysCallReturn syscallhandler_pipe2(SysCallHandler* sys,
300306
const SysCallArgs* args) {
301307
return _syscallhandler_pipeHelper(

src/main/host/syscall/unistd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "main/host/syscall/protected.h"
1010

1111
SYSCALL_HANDLER(close);
12+
SYSCALL_HANDLER(dup);
1213
SYSCALL_HANDLER(getpid);
1314
SYSCALL_HANDLER(pipe);
1415
SYSCALL_HANDLER(pipe2);

src/main/host/syscall/unistd.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,44 @@ pub fn close(sys: &mut c::SysCallHandler, args: &c::SysCallArgs) -> c::SysCallRe
4040
c::SysCallReturn::from_int(0)
4141
}
4242

43+
pub fn dup(sys: &mut c::SysCallHandler, args: &c::SysCallArgs) -> c::SysCallReturn {
44+
let fd = unsafe { args.args[0].as_i64 } as libc::c_int;
45+
46+
dup_helper(sys, args, fd)
47+
}
48+
49+
pub fn dup_helper(
50+
sys: &mut c::SysCallHandler,
51+
args: &c::SysCallArgs,
52+
fd: libc::c_int,
53+
) -> c::SysCallReturn {
54+
// get the descriptor, or return early if it doesn't exist
55+
let desc = match syscall::get_descriptor(fd, sys.process) {
56+
Ok(d) => unsafe { &mut *d },
57+
Err(errno) => return c::SysCallReturn::from_errno(errno),
58+
};
59+
60+
// if it's a legacy descriptor, use the C syscall handler instead
61+
let desc = match desc {
62+
CompatDescriptor::New(d) => d,
63+
CompatDescriptor::Legacy(_) => unsafe {
64+
return c::syscallhandler_dup(
65+
sys as *mut c::SysCallHandler,
66+
args as *const c::SysCallArgs,
67+
);
68+
},
69+
};
70+
71+
// clone the descriptor and register it
72+
let new_desc = CompatDescriptor::New(desc.clone());
73+
let new_fd = unsafe {
74+
c::process_registerCompatDescriptor(sys.process, Box::into_raw(Box::new(new_desc)))
75+
};
76+
77+
// return the new fd
78+
c::SysCallReturn::from_int(new_fd as i64)
79+
}
80+
4381
pub fn read(sys: &mut c::SysCallHandler, args: &c::SysCallArgs) -> c::SysCallReturn {
4482
let fd = unsafe { args.args[0].as_i64 } as libc::c_int;
4583
let buf_ptr = unsafe { args.args[1].as_ptr };
@@ -299,6 +337,15 @@ mod export {
299337
close(unsafe { &mut *sys }, unsafe { &*args })
300338
}
301339

340+
#[no_mangle]
341+
pub extern "C" fn rustsyscallhandler_dup(
342+
sys: *mut c::SysCallHandler,
343+
args: *const c::SysCallArgs,
344+
) -> c::SysCallReturn {
345+
assert!(!sys.is_null() && !args.is_null());
346+
dup(unsafe { &mut *sys }, unsafe { &*args })
347+
}
348+
302349
#[no_mangle]
303350
pub extern "C" fn rustsyscallhandler_read(
304351
sys: *mut c::SysCallHandler,

src/main/host/syscall_handler.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ SysCallReturn syscallhandler_make_syscall(SysCallHandler* sys,
215215
HANDLE_RUST(close);
216216
HANDLE(connect);
217217
HANDLE(creat);
218+
HANDLE_RUST(dup);
218219
HANDLE(epoll_create);
219220
HANDLE(epoll_create1);
220221
HANDLE(epoll_ctl);
@@ -335,7 +336,6 @@ SysCallReturn syscallhandler_make_syscall(SysCallHandler* sys,
335336
NATIVE(sched_setaffinity);
336337

337338
// operations on file descriptors
338-
NATIVE(dup);
339339
NATIVE(dup2);
340340
NATIVE(dup3);
341341
NATIVE(poll);

src/shim/preload_syscalls.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ NOREMAP(int, close, (int a), a);
223223
NOREMAP(int, connect, (int a, const struct sockaddr* b, socklen_t c), a,b,c);
224224
NOREMAP(int, creat, (const char *a, mode_t b), a,b);
225225
REMAP(int, creat64, creat, (const char *a, mode_t b), a,b);
226+
NOREMAP(int, dup, (int a), a);
226227
NOREMAP(int, epoll_create, (int a), a);
227228
NOREMAP(int, epoll_create1, (int a), a);
228229
NOREMAP(int, epoll_ctl, (int a, int b, int c, struct epoll_event* d), a,b,c,d);

src/test/pipe/test_pipe.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ fn get_tests() -> Vec<test_utils::ShadowTest<(), String>> {
4141
test_read_write,
4242
set![TestEnv::Libc, TestEnv::Shadow],
4343
),
44-
// TODO: support dup() in Shadow
45-
test_utils::ShadowTest::new("test_dup", test_dup, set![TestEnv::Libc]),
44+
test_utils::ShadowTest::new("test_dup", test_dup, set![TestEnv::Libc, TestEnv::Shadow]),
4645
test_utils::ShadowTest::new(
4746
"test_write_to_read_end",
4847
test_write_to_read_end,

0 commit comments

Comments
 (0)