Allocating a string of length MAXPATHLEN and then shrinking the string
is inefficient when the resulting path is short. Preallocating a large
string is also a problem for Variable Width Allocation since we can't
easily downsize the capacity.
I ran the following benchmark:
```ruby
Benchmark.ips do |x|
{
"empty" => "",
"short" => "a/" * 10,
"medium" => "a/" * 100,
"long" => "a/" * 500
}.each do |name, path|
x.report(name) do |times|
i = 0
while i < times
File.expand_path(path)
i += 1
end
end
end
end
```
On this commit:
```
empty 97.486k (± 0.7%) i/s - 492.915k in 5.056507s
short 96.026k (± 2.4%) i/s - 486.489k in 5.068966s
medium 86.304k (± 1.3%) i/s - 435.336k in 5.045112s
long 59.395k (± 1.7%) i/s - 302.175k in 5.089026s
```
On master:
```
empty 94.138k (± 1.4%) i/s - 472.158k in 5.016590s
short 92.043k (± 1.4%) i/s - 468.180k in 5.087496s
medium 84.910k (± 2.3%) i/s - 425.750k in 5.017007s
long 61.503k (± 2.7%) i/s - 309.723k in 5.039429s
```
I used this regex:
([A-Za-z]+)\.html#(?:class|module)-[A-Za-z]+-label-([A-Za-z0-9\-\+]+)
And performed a global find & replace for this:
rdoc-ref:$1@$2
After the change to use realpath on loaded features, Solaris CI
started failing in test_no_curdir (which tests behavior for running
ruby without a working directory).
I was able to trace the problem to the following call chain:
rb_call_inits->Init_Thread->Init_thread_sync->rb_provide->
get_loaded_features_index->rb_check_realpath->rb_dir_getwd_ospath->
ruby_getcwd
This will throw an exception, but because Ruby hasn't been fully
initialized at the point the exception is thrown, it just exits
with a status of 1.
The bug here is that rb_check_realpath should not raise an
exception, it should return nil. This bug is hit on Solaris
because Solaris uses the realpath emulation instead of native
realpath, and the realpath emualation raised instead of
returning nil if the mode was RB_REALPATH_CHECK. Use rb_rescue
in the realpath emulation if the mode is RB_REALPATH_CHECK, and
swallow any exceptions raised and return nil.
Fill with the pointer to the root position, instead of zero and
comparing later. Also suppress a false warning by Visual C++.
```
file.c(4759): warning C4090: 'function': different 'const' qualifiers
```
Not every compilers understand that rb_raise does not return. When a
function does not end with a return statement, such compilers can issue
warnings. We would better tell them about reachabilities.
Allow the 'Dir.home' method to reliably locate the user's home directory when
all three of the following are true at the same time:
1. Ruby is running on a Unix-like OS
2. The $HOME environment variable is not set
3. The process is not a descendant of login(1) (or a work-alike)
The prior behavior was that the lookup could only work for login-descended
processes.
This is accomplished by looking up the user's record in the password database
by uid (getpwuid_r(3)) as a fallback to the lookup by name (getpwname_r(3))
which is still attempted first (based on the name, if any, returned by
getlogin_r(3)).
If getlogin_r(3), getpwnam_r(3), and/or getpwuid_r(3) is not available at
compile time, will fallback on using their respective non-*_r() variants:
getlogin(3), getpwnam(3), and/or getpwuid(3).
The rationale for attempting to do the lookup by name prior to doing it by uid
is to accommodate the possibility of multiple login names (each with its own
record in the password database, so each with a potentially different home
directory) being mapped to the same uid (as is explicitly allowed for by
POSIX; see getlogin(3posix)).
Preserves the existing behavior for login-descended processes, and adds the
new capability of having Dir.home being able to find the user's home directory
for non-login-descended processes.
Fixes [Bug #16787]
Related discussion:
https://bugs.ruby-lang.org/issues/16787https://github.com/ruby/ruby/pull/3034
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead. This would significantly
speed up incremental builds.
We take the following inclusion order in this changeset:
1. "ruby/config.h", where _GNU_SOURCE is defined (must be the very
first thing among everything).
2. RUBY_EXTCONF_H if any.
3. Standard C headers, sorted alphabetically.
4. Other system headers, maybe guarded by #ifdef
5. Everything else, sorted alphabetically.
Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
We want to introduce consistency and better compatibility with unixen,
but the Windows APIs doues not have consistency fundamentally and
we can not found any logical way...
This reverts commit 61aff0cd18.