I need to obtain the path of the running Rust executable file from within the program itself. However, calling std::env::current_exe() returns ld-linux-x86-64.so instead of the actual file path.
I am looking for a robust method to retrieve the path of the Rust binary regardless of whether it is launched directly or via ld-linux-x86-64.so.
I prefer not to rely on non-robust methods such as checking the third argument in args. Any suggestions on achieving this in a reliable manner?
If you are on Linux specifically (and don't want to be portable to other Unixes), you could maybe read some data from /proc/self such as the symlink /proc/self/exe (if that points to the correct file in this case, not sure).
But this is a strange way to run a program, hope you don't mind me asking: why?
Thank you for the comment, but unfortunately /proc/self/exe points to the ld.so. Is there any other files that could be useful in /proc/self/*? I couldn't find one.
The original author is not in the team anymore so I can only guess, but the reason is when the runner OS is limited to very old one like CentOS7, and you don't want to be dependent on the system libs (like libs) versions, it's useful to just copy the updated libs from other environment and run your app by specifying the libs not using the system libs like the ones in /lib64.
I suspect that using docker containers is a much better solution for such a situation. But isn't centos 7 EOL by now? So it seems insecure to keep using that system (unless it is properly air gapped I guess).
There's a non-standard but widely-supported global variable called __progname_full that should work in this case, since it will be set by ld.so, like this:
use std::ffi::{CStr, c_char};
extern "C" {
static __progname_full: *const c_char;
}
fn main() {
let s = unsafe { CStr::from_ptr(__progname_full) };
println!("{:?}", s);
}
@carey@jonh
Confirmed both solutions worked correctly. The libaddr solution, at least as far as I've checked on my end, doesn't seem to work with musl tho. But in any case, I think I can solve the current problem and move forward. I also learned a lot. Thank you very much!
EDIT: Sorry I can't set both as the solution, so please allow me to set @carey's one. It was more robust, at least in my environment, in a way it was usable in both glibc and musl.
It makes sense that dynamic loader function does not produce result with static linking. Not sure I would be keen to use undocumented internal variable. At least it would fail to compile if ever removed in future. (rather that requiring runtime debugging.)