How to find Directory in Linux using c?

I'm making a c program in linux where a user could enter the directory name to be found. I Following is the code I have written but not getting the correct output. I'm searching through all directories till I found the directory. I'm just a beginner.

#include<unistd.h>
#include<dirent.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<errno.h>

void findDir(char *dir, char *name)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    if((dp = opendir(dir)) == NULL)
    {
        printf("\ncan not open directory: %s", name);
        printf("\nDescription: %s", strerror(errno));
        return;
    }

    chdir(dir);

    while(( entry = readdir(dp)) != NULL)
    {
        lstat( entry->d_name, &statbuf);
        if(S_ISDIR( statbuf.st_mode))
        {
            if( strcmp(name,entry->d_name) == 0)
            {
                printf("Dir found");
                return;
            }
            findDir(entry->d_name, name);
        }
    }
    chdir("..");
    closedir(dp);
}

void main(int argc, char *argv[])
{
    if( argc != 2 )
    {
        printf("Error");
    }
    else
    {
        findDir("/home", argv[1]);
    }
}

Please Help!! I get the follwing output while giving Documents as argument. Actually program goes infinite and i repeteadly get the following output. This is just a little of the output.

can not open directory: Documents Description: Too many open files can not open directory: Documents Description: Too many open files can not open directory: Documents Description: Too many open filesDir found

Answers


I took a quick look at this. Here is some advice.

  • When debugging, either single-step in a debugger or at least put some print statements to see what is really happening. I put in a printf() in the loop that walks the directories, and found that right away it is trying to visit the .. directory, so it leaves /home and loops forever.

  • So, in your loop, before you do anything else, test to see if entry->d_name is "." or "..", and if so, skip that directory entry (you can just use the continue keyword).

  • Make sure you call closedir(dp); before the function returns. For example, when your code prints the message can not open directory:, your function returns without closing the directory. By the way, you should print entry->d_name in that error message, not name.

The error Too many open files is because your loop is following .. so it will never stop, and it finds plenty of directories it cannot open, so the code not calling closedir() on error exit means more and more directories are left open.

  • Your program will keep on going after it finds the target directory! It will print a message but keep on going. You can modify your function findDir() to return a code saying whether it found the target or not, and make your program stop in this case.

The problem is that readdir() is not re-entrant. It relies on an internal buffer which, when you recurse, is being overwritten. If you're using a POSIX standard, you can try readdir_r which is re-entrant.

Or, you can read the directory into a list before you start to recurse, then process the items in the list one at a time. That way you've read the entire directory before you try to dive down the next level in the directory tree and the entries at the current level won't be lost to the overwrite at the deeper level.


Another problem you're going to run into here (and the one that's probably affecting you most right now) is that the special directory entries . and .. will show up in the results from opendir()/readdir(). You will need to check for and skip these two using something along the lines of:

if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
    continue;

You'll better use the nftw(3) library function, which is able to walk recursively thru a file tree.

If you are not allowed to use it, you could at least study its source, e.g. from the MUSL libc file src/misc/nftw.c which I find quite readable.

BTW, your call to lstat is wrong in your code, you need to construct the entire file path.

You need to use the gdb debugger on your program. You may also want to use strace to understand which syscalls it is doing (and strace-ing some find command would also teach you many things).


Need Your Help

jQuery Unobtrusive client-side validation of custom attribute

jquery asp.net-mvc validation asp.net-mvc-4 unobtrusive-validation

I have created a custom validation attribute which works server-side (after form is posted) but I cannot get the validation to work client-side.

Facebook app not asking for auth

javascript facebook facebook-javascript-sdk

I have a page on my website where I use the Facebook JS SDK and users click like to reveal a discount code, via a newly created app of mine.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.