You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
current_exe() returns invalid path on linux when exe has been deleted #69343
Calling current_exe() on linux after the original executable has been deleted or replaced results in an invalid path being returned.
use std::env::current_exe;fnmain(){// current_exe = /path/to/executableremove_file(current_exe().unwrap()).ok();println!("{:?}", current_exe());}
Output
Ok("/path/to/executable (deleted)")
Desired behavior
While it is the correct behavior of the underlying /proc/self/exe to append the string (deleted) to the original pathname the result is not a valid path and might even end up pointing to a completely different file.
I would either expect the docs to explicitly mention this behavior or classify it as an error and return io::ErrorKind::NotFound accordingly.
Since (deleted) is a valid unix path it would take extra syscalls to check if it actually exists. Additionally there are other cases where /proc/self/exe may point to something that's not accessible, e.g. when mount namespaces or chroot are in play or when a process was launched via memfd_create + fexecve.
So it probably needs a doc update. In the case of mount namespaces this might also be subject to confusion attacks, so this value generally shouldn't be given too much trust.
Rather than simply checking for " (deleted)", it makes more sense to open and stat /proc/self/exe and the path returned. If the inos are different, then the currently running binary isn't the same as the one at the path (it's been replaced or deleted) and an error should be returned.
IMHO. This doesn't explicitly go against the docs on current_exe and I think it'd be good to support that behaviour.
While current_exe() might return all kinds of different paths caused by symlinks or mounts it should return something that points to the executable even if you might not have the permissions to access it.
But /path/to/exe (deleted) has at no point in time been the correct path for the executable and should thus be considered an error. In the end it comes down to how the libraries subteam wants to handle this.
Rather than simply checking for " (deleted)", it makes more sense to open and stat /proc/self/exe and the path returned. If the inos are different, then the currently running binary isn't the same as the one at the path
Does /proc/<pid>/exe have similar magical properties to /proc/<pid>/fd/*?
Even if the program doesn't exist, giving /proc/self/exe to another program would cause that other program to point to itself.
You would pass /proc/<pid>/exe which is valid for the lifetime of the program.
But yes, all of these are workarounds with their own limitations. The proper solution is, at least on linux, to pass around file descriptors which are valid for their whole existence.
As i mentioned in the other thread, it may be worth just deprecating this API in favour of another crate which offers multiple options with different guarantees.
As i mentioned in the other thread, it may be worth just deprecating this API in favour of another crate which offers multiple options with different guarantees.
IMO this is a basically reasonable cross-platform API to have in the standard library, even though it exposes some OS-specific (not Rust-specific) quirks (see #150824) and even though external crates could have richer APIs. In that sense it seems a bit analogous to std::process vs subcommand, or std::time vs Jiff/Time/Chrono, and similarly for other APIs.
A really rich API for this could try to address many dimensions:
Do you want an FD to the current exe even if it's been deleted, or do you want a path?
Do you want the path from which it was once run, even if it's been deleted and renamed?
Do you want to know if it's been deleted?
If it's been renamed do you want the new name?
Do you want a guarantee it's safe (under some definition) to exec the target?
If the answer to any of these can't be known for sure, do you want the library to guess (e.g. by searching the path or returning a possibly old path)?
If you want one of the above but your target OS doesn't support it, do you want a compile time error or do you want a fallback?
What about if your target OS has the API but it doesn't work at runtime (e.g. /proc isn't mounted or a sysctl fails)?
I'm sure that could be done in a crate but I'd rather not lose it altogether from std.
Is there even an option to know the old name on Linux?
Do you want a guarantee it's safe (under some definition) to exec the target?
Only an fd returning api can do that in combination with fexecve. Most OSes don't have an fexecve equivalent afaik.
Well yes, my point is that there aren't any strongly defined behaviors that are really portable. You can use current_exe and get a rough indication of the path, with some caveats about semantics varying across platforms, or you can deal with OS-specific quirks. Someone could write a crate with per-OS precise semantics.
Anyhow, the original comment says
I would either expect the docs to explicitly mention this behavior or classify it as an error and return io::ErrorKind::NotFound accordingly.
I think that's reasonable to expect. I think it's more helpful to document the Linux behavior than to hide the information altogether, so #150824 does that and perhaps it could be considered to fix this.
Activity
the8472 commentedon Feb 21, 2020
Since
(deleted)is a valid unix path it would take extra syscalls to check if it actually exists. Additionally there are other cases where/proc/self/exemay point to something that's not accessible, e.g. when mount namespaces or chroot are in play or when a process was launched via memfd_create + fexecve.So it probably needs a doc update. In the case of mount namespaces this might also be subject to confusion attacks, so this value generally shouldn't be given too much trust.
clarfonthey commentedon Feb 24, 2020
Rather than simply checking for
" (deleted)", it makes more sense to open and stat/proc/self/exeand the path returned. If the inos are different, then the currently running binary isn't the same as the one at the path (it's been replaced or deleted) and an error should be returned.IMHO. This doesn't explicitly go against the docs on
current_exeand I think it'd be good to support that behaviour.tesuji commentedon Feb 24, 2020
Isn't it Linux only?
tsurai commentedon Feb 24, 2020
While current_exe() might return all kinds of different paths caused by symlinks or mounts it should return something that points to the executable even if you might not have the permissions to access it.
But
/path/to/exe (deleted)has at no point in time been the correct path for the executable and should thus be considered an error. In the end it comes down to how the libraries subteam wants to handle this.the8472 commentedon Feb 24, 2020
Does
/proc/<pid>/exehave similar magical properties to/proc/<pid>/fd/*?clarfonthey commentedon Feb 27, 2020
Yes and yes.
the8472 commentedon Feb 27, 2020
Then another option is to simply return the symlink itself instead of the target. At least as a fallback.
After all it may be the only existing reference to an inode, e.g. in the mem_fd case
bjorn3 commentedon Feb 27, 2020
That won't work if you pass the result of
current_exeto another process and then exit.the8472 commentedon Feb 27, 2020
If that symlink was the last reference to the inode then it will never work. So if it's just a fallback you don't lose anything.
Kixunil commentedon Apr 23, 2020
Returning the symlink itself would be a bad idea, even if
/proc/<ID>/fdwas returned:/proc/self/exeto another program would cause that other program to point to itself.the8472 commentedon Apr 23, 2020
You would pass
/proc/<pid>/exewhich is valid for the lifetime of the program.But yes, all of these are workarounds with their own limitations. The proper solution is, at least on linux, to pass around file descriptors which are valid for their whole existence.
clarfonthey commentedon Apr 26, 2020
As i mentioned in the other thread, it may be worth just deprecating this API in favour of another crate which offers multiple options with different guarantees.
6 remaining items
work around rust-lang/rust#69343 in askpass
askpass: Workaround rust lang 69343 (#30774)
sourcefrog commentedon Jan 15, 2026
IMO this is a basically reasonable cross-platform API to have in the standard library, even though it exposes some OS-specific (not Rust-specific) quirks (see #150824) and even though external crates could have richer APIs. In that sense it seems a bit analogous to
std::processvssubcommand, orstd::timevs Jiff/Time/Chrono, and similarly for other APIs.A really rich API for this could try to address many dimensions:
/procisn't mounted or a sysctl fails)?I'm sure that could be done in a crate but I'd rather not lose it altogether from std.
bjorn3 commentedon Jan 15, 2026
Is there even an option to know the old name on Linux?
Only an fd returning api can do that in combination with fexecve. Most OSes don't have an fexecve equivalent afaik.
sourcefrog commentedon Jan 15, 2026
Well yes, my point is that there aren't any strongly defined behaviors that are really portable. You can use
current_exeand get a rough indication of the path, with some caveats about semantics varying across platforms, or you can deal with OS-specific quirks. Someone could write a crate with per-OS precise semantics.Anyhow, the original comment says
I think that's reasonable to expect. I think it's more helpful to document the Linux behavior than to hide the information altogether, so #150824 does that and perhaps it could be considered to fix this.
linux: Store binary path before restart to handle deleted binary file…
askpass: Workaround rust lang 69343 (#30774)
fix(postflight-cli): resolve the running binary before deciding who o…
Rollup merge of rust-lang#150824 - sourcefrog:doc-current-exe, r=clar…
Auto merge of #150824 - sourcefrog:doc-current-exe, r=clarfonthey
Unrolled build for #150824 in rollup 163386