[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ia64 GNU/Linux pwd-long test failure in CVS coreutils
From: |
Jim Meyering |
Subject: |
Re: ia64 GNU/Linux pwd-long test failure in CVS coreutils |
Date: |
Sun, 18 Jun 2006 20:23:05 +0200 |
address@hidden (Bob Proulx) wrote:
> Jim Meyering wrote:
>> I should have created a directory whose abs. name length
>> is a little *larger* than 16K, not just smaller.
>>
>> Does it provoke the failed assertion if you change this line
>>
>> size_t buf_len = 16 * 1024;
>>
>> to e.g., this:
>>
>> size_t buf_len = 20 * 1024;
>
> Yes. At 20k the mkdir succeeds, the chdir succeeds, the desired depth
> is reached and then the getcwd fails. The getcwd fails with errno
> equal to 36 "File name too long" as expected. It cleans up the
> created directory structure.
>
> $ ls -log
> total 36
> -rwxr-xr-x 1 29101 Jun 18 11:54 getcwd-glibc-bug
> -rw-r--r-- 1 1180 Jun 18 11:56 getcwd-glibc-bug.c
> $ ./getcwd-glibc-bug ; echo $?
> 4
Bummer. I was hoping for a failed assertion.
Ohh....
I finally looked at the source for glibc's getcwd.c and see that
the bug is triggered only if you make *glibc* allocate the result buffer.
Would you please try one more time?
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
/* Don't get link errors because mkdir is redefined to rpl_mkdir. */
#undef mkdir
#ifndef S_IRWXU
# define S_IRWXU 0700
#endif
#define TARGET_LEN (20 * 1024)
int
main ()
{
char const *dir_name = "confdir-14B---";
char *cwd;
size_t initial_cwd_len;
int fail = 0;
size_t desired_depth;
size_t d;
cwd = getcwd (NULL, 0);
if (cwd == NULL)
exit (2);
initial_cwd_len = strlen (cwd);
free (cwd);
desired_depth = ((TARGET_LEN - 1 - initial_cwd_len)
/ (1 + strlen (dir_name)));
for (d = 0; d < desired_depth; d++)
{
if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
{
fail = 3; /* Unable to construct deep hierarchy. */
break;
}
}
cwd = getcwd (NULL, 0);
if (cwd == NULL)
fail = 4; /* getcwd failed. This is ok, and expected. */
free (cwd);
/* Call rmdir first, in case the above chdir failed. */
rmdir (dir_name);
while (0 < d--)
{
if (chdir ("..") < 0)
break;
rmdir (dir_name);
}
exit (fail);
}