Building the linux version of 7zz on Centos 7.x running on an XFS file system (default filesystem for Redhat 7.x) I ran into an issue where file scanning operations would follow '.' and '..' paths recursively until it exhausted the path space.
Example:
WARNING: errno=36 : File name too long
/tmp/data/././././././././././././././././././ [snip] ././././././././..
I ran through the debugger and noticed the IsDots() function that filters out '.' and '..' was failing because it was first testing whether it was a directory (!IsDir()) which was coming back as false. IsDir() checks whether Type == DT_DIR which it was not; it was zero ('0').
Type is set by the NextAny() which calls readdir() and then sets Type from de->d_type. The manpage for readdir() says this:
The only fields in the dirent structure that are mandated by POSIX.1 are: d_name[], of unspecified size, with at most NAME_MAX characters preceding the terminating null byte ('\0'); and (as an XSI extension) d_ino. The other fields are unstandardized, and not present on all systems; see NOTES below for some further details. NOTES: Other than Linux, the d_type field is available mainly only on BSD systems. This field makes it possible to avoid the expense of calling lstat(2) if further actions depend on the type of the file. If the file type could not be determined, the value DT_UNKNOWN is returned in d_type. Currently, only some file systems (among them: Btrfs, ext2, ext3, and ext4) have full support for returning the file type in d_type. All applications must properly handle a return of DT_UNKNOWN.
DT_UNKNOWN is zero, so in my case with my xfs filesystem I was not getting the DT_DIR value set, which would cause IsDots() to always fail causing infinite recursion through the directory tree.
I added the following after the 'fi.Type = de->d_type' (around line 1140 in FileFind.cpp)
if (fi.Type == DT_UNKNOWN)
{
struct stat st;
if (MY__lstat(de->d_name, &st, true) == 0 && S_ISDIR(st.st_mode) == 1)
{
fi.Type = DT_DIR;
}
}
which fixed the problem for me.
Thanks for report!
I'll fix that problem in another function.
Last edit: Igor Pavlov 2021-09-10