UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#1 2009-04-16 08:34 PM

xinglp
Member
Registered: 2008-04-13
Posts: 35

Re: About getdents and file type

When I use getdents() on ext2, I got some info in "*(Buf+Pos+DirEnt->d_reclen-1)", like "is it a dir or file". But I got nothing on reiserfs.

How can I get that on reiserfs othet than use lstat().

This is my code.

void ListDir(const char* DirPath)
{
	int                 DirFd;
	char              Buf[1024*128];
	int                 Len;
	int                 Pos;
	struct dirent*  DirEnt;

	DirFd=open(DirPath,O_RDONLY|O_NONBLOCK|O_DIRECTORY);
	if(-1==DirFd)
	{
		return;
	}

	Len=syscall(SYS_getdents,DirFd,Buf,sizeof(Buf));
//	Len=getdents(,DirFd,Buf,sizeof(Buf));

	for(Pos=0;Pos<Len;Pos+=DirEnt->d_reclen)
	{
		DirEnt=(struct dirent*)(Buf+Pos);
		printf(
			"%u\t%s\t%u\r\n",
			DirEnt->d_reclen,
			DirEnt->d_name,
			*(Buf+Pos+DirEnt->d_reclen-1)
			);
	}

	close(DirFd);
}

Thanks

Offline

#2 2009-04-16 09:00 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,829
Website

Re: About getdents and file type

What about the "d_type" field?  Is that not filled in?

Also, why not use the glibc getdirentries() instead of directly calling the syscall?  Or,
for that matter, opendir()+readdir(), or scandir(), or something a lot easier to use?

Offline

#3 2009-04-16 09:41 PM

xinglp
Member
Registered: 2008-04-13
Posts: 35

Re: About getdents and file type

I have use opendir()+readdir(), It didn't fill in d_type on reiserfs.
But then work fine on ext2.

Offline

#4 2009-04-16 11:31 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,829
Website

Re: About getdents and file type

*shrug*  I don't know, maybe Reiserfs just sucks... ;-)  I've never used it, and have
heard nothing but bad things from those who have...

Offline

#5 2009-04-17 12:29 AM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,230

Re: About getdents and file type

Reiserfs is okay, mostly for small files because it appends file data to the inode
for small files. It should be quite reliable too by now. ;-)

Looking at the source, Reiserfs indeed doesn't set d_type, but on the other
hand that field only exists since Linux 2.6.4, so you can't count on it being
filled in anyway.

Offline

#6 2009-04-17 01:25 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,829
Website

Re: About getdents and file type

Looking at the source, Reiserfs indeed doesn't set d_type, but on the other
hand that field only exists since Linux 2.6.4, so you can't count on it being
filled in anyway.

I'm certain I was using "d_type" long ago, on at least 2.4.x kernels...   Hmmm, the
oldest box I can access at the moment is runing 2.4.20 (RH7.3), and its struct dirent
definitely contains "d_type"...  I'm talking about the user-space glibc struct dirent; the
kernel definition doesn't seem to contain it even on my 2.6.18 (CentOS5) box...  But,
"struct dirent64" DOES have it (on both systems)... *shrug*  Weird...

Offline

#7 2009-04-17 07:59 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,230

Re: About getdents and file type

As he's calling getdents(2) directly, he should probably call getdents64() instead.

My manpage says that d_type in  struct linux_dirent is only filled in since 2.6.4...

Offline

#8 2009-04-17 10:06 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,829
Website

Re: About getdents and file type

My getdents() man page (on CentOS5) doesn't mention anything about "d_type", and
my local kernel "struct dirent" from "/usr/include/linux/dirent.h" has no "d_type" (but
"struct dirent64" does)...  My local kernel headers define a "struct linux_dirent64" (with
"d_type"), but no "struct linux_dirent" at all...

However, I'm referring entirely to user-space/glibc, when *I* am talking about using
"d_type"...  Unless there's some rational reason for directly calling syscalls like that,
I'd recommend against it...  Just use glibc, and hopefully it will take care of anything
needed to make sure the data is filled in properly, if at all possible...  And, glibc's
"struct dirent" has had a "d_type" as long as I can recall...  Though, I believe it has
also always been documented to be possibly set to DT_UNKNOWN in some cases,
so you always are supposed to check for that and do the work of figuring out file type
by other means, if necessary...  Yeah, here's a man page that says that in the notes...
And, this glibc reference...  (Strangely, my local readdir() man page doesn't mention that caveat...)

Offline

#9 2009-04-18 03:51 PM

xinglp
Member
Registered: 2008-04-13
Posts: 35

Re: About getdents and file type

Thanks.

As I need to get the size,date of file, I use stat() now, so that's not a question. I'm just curious about this.

I didn't use opendir() readdir() because they use malloc(). I always prepare all the memory before enter "work loop".

Offline

#10 2009-04-18 04:10 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,230

Re: About getdents and file type

So what that malloc is used? Is it too slow, and if it is, is your approach faster?

Offline

#11 2009-04-18 04:29 PM

xinglp
Member
Registered: 2008-04-13
Posts: 35

Re: About getdents and file type

valgrind tell me opendir() used malloc(). (valgrind tell one more malloc() when opendir() is called).

opendir() is the same speed with getdents()/getdents64().:rolleyes:

Offline

#12 2009-04-18 05:59 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,829
Website

Re: About getdents and file type

Have you tried scandir() instead?  That's my usual prefered approach...  It may not
end up being any more efficient though... *shrug*

But, even if you want the low-level do-it-yourself aspect of getdents(), you should
still use the glibc cover function for that syscall, instead of the syscall directly, which
in this case is getdirentries()...  That's pretty much a direct cover for getdents64(),
but which will do the work of filling "d_type" even if its stored at the end of "d_name"
or whatever...

Offline

#13 2009-04-18 08:28 PM

xinglp
Member
Registered: 2008-04-13
Posts: 35

Re: About getdents and file type

Thanks a lot. getdirentries() seems better than syscall(..),

Offline

Board footer

Powered by FluxBB