@@ -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+
4381pub 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 ,
0 commit comments