Mail Archives: cygwin/2009/08/12/03:05:57
Hi,
Avira will cause findutils configure take a loooong time. And I doubt
many other anti-virus software will cause problems here.
I tried to build findutil, the `configure' hangs (but not really) when
testing long file name. I checked the conftest.c to see where it seemed
to hang.
At the end of the test (after making 1366 folders in straight line), the
code will back up, deleting all the folders one by one.
For the deepest folders, it's taking ~30 seconds to delete each. My
guess is the conservative average will be ~10 secs, and takes ~13000
secs to finish the conftest, so I just terminated the process and
decided to report a bug (I actually did yesterday, but the email seem to
be lost in the way).
Then it occured to me this might be a BLODA issue, so I disabled the
Avira Guard and test again, and the conftest finishes quickly.
The conftest source is below (sorry can't use attachment. You can get it
from findutils-4.5.4/gnulib/m4/getcwd-path-max.m4 too), I only added 2
printf to show folder depth.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#ifndef AT_FDCWD
# define AT_FDCWD 0
#endif
#ifdef ENAMETOOLONG
# define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG)
#else
# define is_ENAMETOOLONG(x) 0
#endif
/* Don't get link errors because mkdir is redefined to rpl_mkdir. */
#undef mkdir
#ifndef S_IRWXU
# define S_IRWXU 0700
#endif
/* The length of this name must be 8. */
#define DIR_NAME "confdir3"
#define DIR_NAME_LEN 8
#define DIR_NAME_SIZE (DIR_NAME_LEN + 1)
/* The length of "../". */
#define DOTDOTSLASH_LEN 3
/* Leftover bytes in the buffer, to work around library or OS bugs. */
#define BUF_SLOP 20
int
main ()
{
#ifndef PATH_MAX
/* The Hurd doesn't define this, so getcwd can't exhibit the bug --
at least not on a local file system. And if we were to start worrying
about remote file systems, we'd have to enable the wrapper function
all of the time, just to be safe. That's not worth the cost. */
exit (0);
#elif ((INT_MAX / (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1) \
- DIR_NAME_SIZE - BUF_SLOP) \
<= PATH_MAX)
/* FIXME: Assuming there's a system for which this is true,
this should be done in a compile test. */
exit (0);
#else
char buf[PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1)
+ DIR_NAME_SIZE + BUF_SLOP];
char *cwd = getcwd (buf, PATH_MAX);
size_t initial_cwd_len;
size_t cwd_len;
int fail = 0;
size_t n_chdirs = 0;
if (cwd == NULL)
exit (1);
cwd_len = initial_cwd_len = strlen (cwd);
while (1)
{
size_t dotdot_max = PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN);
char *c = NULL;
cwd_len += DIR_NAME_SIZE;
/* If mkdir or chdir fails, it could be that this system cannot create
any file with an absolute name longer than PATH_MAX, such as cygwin.
If so, leave fail as 0, because the current working directory can't
be too long for getcwd if it can't even be created. For other
errors, be pessimistic and consider that as a failure, too. */
if (mkdir (DIR_NAME, S_IRWXU) < 0 || chdir (DIR_NAME) < 0)
{
if (! (errno == ERANGE || is_ENAMETOOLONG (errno)))
fail = 2;
break;
}
if (PATH_MAX <= cwd_len && cwd_len < PATH_MAX + DIR_NAME_SIZE)
{
c = getcwd (buf, PATH_MAX);
if (!c && errno == ENOENT)
{
fail = 1;
break;
}
if (c || ! (errno == ERANGE || is_ENAMETOOLONG (errno)))
{
fail = 2;
break;
}
}
if (dotdot_max <= cwd_len - initial_cwd_len)
{
if (dotdot_max + DIR_NAME_SIZE < cwd_len - initial_cwd_len)
break;
c = getcwd (buf, cwd_len + 1);
if (!c)
{
if (! (errno == ERANGE || errno == ENOENT
|| is_ENAMETOOLONG (errno)))
{
fail = 2;
break;
}
if (AT_FDCWD || errno == ERANGE || errno == ENOENT)
{
fail = 1;
break;
}
}
}
if (c && strlen (c) != cwd_len)
{
fail = 2;
break;
}
++n_chdirs;
printf("%d\n", n_chdirs);
}
/* Leaving behind such a deep directory is not polite.
So clean up here, right away, even though the driving
shell script would also clean up. */
{
size_t i;
/* Try rmdir first, in case the chdir failed. */
rmdir (DIR_NAME);
for (i = 0; i <= n_chdirs; i++)
{
printf("%d\n", n_chdirs - i);
if (chdir ("..") < 0)
break;
if (rmdir (DIR_NAME) != 0)
break;
}
}
exit (fail);
#endif
}
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -