问题
I am currently building some code that traverses through directorys listing all files and paths and file sizes. I am now stuck with the final part of the traverse process which is the if statement to make the code go into any encountered directories.
do {
char *filename = entry->d_name;
stat(filename,&buffer);
if (S_ISDIR(buffer.st_mode)) {
name = entry->d_name;
chdir(name);
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
listdir(name); //THIS IS THE NAME OF THE FUNCTION THAT THIS SNIPPET IT FROM!
chdir("..");
}
else
printf("%s\t%d\n", entry->d_name,buffer.st_size);
Am so confused by trying to get it to cd into the directory that it encounters! ARGH!
回答1:
The problem, when I executed, was stat()
was failing.
This worked for me:
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
void listdir(const char* const name);
int main(void)
{
listdir(getenv("PWD"));
return 0;
}
void listdir(const char* const name)
{
DIR *dir;
struct dirent *entry;
struct stat buffer;
char* path = 0;
if (!(dir = opendir(name)))
return;
if (!(entry = readdir(dir)))
return;
do {
path =
malloc((strlen(name) + strlen(entry->d_name) + 2) * sizeof(char));
sprintf(path, "%s/%s", name, entry->d_name);
if (-1 == stat(path,&buffer))
{
fprintf(stderr, "stat(%s) failed: %s\n",
path, strerror(errno));
exit(1);
}
else if (S_ISDIR(buffer.st_mode))
{
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
{
listdir(path);
}
}
else
{
printf("%s\t%d\n", path, buffer.st_size);
}
free(path);
} while (entry = readdir(dir));
closedir(dir);
}
EDIT:
Removed call to chdir()
as realised it was superfluous. This does provide listing but does not do it using chdir()
.
回答2:
First, you should use lstat
. Second, with your chdir(name)
call, you actually do go up into parent direectories (when name=".."), but never go back down.
回答3:
The problems lie in this code:
if (S_ISDIR(buffer.st_mode)) {
name = entry->d_name;
chdir(name);
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
listdir(name); //THIS IS THE NAME OF THE FUNCTION THAT THIS SNIPPET IT FROM!
chdir("..");
}
This is embedded in a do-while loop, but you don't show us how the directory entry is read.
The strcmp()
conditions should be applied to the current directory before doing a chdir()
; that is a 'dangerous' operation. When you're sure that you need to process the directory, then you can do chdir()
, open a new directory stream, and process entries from the new stream - which is probably a recursive call, and then chdir()
back again. Your jump after you've done chdir(..)
(because you didn't check for ..
before doing the chdir(name)
) is going to wreak havoc on things.
You should look up fchdir()
which might be better for the purpose of getting back to where you started.
来源:https://stackoverflow.com/questions/8460166/current-working-directory