Issue
I've done a C program that does what the ls -aln
command does, but I have a problem.
I expect this results :
drwxr-xr-x@ 6 seven staff 192 19 fév 18:58 .
drwxr-xr-x@ 4 seven staff 128 6 fév 00:37 ..
drwxr-xr-x@ 7 seven staff 224 17 fév 15:00 .idea
-rw-r--r--@ 1 seven staff 104 5 fév 17:37 CMakeLists.txt
drwxr-xr-x@ 11 seven staff 352 19 fév 18:58 cmake-build-debug
-rw-r--r--@ 1 seven staff 2144 19 fév 18:58 main.c
but instead I'm having this:
d-----rwxr-xr-x 11 352 seven staff .
d-----rwxr-xr-x 6 192 seven staff ..
d-----rwxr-xr-x 6 192 seven staff cmake-build-debug
d-----rwxr-xr-x 6 192 seven staff CMakeLists.txt
d-----rwxr-xr-x 6 192 seven staff main.c
d-----rwxr-xr-x 6 192 seven staff .idea
Basically my number of links is not what I expected, size of files is not what I expected, the permissions are not all what I expected and then it says that all files are directory and add a "-" after that. I know it's probably caused by all the printf but I don't know how to fix this.
here is my code:
int main() {
char* curr_dir = NULL;
DIR* dir = NULL;
struct dirent* entity = NULL;
struct stat fileStat;
struct passwd* pwd;
struct group* gid;
curr_dir = getenv("PWD");//current directory with PWD
if (curr_dir==NULL){
printf("ERROR: j'ai pas pris le repertoire courrant");
}
dir = opendir("/Users/seven/Desktop/Programmazione/TP");
if(dir == NULL) {
printf("ERROR: j'ai pas pue ouvrir le repertoire");
}
while((entity = readdir(dir)) != NULL){
stat(entity->d_name, &fileStat);
printf((S_ISDIR(fileStat.st_mode)) ? "d" : "-");
printf((S_ISLNK(fileStat.st_mode)) ? "l" : "-");
printf((S_ISSOCK(fileStat.st_mode)) ? "s" : "-");
printf((S_ISFIFO(fileStat.st_mode)) ? "p" : "-");
printf((S_ISBLK(fileStat.st_mode)) ? "b" : "-");
printf((S_ISCHR(fileStat.st_mode)) ? "c" : "-");
printf((fileStat.st_mode & S_IRUSR) ? "r" : "-");
printf((fileStat.st_mode & S_IWUSR) ? "w" : "-");
printf((fileStat.st_mode & S_IXUSR) ? "x" : "-");
printf((fileStat.st_mode & S_IRGRP) ? "r" : "-");
printf((fileStat.st_mode & S_IWGRP) ? "w" : "-");
printf((fileStat.st_mode & S_IXGRP) ? "x" : "-");
printf((fileStat.st_mode & S_IROTH) ? "r" : "-");
printf((fileStat.st_mode & S_IWOTH) ? "w" : "-");
printf((fileStat.st_mode & S_IXOTH) ? "x" : "-");
printf("\t %u", fileStat.st_nlink);
printf("\t %lld", fileStat.st_size);
pwd = getpwuid(fileStat.st_uid);
gid = getgrgid(fileStat.st_gid);
if(pwd != NULL && gid != NULL ){
printf("\t %s", pwd->pw_name);
printf("\t %s", gid->gr_name);
}
printf("\t %s\n", entity->d_name);
}
closedir(dir);
}
Solution
The entity->d_name
doesn't contain the full path of the file. All files you try to stat
will be relative to the current working directory, not the one you passed to opendir
. So some files will not exist and stat
will silently fail (since you don't check for that).
Two possible solutions:
- Change working directory to the one you use for the
opendir
call; Or - Append the directory and the
entity->d_name
(with path separator) and pass that appended name tostat
.
And of course, add error checking for all calls.
Answered By - Some programmer dude Answer Checked By - Mary Flores (WPSolving Volunteer)