Skip to content

Inconsistent current_exe behavior for symlinks on different platforms #43617

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jeffweiss opened this issue Aug 2, 2017 · 3 comments
Closed
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools C-enhancement Category: An issue proposing an enhancement or a PR with one. P-medium Medium priority T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@jeffweiss
Copy link

Background

I was attempting to use std::env::current_exe() to figure out how my program was invoked so I could respond with convenience code paths (analogous to how gpgv is basically a shortcut/alias for gpg --verify) when I noticed inconsistent behavior between OS X and Linux when the program was invoked via a symbolic link.

Steps to Reproduce

test.rs

fn main() {
    println!("{:?}", std::env::current_exe());
}
$ rustc test.rs
$ ln test one
$ ln -s test two
$ ./test
$ ./one
$ ./two

For convenience I have bundled these in a repo: jeffweiss/rust-current_exe

Rust Version

rustc 1.19.0 (0ade339 2017-07-17)

Expected Behavior

On all platforms, I would expect to get:

Ok("/home/jweiss/devel/jeffweiss/rust-current_exe/test")
Ok("/home/jweiss/devel/jeffweiss/rust-current_exe/one")
Ok("/home/jweiss/devel/jeffweiss/rust-current_exe/two")

Actual Behavior

On Mac OS X, I get:

Ok("/home/jweiss/devel/jeffweiss/rust-current_exe/test")
Ok("/home/jweiss/devel/jeffweiss/rust-current_exe/one")
Ok("/home/jweiss/devel/jeffweiss/rust-current_exe/two")

On Linux, I get:

Ok("/home/jweiss/devel/jeffweiss/rust-current_exe/test")
Ok("/home/jweiss/devel/jeffweiss/rust-current_exe/one")
Ok("/home/jweiss/devel/jeffweiss/rust-current_exe/test")

Related Documentation

The documentation for std::env::current_exe implies that if you run current_exe from the symlink, you'll get the name of the symlink, not the dereferenced target of the symlink; however, the documentation's example does not actually include a symbolic link (ln -s), but rather a hard link (ln).

@Mark-Simulacrum Mark-Simulacrum added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Aug 3, 2017
@aidanhs
Copy link
Member

aidanhs commented Aug 3, 2017

I suspect this will have to be fixed in documentation (probably by just being more vague about what different platforms return) since I'm not sure there's a way to get what you want in Linux:

$ ln -s /bin/ls /tmp/some-test-ls
$ /tmp/some-test-ls -l /proc/self/exe
lrwxrwxrwx 1 aidanhs aidanhs 0 Aug  4 00:24 /proc/self/exe -> /bin/ls

