Closed thesam closed 8 years ago
Here’s the question: which exit does the syscall::exit
refer to in exit
? If it is the rust exit function, that’s infinite recursion. If it is the extern function, how would one ever recurse to the rust function?
To me this special case doesn’t make sense, even if it looks OKish in your provided usecase.
Thank you for replying! "exit" may have been a poor example. It is not the Rust exit function. Let me clarify my usecase a little bit:
I am trying to port the xv6 "teaching operating system" to Rust, starting by porting the userspace applications while keeping the kernel in C. For example, echo: https://github.com/mit-pdos/xv6-public/blob/master/echo.c
Echo uses the user.h header file (https://github.com/mit-pdos/xv6-public/blob/master/user.h) to be able to call "exit". I want to do this from Rust instead and that's why I'm making a thin Rust wrapper for user.h.
When writing the wrapper I found it a bit inconvenient that I couldn't use the original function name for my safe wrapper function. In the FFI examples I've seen the Rust wrapper function always has another name, but in this case I think it would feel a bit forced to call it something other than "exit".
My workaround with the nested module lets me define the public syscall::exit function like I want to, but ideally I would like to be able to do something like this, inspired by the "use x as y" syntax:
mod syscall {
extern {
pub fn exit() -> () as real_exit;
}
pub fn exit() {
unsafe { real_exit() }
}
}
fn main() {
syscall::exit();
}
It is not the Rust exit function.
pub fn exit() {} is a function with rust ABI, or, in short, a rust function.
My workaround with the nested module lets me define the public syscall::exit function like I want to, but ideally I would like to be able to do something like this, inspired by the "use x as y" syntax:
AFAIK module scoping (like you shown in the alternative) is the way to do this, possibly with reexports if desired:
mod syscall {
mod ffi {
extern { pub fn exit() -> () }
}
pub use self::ffi::exit as real_exit;
pub fn exit() { unsafe { real_exit() } }
}
// both syscall::exit (safe binding) and syscall::real_exit (ffi binding) are available.
Alternatively, we have a link_name
attribute:
extern {
#[link_name="exit"]
pub fn myawesomeffiexit() -> ();
}
All in all, I do not see the immediate necessity to implement this, as we have tools to do both renaming and exporting extern functions in various ways.
I wasn't familiar with "link_name", but it is exactly what I was looking for! Thank you very much. I'll close this RFC.
The following example won't work since there's a duplicate definition of "exit".
It would be nice if the public function could be defined as "syscall::exit" even though the function in the extern block is also called "exit".
Input:
Output:
As a workaround, a nested module can be added to avoid the name clash: