20

I am accepting the path through command line input.

When I do

dir=opendir(args[1]);

it doesn' t enter the loop...i.e dir==null...

How do I pass the command line input to dir pointer?

void main(int c,char **args)
{
    DIR *dir;
    struct dirent *dent;
    char buffer[50];
    strcpy(buffer, args[1]);
    dir = opendir(buffer);   //this part
    if(dir!=NULL)
    {
        while((dent=readdir(dir))!=NULL)
            printf(dent->d_name);
    }
    close(dir);
}

./a.out  /root/TEST is used to run the program..
./a.out --> to execute the program
/root/TEST --> input by the user i.e valid path
rollstuhlfahrer
  • 3,988
  • 9
  • 25
  • 38
Vinod K
  • 1,885
  • 11
  • 35
  • 45
  • 2
    Please, provide the relevant part of your code. Your question is not clear, at least to me. `opendir` returns a `DIR *`. It returns NULL in 2 situations: the directory couldn't be accessed or memory couldn't be allocated to hold the result. – jweyrich Aug 24 '10 at 07:00
  • @Vinod K: How are you executing this code / what command line are you using to run it? – Thanatos Aug 24 '10 at 07:06
  • @Vinod: Print args[1] and manually check if it exists. 1) Does it exist? 2) Does your path fit in 50 bytes (you should use strncpy)? 3) What happens if you don't pass the paremeter? Add proper conditions there. – jweyrich Aug 24 '10 at 07:08
  • @rasjani how do i accept the answer???..i dint know abt this...am new to this.. – Vinod K Aug 24 '10 at 07:13
  • 1
    @Vinod K - go back through your old questions. Find the answer that best answers the question (if there is one) and click the grey outlined "tick" symbol (it should turn green). – detly Aug 24 '10 at 07:15
  • 1
    I'm going to go out on a limb here and suggest that `/root/TEST` is either not a directory or you do not have permissions to search through it. Try run your code using `/tmp` or `.` as the directory. – paxdiablo Aug 24 '10 at 07:17
  • @Vinod K: Click the outlined check mark, to the left side of the answer you wish to accept. It is right under the vote up/vote down buttons. – Thanatos Aug 24 '10 at 07:18
  • instead of dir=open(buffer) when i do dir=open("/root/TEST")...it works fine. – Vinod K Aug 24 '10 at 07:22
  • @Vinod, I'm assuming you mean `opendir` in that previous comment rather than `open`. What does `ls -ald /root /root/TEST` output? – paxdiablo Aug 24 '10 at 07:24
  • guys......its working...thnx a lot – Vinod K Aug 24 '10 at 07:25
  • Okay, so the problem was ... what, exactly? – paxdiablo Aug 24 '10 at 07:25
  • last thing...what does that [.] and [..] indicate.. – Vinod K Aug 24 '10 at 07:26
  • @Vinod, that's the current and parent directory. Example, if you're in `/dir1/dir2` then `cd .` will leave you there and `cd ..` will take you to `/dir1`. (and keep in mind if you want to talk to someone specific, use the '@paxdiablo' text somewhere in your comment - that way the user gets notified). – paxdiablo Aug 24 '10 at 07:27
  • thnx..the problem ..i dont know...it was not working bfore...now its working...thnx agn.. – Vinod K Aug 24 '10 at 07:29
  • 1
    Ahh, yes, the infamous Heisenbug :-) – paxdiablo Aug 24 '10 at 07:30

4 Answers4

53

You should really post your code(a), but here goes. Start with something like:

    #include <stdio.h>
    #include <dirent.h>

    int main (int argc, char *argv[]) {
        struct dirent *pDirent;
        DIR *pDir;

        // Ensure correct argument count.

        if (argc != 2) {
            printf ("Usage: testprog <dirname>\n");
            return 1;
        }

        // Ensure we can open directory.

        pDir = opendir (argv[1]);
        if (pDir == NULL) {
            printf ("Cannot open directory '%s'\n", argv[1]);
            return 1;
        }

        // Process each entry.

        while ((pDirent = readdir(pDir)) != NULL) {
            printf ("[%s]\n", pDirent->d_name);
        }

        // Close directory and exit.

        closedir (pDir);
        return 0;
    }

You need to check in your case that args[1] is both set and refers to an actual directory. A sample run, with tmp is a subdirectory off my current directory but you can use any valid directory, gives me: testprog tmp

[.]
[..]
[file1.txt]
[file1_file1.txt]
[file2.avi]
[file2_file2.avi]
[file3.b.txt]
[file3_file3.b.txt]

Note also that you have to pass a directory in, not a file. When I execute:

testprog tmp/file1.txt

I get:

Cannot open directory 'tmp/file1.txt'

That's because it's a file rather than a directory (though, if you're sneaky, you can attempt to use diropen(dirname(argv[1])) if the initial diropen fails).


(a) This has now been rectified but, since this answer has been accepted, I'm going to assume it was the issue of whatever you were passing in.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • i meant was ...instead of pDir=opendir("Hardcoding the path") can we like put pDir=opendir(args[1]) Which the user enters? – Vinod K Aug 24 '10 at 07:07
  • 1
    How does one avoid traversing into [.] and [..]? – Jason John Oct 02 '14 at 13:04
  • @jaytj95, you're not traversing a hierarchy here, you're just doing the one level. But the logic would be similar. In the loop, just `strcmp` `pDirent->d_name` against the items you want to ignore and only do the `printf`/traversal for the others. – paxdiablo Apr 22 '20 at 03:59
3

Some feedback on the segment of code, though for the most part, it should work...

void main(int c,char **args)
  • int main - the standard defines main as returning an int.
  • c and args are typically named argc and argv, respectfully, but you are allowed to name them anything

...

{
DIR *dir;
struct dirent *dent;
char buffer[50];
strcpy(buffer,args[1]);
  • You have a buffer overflow here: If args[1] is longer than 50 bytes, buffer will not be able to hold it, and you will write to memory that you shouldn't. There's no reason I can see to copy the buffer here, so you can sidestep these issues by just not using strcpy...

...

dir=opendir(buffer);   //this part

If this returning NULL, it can be for a few reasons:

  • The directory didn't exist. (Did you type it right? Did it have a space in it, and you typed ./your_program my directory, which will fail, because it tries to opendir("my"))
  • You lack permissions to the directory
  • There's insufficient memory. (This is unlikely.)
Thanatos
  • 42,585
  • 14
  • 91
  • 146
2

Parameters passed to the C program executable is nothing but an array of string(or character pointer),so memory would have been already allocated for these input parameter before your program access these parameters,so no need to allocate buffer,and that way you can avoid error handling code in your program as well(Reduce chances of segfault :)).

Anil Vishnoi
  • 1,352
  • 3
  • 18
  • 25
0

Here is a simple way to implement ls command using c. To run use for example ./xls /tmp

    #include<stdio.h>
    #include <dirent.h>
    void main(int argc,char *argv[])
    {
   DIR *dir;
   struct dirent *dent;
   dir = opendir(argv[1]);   

   if(dir!=NULL)
      {
   while((dent=readdir(dir))!=NULL)
                    {
        if((strcmp(dent->d_name,".")==0 || strcmp(dent->d_name,"..")==0 || (*dent->d_name) == '.' ))
            {
            }
       else
              {
        printf(dent->d_name);
        printf("\n");
              }
                    }
       }
       close(dir);
     }
Vijay S B
  • 1,251
  • 1
  • 13
  • 24