LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-04-2015, 07:02 AM   #1
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
readdir on centos 7


I'm seeing an issue on a CentOS 7 x86-64 VM in which readdir() is reporting that each file that it finds is of an unknown type (DT_UNKNOWN).

I've verified that the path (and files within such) are all readable, but still no joy. Directories have permissions of 0755 and files of 0644.

If you have a similar system, can you please confirm whether this issue is endemic to only my system, or whether it is a general bug with this particular OS.

Similar tests on CentOS 6 and Ubuntu do not show a similar problem.

Thank you.

Btw, here's the sample C++ application I'm using where I pass the path to the directory to search (for XML files) containing the .xml extension:
Code:
#include <dirent.h>
#include <cstring>
#include <vector>
#include <string>
#include <iostream>

using namespace std;


typedef vector< string > StrVector;


StrVector getWildCardTokens( const string &wildcard )
{
  StrVector wildCardList;

  char *token = strtok( (char*) wildcard.c_str(), "*" );

  while ( token != NULL )
  {
    wildCardList.push_back( token );
    token = strtok( NULL, "*" );
  }

  return wildCardList;
}

void getAllFiles( StrVector &fileList, const string &dirName, const StrVector &wildCards )
{
  DIR *dirp = opendir( dirName.c_str() );

  if ( dirp )
  {
    struct dirent *dp = NULL;

    while ( (dp = readdir( dirp )) != NULL )
    {
        string file( dp->d_name );

        if ( file == "." || file == ".." )    // skip these
          continue;

        if ( dp->d_type & DT_DIR )
        {
          // found a directory; recurse into it.
          string filePath = dirName + "/" + file;

          getAllFiles( fileList, filePath, wildCards );
        }
        else if (dp->d_type == DT_UNKNOWN)
        {
            std::cerr << "Unknown file: " << dirName << "/" << file << std::endl;
        }
        else
        {
          bool matches = true;

          // found a file; check if all of the wildcard tokens exist in its name.
          // search linearly thru the file name (i.e. continue where the last token
          // is found).
          for ( size_t i = 0, pos = 0; i < wildCards.size(); ++i )
          {
            if ( (pos = file.find( wildCards[i], pos )) == string::npos )
            {
              matches = false;
            }
          }

          if ( matches )
          {
            fileList.push_back( dirName + "/" + file );
          }
        }
    }

    closedir( dirp );
  }
}

int main( int argc, char **argv )
{
  string dir      = argc > 1 ? argv[1] : "/tmp";
  string wildcard = argc > 2 ? argv[2] : "*.xml";

  StrVector wildCardTokens = getWildCardTokens( wildcard );

  StrVector fileList;
  getAllFiles( fileList, (argc > 1 ? argv[1] : dir), wildCardTokens );

  cout << "Found " << fileList.size() << " file(s)." << endl;
  for ( size_t i = 0; i < fileList.size(); ++i )
  {
    cout << "found file " << fileList[i] << endl;
  }
}
------------

Edit:

I wanted to add that on the CentOS 6 system, the files are reported to have the following type (using the 'file' command):
Code:
MyFile.xml: ASCII HTML document text
On CentOS 7, the result is:
Code:
MyFile.xml: exported SGML document, ASCII text
Why the difference?

Last edited by dwhitney67; 03-04-2015 at 07:10 AM. Reason: Added info regarding files types.
 
Old 03-04-2015, 07:10 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,860
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
My manual says:
Code:
...
unsigned char  d_type;      /* type of file; not supported by all file system types */
...
so I think you have to call (l)stat(2) if d_type==DT_UNKNOWN
 
Old 03-04-2015, 07:10 AM   #3
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,860
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Question#2: utility 'file' keeps improving

Last edited by NevemTeve; 03-04-2015 at 07:12 AM.
 
Old 03-04-2015, 07:56 AM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Original Poster
Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by NevemTeve View Post
My manual says:
Code:
...
unsigned char  d_type;      /* type of file; not supported by all file system types */
...
so I think you have to call (l)stat(2) if d_type==DT_UNKNOWN
I added this to my code to check whether d_type is supported, and it is.
Code:
...
#ifdef _DIRENT_HAVE_D_TYPE
int haveType = 1;
#else
int haveType = 0;
#endif

int main( int argc, char **argv )
{
  std::cout << "_DIRENT_HAVE_D_TYPE is " << haveType << std::endl;    // expected result is haveType == 1

  ...
}
I think the issue may somehow be related to the file system type in use on the CentOS 7 system. RHEL7 and CentoOS 7 now use XFS as the default file system, whereas with previous OS releases I believe EXT4 was the default.
 
Old 03-04-2015, 08:01 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,860
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
I think text 'not supported' in manual means 'is not filled with useful value'
 
Old 03-04-2015, 08:11 AM   #6
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Original Poster
Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by NevemTeve View Post
I think text 'not supported' in manual means 'is not filled with useful value'
I will accept your answer. After I re-read the man-page, it is quite apparent that I should not assume that the d_type is usable. From the man-page:
Quote:
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.
However, further down (and this is why I think you are correct):
Quote:
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.
Since CentOS 7 is using the XFS file system, it is quite logical that d_type could very well be set to DT_UNKNOWN.

So, in conclusion, I will need to use lstat(2).

Thank you for your help... and for the enlightenment.
 
  


Reply

Tags
centos7, readdir



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
readdir() question MTK358 Programming 3 05-25-2011 07:10 PM
question on readdir() pcube Programming 3 09-04-2009 08:27 AM
Perl: Using readdir and . .. cramer Programming 7 04-24-2008 03:25 AM
about readdir r_213 Programming 1 01-16-2005 11:26 PM
Regarding readdir r_213 Linux - Networking 2 01-15-2005 07:56 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:46 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration