Valhalla Legends Forums Archive | General Programming | Listing directories using POSIX-compliant calls

AuthorMessageTime
tA-Kane
Let's say I've passed my program a directory that it needs to search all files and subdirectories for anything that matches a specific filename. It needs to be POSIX-compliant.

After about two hours of searching the 'net using google, I've come up with little as far as results. The best I can come up with is that fopen() will fail and set errno to EISDIR, if you do not try to open a directory with write access. With that in mind, how would I get the names of all entities in a directory? Or is there another way to do this, which I am simply too blind to see?

I did find this nice little function, but it appears (according to the read) to be only for BSD.

I would like it to be as easy as calling FindFirstFile/FindNextFile/FindClose using the WinAPI, but again, sadly that's not POSIX compliant.  :(

Any help would be appreciated!
February 7, 2006, 2:52 PM
Kp
See opendir(3), readdir(3), closedir(3).
February 8, 2006, 12:30 AM
netytan
[quote author=tA-Kane link=topic=14183.msg145003#msg145003 date=1139323974]
Let's say I've passed my program a directory that it needs to search all files and subdirectories for anything that matches a specific filename. It needs to be POSIX-compliant.

After about two hours of searching the 'net using google, I've come up with little as far as results. The best I can come up with is that fopen() will fail and set errno to EISDIR, if you do not try to open a directory with write access. With that in mind, how would I get the names of all entities in a directory? Or is there another way to do this, which I am simply too blind to see?

I did find this nice little function, but it appears (according to the read) to be only for BSD.

I would like it to be as easy as calling FindFirstFile/FindNextFile/FindClose using the WinAPI, but again, sadly that's not POSIX compliant.  :(

Any help would be appreciated!

[/quote]

Not really about how to access a dir, Kp pretty much has that covered there :). Of course there are other ways but they're less cross platform such as though system calls so you should probably ignore them.

Anyway, I'd like to offer a little suggestion about searching directories (or trees in general). I've found that the best technique for searching this kind of structure is through recursion, the code will be a lot easier to follow than if you had loops & nested-loops & nested-nested-loops...

You've likely figure this much out already but just incase you haven't thought it worth mentioning just incase.

Mark.
February 8, 2006, 2:59 PM
iago
Of course, recursion is also dog-slow and should be replaced with iteration in just about every scenario.  So it's up to you to make a choice, depending on what you're trying to do. 
February 9, 2006, 12:43 AM
tA-Kane
I fail to see how recursion is "dog-slow", when for every time through, you must still set up and break down the structures which you used in order to create a non-recursive algorithm.
February 9, 2006, 4:21 PM
netytan
[quote author=tA-Kane link=topic=14183.msg145284#msg145284 date=1139502092]
I fail to see how recursion is "dog-slow", when for every time through, you must still set up and break down the structures which you used in order to create a non-recursive algorithm.[/quote]

Have to agree here :) even though [most] compilers don't optimize recursion it doesn't make it slow. Recursion lends itself more naturally to a lot of different tasks, often more flexibly. In general recursive code is easier to read because you avoid state change – state changing is a performance hit on it's own, but Has been highly optimized.

Recursion helps avoid this state change and prevent the programmer from having to set up intermediate data structures to hold the results, rather than using the return value of a function ;).

Either way, the simplicity of expression should be reason enough to use recursion where appropriate.

Enjoy,

Mark.
February 9, 2006, 5:51 PM
Skywing
I think iago was thinking of some problems where there is an easy recursive solution that can get exponentially slow vs a harder iterative solution that has a much smaller complexity factor; a good example of this is wildcard pattern matching.

This isn't necessarily true of all recursive solutions (higher algorithmic complexity).  However, there are still good reasons to be wary of recursion, especially if you are going to be traversing an arbitrarily long structure; it's easy to blow the stack and crash with a stack overflow, particularly if the thing you are recursing is something that is provided as user input in some form (like a user writable directory tree).
February 9, 2006, 6:51 PM
JoeTheOdd
My way of doing this is rather messy, but oh well?

[code]int main()
{
  system("cd /");
  system("ls > /tmp/lsresult");
  // open /tmp/lsresult, on each line, check if theres a file size (if not its a directory)
  return 0;
}
[/code]
February 10, 2006, 10:46 PM
Myndfyr
Then if you run the program you lose your current directory.
February 10, 2006, 11:08 PM
iago
[quote author=MyndFyre link=topic=14183.msg145478#msg145478 date=1139612925]
Then if you run the program you lose your current directory.
[/quote]

Doesn't look that way to me:
[code]ron@slayer:~/tmp$ cat test.c
#include <stdlib.h>

int main()
{
        system("cd /");
        system("ls > /tmp/lsresult");

        return 0;
}

ron@slayer:~/tmp$ gcc -Wall -ansi test.c
ron@slayer:~/tmp$ ./a.out
ron@slayer:~/tmp$
[/code]

Yes, it's a bad way of doing it, but not for that reason :P
February 10, 2006, 11:52 PM
Kp
Pretty sure Joe's way won't work anyway, since it should spawn a separate process to do the cd, leaving the cwd of the parent process alone.  Now, if he'd used chdir("/") instead of system("cd /"), it'd work.  It might also work on some very damaged operating systems that try to let processes change other processes' environments, but that's dangerous anyway and should never be done.
February 11, 2006, 12:11 AM
iago
[quote author=Kp link=topic=14183.msg145496#msg145496 date=1139616664]
Pretty sure Joe's way won't work anyway, since it should spawn a separate process to do the cd, leaving the cwd of the parent process alone.  Now, if he'd used chdir("/") instead of system("cd /"), it'd work.  It might also work on some very damaged operating systems that try to let processes change other processes' environments, but that's dangerous anyway and should never be done.
[/quote]

You're right, it listed the contents of the CWD, not the root directory.  I never bothered checking :)
February 11, 2006, 12:53 AM
JoeTheOdd
I'm not all that great in C++. I guess I was kind of expecting you do to that yourself. =p
February 11, 2006, 11:01 PM

Search