Reputation: 247
EXAMPLE
Imagine I have a directory called Alpha and I want it as root.
INPUT/OUTPUT
Using input as: ./myfind Alpha
I'll want as output:
Alpha
Beta
Gamma
Theta
(I don't care about the order).
MY CODE I tried with this code but it doesn't work. I'll want to do a recursive function to do it and i can't use POSIX.
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#if !defined(NAME_MAX)
#define NAME_MAX 256
#endif
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "ERROR: Run as ./myfind directory\n");
exit(EXIT_FAILURE);
}
const char *dir = argv[1];
struct stat statbuf;
stat(dir, &statbuf);
if (!S_ISDIR(statbuf.st_mode)) {
fprintf(stderr, "FATAL ERROR: %s IS NOT A DIRECTORY\n", dir);
exit(EXIT_FAILURE);
}
find(dir);
exit(EXIT_SUCCESS);
}
Upvotes: 1
Views: 64
Reputation: 145277
The problem is you change the current directory when you recurse into a subdirectory but you do not change back to the parent directory when returning from the recursive function.
You could add a chdir("..");
at the end of the find
function, but it might not work in all cases:
It is preferable to compute the path of the destination directory for the recursive call to find()
by concatenating the passed_dir_name
, a /
and dir->d_name
and avoid changing the current directory.
Here is a modified version of find()
for the simplistic approach:
int find(const char *passed_dir_name) {
if (chdir(passed_dir_name) == -1) {
perror("FATAL ERROR CHANGING DIRECTORY");
return -1;
}
DIR *current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("FATAL ERROR OPENING CURRENT WORKING DIRECTORY");
chdir("..");
return -1;
}
struct dirent *dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
fprintf(stdout, "%s\n", dir->d_name);
find(dir->d_name);
}
}
if (closedir(current_directory) == -1) {
perror("FATAL ERROR CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
chdir("..");
}
Upvotes: 1