I note that the busybox docker container uses hardlinks in /bin, presumably due to the same problem (it's a multi-call binary, as you want to provide).

Putting aside current_exe, you can possibly solve your use-case with the first element of std::env::args() instead.

@retep998
Copy link
Member

retep998 commented Aug 7, 2017

Behavior on Windows is similar to the behavior on OS X. It calls GetModuleFileNameW which gets the path from the file handle for the module handle, which returns a canonical path to the file.

Ok("D:\\Test\\link.exe")
Ok("D:\\Test\\one.exe")
Ok("D:\\Test\\two.exe")

@steveklabnik steveklabnik added the P-medium Medium priority label Oct 31, 2017
frewsxcv added a commit to frewsxcv/rust that referenced this issue Dec 24, 2017
- Update example in ‘security’ section to use hard links, like the
  linked securityvulns.com example.
- Weaken language on symbolic links – indicate behavior is
  platform-specific

Fixes rust-lang#43617.
@frewsxcv
Copy link
Member

opened a pr for this: #46987

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Jan 6, 2018
…ietMisdreavus

Minor rewrite of env::current_exe docs; clarify symlinks.

- Update example in ‘security’ section to use hard links, like the
  linked securityvulns.com example.
- Weaken language on symbolic links – indicate behavior is
  platform-specific

Fixes rust-lang#43617.
rivy added a commit to rivy/rs.coreutils that referenced this issue May 3, 2020
## [why]

`std::env::current_exe()` has platform dependent behavior and will often
not return a symlink name when executed via symlink.

... fallback to `std::env::current_ext()` if args are missing or empty.

- ref: <rust-lang/rust#43617>
rivy added a commit to rivy/rs.coreutils that referenced this issue May 4, 2020
## [why]

`std::env::current_exe()` has platform dependent behavior and will often
return the target binary, not the symlink name, when the binary is executed
via symlink. So, to support symlinking, the first (0th) arg from `std::env::args()`
is used, when possible with fallback to `std::env::current_ext()` if args are
missing or empty.

- ref: <rust-lang/rust#43617>
rivy added a commit to rivy/rs.coreutils that referenced this issue May 4, 2020
## [why]

`std::env::current_exe()` has platform dependent behavior and will often
return the target binary, not the symlink name, when the binary is executed
via symlink. So, to support symlinking, the first (0th) arg from `std::env::args()`
is used, when possible, with fallback to `std::env::current_ext()` if args are
missing or empty.

- ref: <rust-lang/rust#43617>
rivy added a commit to rivy/rs.coreutils that referenced this issue May 5, 2020
## [why]

`std::env::current_exe()` has platform dependent behavior and will often
return the target binary, not the symlink name, when the binary is executed
via symlink. So, to support symlinking, the first (0th) arg from `std::env::args()`
is used, when possible, with fallback to `std::env::current_ext()` if args are
missing or empty.

- ref: <rust-lang/rust#43617>
rivy added a commit to rivy/rs.coreutils that referenced this issue May 5, 2020
…re possible

## [why]

`std::env::current_exe()` has platform dependent behavior and will often
return the target binary, not the symlink name, when the binary is executed
via symlink. So, to support symlinking, the first (0th) arg from `std::env::args()`
is used, when possible, with fallback to `std::env::current_ext()` if args are
missing or empty.

- ref: <rust-lang/rust#43617>
rivy added a commit to rivy/rs.coreutils that referenced this issue May 5, 2020
…re possible

## [why]

`std::env::current_exe()` has platform dependent behavior and will often
return the target binary, not the symlink name, when the binary is executed
via symlink. So, to support symlinking, the first (0th) arg from `std::env::args()`
is used, when possible, with fallback to `std::env::current_ext()` if args are
missing or empty.

- ref: <rust-lang/rust#43617>
rivy added a commit to rivy/rs.coreutils that referenced this issue May 5, 2020
…re possible

## [why]

`std::env::current_exe()` has platform dependent behavior and will often
return the target binary, not the symlink name, when the binary is executed
via symlink. So, to support symlinking, the first (0th) arg from `std::env::args()`
is used, when possible, with fallback to `std::env::current_ext()` if args are
missing or empty.

- ref: <rust-lang/rust#43617>
rivy added a commit to rivy/rs.coreutils that referenced this issue May 6, 2020
…re possible

## [why]

`std::env::current_exe()` has platform dependent behavior and will often
return the target binary, not the symlink name, when the binary is executed
via symlink. So, to support symlinking, the first (0th) arg from `std::env::args()`
is used, when possible, with fallback to `std::env::current_ext()` if args are
missing or empty.

- ref: <rust-lang/rust#43617>
rivy added a commit to rivy/rs.coreutils that referenced this issue May 22, 2020
…re possible

## [why]

`std::env::current_exe()` has platform dependent behavior and will often
return the target binary, not the symlink name, when the binary is executed
via symlink. So, to support symlinking, the first (0th) arg from `std::env::args()`
is used, when possible, with fallback to `std::env::current_ext()` if args are
missing or empty.

- ref: <rust-lang/rust#43617>
rivy added a commit to rivy/rs.coreutils that referenced this issue May 24, 2020
…re possible

## [why]

`std::env::current_exe()` has platform dependent behavior and will often
return the target binary, not the symlink name, when the binary is executed
via symlink. So, to support symlinking, the first (0th) arg from `std::env::args()`
is used, when possible, with fallback to `std::env::current_ext()` if args are
missing or empty.

- ref: <rust-lang/rust#43617>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools C-enhancement Category: An issue proposing an enhancement or a PR with one. P-medium Medium priority T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants