-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
We need fs::realpath #11857
Comments
Minor correction: libuv doesn't have a realpath() implementation. The fs.realpath() and fs.realpathSync() functions in node.js are implemented in JavaScript. |
@bnoordhuis That's unfortunate. Given that |
realpath() can block so I wouldn't call it from a green thread. You can use uv_queue_work() to offload the call to a thread from the thread pool. It would look something like this in C: typedef struct {
uv_work_t work_req;
int errorno;
char resolved_path[PATH_MAX];
char path[1];
} realpath_req;
static void work_cb(uv_work_t *req);
static void done_cb(uv_work_t *req, int status);
void fs_realpath(const char *path) {
size_t len = strlen(path);
realpath_req *req = malloc(sizeof(*req) + len);
memcpy(req->path, path, len + 1);
uv_queue_work(uv_default_loop(), &req->work_req, work_cb, done_cb);
}
static void work_cb(uv_work_t *work_req) {
realpath_req *req = container_of(work_req, realpath_req, work_req);
req->errno = 0;
if (realpath(req->path, req->resolved_path) == NULL)
req->errorno = errno;
}
static void done_cb(uv_work_t *req, int status) {
realpath_req *req = container_of(work_req, realpath_req, work_req);
(void) &status; // Only relevant when calling uv_cancel().
// ...
free(req);
} |
This commit implements a layman's version of realpath() for metadata::loader to use in order to not error on symlinks pointing to the same file. Closes rust-lang#12459
When calculating the sysroot, it's more accurate to use realpath() rather than just one readlink() to account for any intermediate symlinks that the rustc binary resolves itself to. For rpath, realpath() is necessary because the rpath must dictate a relative rpath from the destination back to the originally linked library, which works more robustly if there are no symlinks involved. Concretely, any binary generated on OSX into $TMPDIR requires an absolute rpath because the temporary directory is behind a symlink with one layer of indirection. This symlink causes all relative rpaths to fail to resolve. cc rust-lang#11734 cc rust-lang#11857
When calculating the sysroot, it's more accurate to use realpath() rather than just one readlink() to account for any intermediate symlinks that the rustc binary resolves itself to. For rpath, realpath() is necessary because the rpath must dictate a relative rpath from the destination back to the originally linked library, which works more robustly if there are no symlinks involved. Concretely, any binary generated on OSX into $TMPDIR requires an absolute rpath because the temporary directory is behind a symlink with one layer of indirection. This symlink causes all relative rpaths to fail to resolve. cc rust-lang#11734 cc rust-lang#11857
The current state is not acceptable. For Cargo, we had to pull in the |
It doesn't make sense to me to have an implementation that we use internally in the compiler but to be unwilling to ship it even temporarily as part of std. If it's broken, that will mean the compiler is broken! |
That It also isn't appending the resolved symlink path to the directory the symlink was in before calling the recursive I would suggest that as a temporary workaround you use FFI to call POSIX |
Windows supports symlinks as of Vista, so that seems like a problem. I would suggest that getting this working correctly in the compiler is important. |
In other words, either this is horribly broken in the compiler and needs to be fixed ASAP, or it's working well enough to include in the standard library for now. |
There's a grey area in between those two extremes. It's definitely broken enough that it's not appropriate to put in the standard library. But it apparently works well enough for the limited use-case of the compiler, or this would have been an issue before now. Which is to say, it should be fixed, but it's not an ASAP kind of fix. |
The "limited use case of the compiler" seems to be every symlink ever. |
Hrm, looks like I actually misread the code. The assertion that it "isn't appending the resolved symlink path to the directory the symlink was in" is wrong. But the issue with |
With libgreen gone this should be easy. #[cfg(unix)]
pub fn real_path(p: Path) -> Path {
use libc::{c_char};
use std::c_str::{CString};
extern {
fn realpath(path: *const c_char, resolved: *mut c_char) -> *const c_char;
}
let mut p = p.into_vec();
p.push(0);
let new_p = unsafe { realpath(p.as_ptr() as *const c_char, 0 as *mut c_char) };
unsafe { Path::new(CString::new(new_p, true).as_bytes_no_nul()) }
}
#[cfg(windows)]
pub fn real_path(p: Path) -> Path {
// TODO
p
} |
Note for posterity: look at |
Closing in favor of rust-lang/rfcs#939 |
For those landing from Google here: realpath has been added as
|
…flip1995 Add documentation update hint using `cargo collect-metadata` This adds a little reminder to update the documentation in the book using `cargo collect-metadata` after changing the lint configuration since this can easily be missed (been there done that 🙈). > Yeah a note would be good, would be good for us to see if we can make it automatic also _Originally posted by `@Alexendoo` in rust-lang/rust-clippy#11757 (comment) Regarding the automation Im not sure whats the best option here. I thought about a kind of a "semi-automated" way, e.g. a `cargo dev` command which runs the "is the documentation updated" check (and maybe other useful checks) locally and reminds the user of updating the documentation so this gets caught before pushing. changelog: none
After an aborted attempt at implementing this directly (#11734), we need to investigate how to provide
fs::realpath()
correctly.The current thinking is that for libgreen, we should defer to libuv. For libnative, on POSIX, we should use
realpath()
. On Windows, I don't know, but we should avoid writing this ourselves at all costs because there's a lot of complexity involved.The text was updated successfully, but these errors were encountered: