• Welcome to Valhalla Legends Archive.
 

Listing directories using POSIX-compliant calls

Started by tA-Kane, February 07, 2006, 08:52 AM

Previous topic - Next topic

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!
Macintosh programmer and enthusiast.
Battle.net Bot Programming: http://www.bash.org/?240059
I can write programs. Can you right them?

http://www.clan-mac.com
http://www.eve-online.com

Kp

[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

netytan

Quote from: tA-Kane on February 07, 2006, 08:52 AM
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!


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.

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. 
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


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.
Macintosh programmer and enthusiast.
Battle.net Bot Programming: http://www.bash.org/?240059
I can write programs. Can you right them?

http://www.clan-mac.com
http://www.eve-online.com

netytan

Quote from: tA-Kane on February 09, 2006, 10:21 AM
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.

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.

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).

Joe[x86]

My way of doing this is rather messy, but oh well?

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;
}
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

MyndFyre

Then if you run the program you lose your current directory.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

iago

Quote from: MyndFyre on February 10, 2006, 05:08 PM
Then if you run the program you lose your current directory.

Doesn't look that way to me:
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$


Yes, it's a bad way of doing it, but not for that reason :P
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


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.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

iago

Quote from: Kp on February 10, 2006, 06:11 PM
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.

You're right, it listed the contents of the CWD, not the root directory.  I never bothered checking :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Joe[x86]

I'm not all that great in C++. I guess I was kind of expecting you do to that yourself. =p
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.