diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libc/stdlib/realpath.3 | 36 | ||||
| -rw-r--r-- | lib/libc/stdlib/realpath.c | 10 | ||||
| -rw-r--r-- | lib/libc/tests/stdlib/cxa_thread_atexit_nothr_test.cc | 11 | ||||
| -rw-r--r-- | lib/libc/tests/stdlib/cxa_thread_atexit_test.cc | 10 |
4 files changed, 35 insertions, 32 deletions
diff --git a/lib/libc/stdlib/realpath.3 b/lib/libc/stdlib/realpath.3 index 76f40249963b..a17ddee0b2f1 100644 --- a/lib/libc/stdlib/realpath.3 +++ b/lib/libc/stdlib/realpath.3 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd October 10, 2025 +.Dd March 18, 2026 .Dt REALPATH 3 .Os .Sh NAME @@ -75,27 +75,24 @@ must exist when is called, and all but the last component must name either directories or symlinks pointing to the directories. .Sh "RETURN VALUES" -The +On success, the .Fn realpath function returns .Fa resolved_path -on success. -If the function was supplied -.Dv NULL -as -.Fa resolved_path , -and operation did not cause errors, the returned value is -a null-terminated string in a buffer allocated by a call to -.Fn malloc 3 . +if it was not +.Dv NULL , +or a pointer to a null-terminated string which must be freed by the +caller if it was. If an error occurs, .Fn realpath returns .Dv NULL , and if .Fa resolved_path -is not +was not .Dv NULL , -the array that it points to contains the pathname which caused the problem. +the array that it points to contains the pathname which caused the +problem. .Sh ERRORS The function .Fn realpath @@ -107,6 +104,9 @@ for any of the errors specified for the library functions and .Xr getcwd 3 . .Sh SEE ALSO +.Xr basename 3 , +.Xr dirname 3 , +.Xr free 3 , .Xr getcwd 3 .Sh STANDARDS The @@ -118,15 +118,3 @@ The .Fn realpath function first appeared in .Bx 4.4 . -.Sh CAVEATS -This implementation of -.Fn realpath -differs slightly from the Solaris implementation. -The -.Bx 4.4 -version always returns absolute pathnames, -whereas the Solaris implementation will, -under certain circumstances, return a relative -.Fa resolved_path -when given a relative -.Fa pathname . diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c index 18f29e95ee6b..9dc0cc4d3dd4 100644 --- a/lib/libc/stdlib/realpath.c +++ b/lib/libc/stdlib/realpath.c @@ -98,7 +98,6 @@ realpath1(const char *path, char *resolved) left_len = 0; } - prev_len = resolved_len; if (resolved[resolved_len - 1] != '/') { if (resolved_len + 1 >= PATH_MAX) { errno = ENAMETOOLONG; @@ -129,7 +128,9 @@ realpath1(const char *path, char *resolved) /* * Append the next path component and lstat() it. */ - resolved_len = strlcat(resolved, next_token, PATH_MAX); + prev_len = resolved_len; + resolved_len += strlcpy(resolved + prev_len, next_token, + PATH_MAX - prev_len); if (resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; return (NULL); @@ -141,8 +142,11 @@ realpath1(const char *path, char *resolved) * directory is not a directory. Rewind the path * to correctly indicate where the error lies. */ - if (errno == EACCES || errno == ENOTDIR) + if (errno == EACCES || errno == ENOTDIR) { + if (prev_len > 1) + prev_len--; resolved[prev_len] = '\0'; + } return (NULL); } if (S_ISLNK(sb.st_mode)) { diff --git a/lib/libc/tests/stdlib/cxa_thread_atexit_nothr_test.cc b/lib/libc/tests/stdlib/cxa_thread_atexit_nothr_test.cc index 0b3b9497a6bd..d70c6b1b88dc 100644 --- a/lib/libc/tests/stdlib/cxa_thread_atexit_nothr_test.cc +++ b/lib/libc/tests/stdlib/cxa_thread_atexit_nothr_test.cc @@ -30,7 +30,10 @@ #include <cstdio> #include <cstdlib> +#define AGAIN_CALL_LIMIT 20 + static FILE *output = NULL; +static int again_counter = 0; struct Foo { Foo() { ATF_REQUIRE(fprintf(output, "Created\n") > 0); } @@ -79,14 +82,16 @@ extern "C" int __cxa_thread_atexit(void (*)(void *), void *, void *); static void again(void *arg) { - - __cxa_thread_atexit(again, arg, &output); + if (again_counter < AGAIN_CALL_LIMIT) { + again_counter++; + __cxa_thread_atexit(again, arg, &output); + } } ATF_TEST_CASE_WITHOUT_HEAD(cxx__thread_inf_dtors); ATF_TEST_CASE_BODY(cxx__thread_inf_dtors) { - + skip("Skip since we only have main thread"); again(NULL); } diff --git a/lib/libc/tests/stdlib/cxa_thread_atexit_test.cc b/lib/libc/tests/stdlib/cxa_thread_atexit_test.cc index 628a70b510d1..6a5587698d37 100644 --- a/lib/libc/tests/stdlib/cxa_thread_atexit_test.cc +++ b/lib/libc/tests/stdlib/cxa_thread_atexit_test.cc @@ -30,7 +30,10 @@ #include <cstdlib> #include <thread> +#define AGAIN_CALL_LIMIT 20 + static FILE *output = NULL; +static int again_counter = 0; struct Foo { Foo() { ATF_REQUIRE(fprintf(output, "Created\n") > 0); } @@ -52,8 +55,10 @@ extern "C" int __cxa_thread_atexit(void (*)(void *), void *, void *); static void again(void *arg) { - - __cxa_thread_atexit(again, arg, &output); + if (again_counter < AGAIN_CALL_LIMIT) { + ++again_counter; + __cxa_thread_atexit(again, arg, &output); + } } struct Baz { @@ -164,6 +169,7 @@ ATF_TEST_CASE_BODY(cxx__thread_inf_dtors) std::thread t([]() { e.use(); }); t.join(); + ATF_REQUIRE_EQ(again_counter, AGAIN_CALL_LIMIT); } ATF_INIT_TEST_CASES(tcs) |
