diff options
| author | Barosl Lee <vcs@barosl.com> | 2015-08-19 13:11:40 +0900 |
|---|---|---|
| committer | Barosl Lee <vcs@barosl.com> | 2015-08-28 04:46:55 +0900 |
| commit | 7723550fdd7fe29bee9dcbd45bdef4f209a7e1f1 (patch) | |
| tree | 438faf68363ac8833f52c8e4e049de7998253318 /src/rt | |
| parent | 4ff44ff8faabb7e0545dfefa96b0d601f0f17b94 (diff) | |
| download | rust-7723550fdd7fe29bee9dcbd45bdef4f209a7e1f1.tar.gz rust-7723550fdd7fe29bee9dcbd45bdef4f209a7e1f1.zip | |
Reduce the reliance on `PATH_MAX`
- Rewrite `std::sys::fs::readlink` not to rely on `PATH_MAX` It currently has the following problems: 1. It uses `_PC_NAME_MAX` to query the maximum length of a file path in the underlying system. However, the meaning of the constant is the maximum length of *a path component*, not a full path. The correct constant should be `_PC_PATH_MAX`. 2. `pathconf` *may* fail if the referred file does not exist. This can be problematic if the file which the symbolic link points to does not exist, but the link itself does exist. In this case, the current implementation resorts to the hard-coded value of `1024`, which is not ideal. 3. There may exist a platform where there is no limit on file path lengths in general. That's the reaon why GNU Hurd doesn't define `PATH_MAX` at all, in addition to having `pathconf` always returning `-1`. In these platforms, the content of the symbolic link can be silently truncated if the length exceeds the hard-coded limit mentioned above. 4. The value obtained by `pathconf` may be outdated at the point of actually calling `readlink`. This is inherently racy. This commit introduces a loop that gradually increases the length of the buffer passed to `readlink`, eliminating the need of `pathconf`. - Remove the arbitrary memory limit of `std::sys::fs::realpath` As per POSIX 2013, `realpath` will return a malloc'ed buffer if the second argument is a null pointer.[1] [1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html - Comment on functions that are still using `PATH_MAX` There are some functions that only work in terms of `PATH_MAX`, such as `F_GETPATH` in OS X. Comments on them for posterity.
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/rust_builtin.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/rt/rust_builtin.c b/src/rt/rust_builtin.c index 945057f8612..37ce30d7066 100644 --- a/src/rt/rust_builtin.c +++ b/src/rt/rust_builtin.c @@ -341,7 +341,11 @@ const char * rust_current_exe() char **paths; size_t sz; int i; - char buf[2*PATH_MAX], exe[2*PATH_MAX]; + /* If `PATH_MAX` is defined on the platform, `realpath` will truncate the + * resolved path up to `PATH_MAX`. While this can make the resolution fail if + * the executable is placed in a deep path, the usage of a buffer whose + * length depends on `PATH_MAX` is still memory safe. */ + char buf[2*PATH_MAX], exe[PATH_MAX]; if (self != NULL) return self; |
