Program:
#include<stdio.h>
#include<stdlib.h>
#include<dirent.h>
#include<sys/stat.h>
int main(int argc, char *argv[])
{
DIR *dp;
struct dirent *dirp;
struct stat stbuf;
if (argc != 2)
printf("usage: ls directory_name\n");
if ((dp = opendir(argv[1])) == NULL)
printf("can’t open %s", argv[1]);
while ((dirp = readdir(dp)) != NULL){
stat(dirp->d_name,&stbuf);
if(S_ISDIR(stbuf.st_mode)){
printf("Directory: ");
}
printf("%s\n",dirp->d_name);
}
closedir(dp);
exit(0);
}
Output:
$ ./a.out test/
dir3
d
c
Directory: .
Directory: a
Directory: ..
Directory: dir4
Directory: dir2
Directory: dir0
Directory: b
Directory: e
Directory: dir1
$
The following are the list of files that the directory "test" contains.
$ ls -F test/
a b c d dir0/ dir1/ dir2/ dir3/ dir4/ e
$
The expected output is, if the file is directory the output will be "Directory: dir1/". Else only the file name. But, the output of the program is not as expected. Is the program contains any error?. Is there any let me know.
Thanks in Advance...
Lets break it down into steps:
You start your program from some directory. This directory will become the process current working directory (CWD).
You call opendir
on the directory test
. This is actually the directory test
in the CWD.
You call readdir
to get the first entry in the directory.
This first entry is the .
directory, which is short for current directory, all directories have it.
You call stat
with .
, meaning you call stat
on the CWD. It of course succeeds and stat
fills in the structure with all the details of the CWD.
Next iteration you get the entry a
and you call stat
on that entry. However since there is no a
in the CWD, the stat
call fails. You however doesn't check for that, and uses the stat
structure that was filled in from the previous call (from the successful stat
of the .
directory).
And so on...
You need to tell stat
to look for the entries in the given directory instead of the CWD. This can basically be done in only two ways:
Format a string so that you prefix the entry with the directory you passed to opendir
. E.g.
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", argv[1] ,dirp->p_name);
if (stat(path, &stbuf) != -1)
{
// `stat` call succeeded, do something
}
After calling opendir
, but before looping that directory, change the CWD:
// Opendir call etc...
chdir(argv[1]);
// Loop using readdir etc.
Alternatively, start the program from the directory you want to check:
$ cd test
$ ../a.out .