I just started learning linux/C, i just want to show the names of all the files of the directories given in argument, and their access permissions by using stat() which causes some problems. It actually shows the correct name/mode of all the files included in the current directory, but for the other directories given in argument, it does give the right name but the same st_mode for all the files…
here’s my code:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <dirent.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> int main(int argc, char *argv[]) { printf("Hello, world!n"); int status; struct stat sbuf; DIR *dirp; struct dirent *dp; dp = (struct dirent*) malloc(sizeof(struct dirent)); for (int i=1; i<argc; i++){ dirp = opendir(argv[i]); if (dirp == NULL){/*perror("Argument invalide");*/printf("Argument %d invalid", i); exit(1);} printf("nnOpening %sn", argv[i]); do{ dp = readdir(dirp); if (dp != NULL && strcmp(dp->d_name,".") && strcmp(dp->d_name, "..")) { status = stat(dp->d_name,&sbuf); printf("The file is %s tMode :%on", dp->d_name, (sbuf.st_mode & 0777)); } } while (dp != NULL); closedir(dirp); } return 0; }
for example I did try this :
gcc -o test main.c
then
./test . ..
And here’s the result !
Opening . The file is c.txt Mode :644 The file is d.txt Mode :644 The file is xxxx.txt Mode :777 The file is test Mode :755 Opening .. The file is a.txt Mode :755 The file is b.txt Mode :755 The file is dossier Mode :755 The file is main Mode :755 The file is main.c Mode :755 The file is test Mode :755
As you can see, all the files of the ” .. ” directory have the same Mode, which is completely wrong… I did try with full paths and different directories, same problem.
Advertisement
Answer
Well, stat
isn’t giving you the file information because readdir
gives you the file name, not the path. Try something like this to build up the path so you can actually call stat
.
char *path = malloc(strlen(dp->d_name) + strlen(argv[i]) + 2); stpcpy(stpcpy(stpcpy(path, argv[i]), "/"), dp->d_name); status = stat(path,&sbuf); free(path);