mirror of git://sourceware.org/git/glibc.git
realpath: Bring back GNU extension on ENOENT and EACCES [BZ #28996]
The GNU extension for realpath states that if the path resolution fails with ENOENT or EACCES and the resolved buffer is non-NULL, it will contain part of the path that failed resolution. commit949ad78a18broke this when it omitted the copy on failure. Bring it back partially to continue supporting this GNU extension. Resolves: BZ #28996 Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> Reviewed-by: Andreas Schwab <schwab@linux-m68k.org> (cherry picked from commitb416555431)
This commit is contained in:
parent
8a82a76a42
commit
5eae275400
1
NEWS
1
NEWS
|
|
@ -44,6 +44,7 @@ The following bugs are resolved with this release:
|
||||||
variants when avoiding overflow
|
variants when avoiding overflow
|
||||||
[28937] New DSO dependency sorter does not put new map first if in a cycle
|
[28937] New DSO dependency sorter does not put new map first if in a cycle
|
||||||
[28953] nss: Protect against errno changes in function lookup
|
[28953] nss: Protect against errno changes in function lookup
|
||||||
|
[28996] realpath fails to copy partial result on ENOENT and EACCES
|
||||||
[29029] nptl: poll() spuriously returns EINTR during thread
|
[29029] nptl: poll() spuriously returns EINTR during thread
|
||||||
cancellation and with cancellation disabled
|
cancellation and with cancellation disabled
|
||||||
[29039] Corrupt DTV after reuse of a TLS module ID following dlclose with unused TLS
|
[29039] Corrupt DTV after reuse of a TLS module ID following dlclose with unused TLS
|
||||||
|
|
|
||||||
|
|
@ -400,11 +400,14 @@ realpath_stk (const char *name, char *resolved,
|
||||||
|
|
||||||
error:
|
error:
|
||||||
*dest++ = '\0';
|
*dest++ = '\0';
|
||||||
if (!failed && resolved != NULL)
|
if (resolved != NULL)
|
||||||
{
|
{
|
||||||
if (dest - rname <= get_path_max ())
|
/* Copy the full result on success or partial result if failure was due
|
||||||
|
to the path not existing or not being accessible. */
|
||||||
|
if ((!failed || errno == ENOENT || errno == EACCES)
|
||||||
|
&& dest - rname <= get_path_max ())
|
||||||
rname = strcpy (resolved, rname);
|
rname = strcpy (resolved, rname);
|
||||||
else
|
else if (!failed)
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
__set_errno (ENAMETOOLONG);
|
__set_errno (ENAMETOOLONG);
|
||||||
|
|
|
||||||
|
|
@ -174,8 +174,8 @@ do_test (int argc, char ** argv)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only on success verify that buf contains the result too. */
|
/* Verify buf contents if the call succeeded or failed with ENOENT. */
|
||||||
if (result != NULL
|
if ((result != NULL || errno == ENOENT)
|
||||||
&& !check_path (buf, tests[i].out ? tests[i].out : tests[i].resolved))
|
&& !check_path (buf, tests[i].out ? tests[i].out : tests[i].resolved))
|
||||||
{
|
{
|
||||||
printf ("%s: flunked test %d (expected resolved `%s', got `%s')\n",
|
printf ("%s: flunked test %d (expected resolved `%s', got `%s')\n",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue