Search code examples
cdirectoryparentstat

stat() doesn't work on parent directory


I'm trying to code the ls command in C, but stat() refuse to open any other directory.

 ~/Desktop/ls$ cat bug.c 
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <unistd.h>

int     main(int ac, char **av)
{
  DIR       *d;
  struct dirent *dir;
  struct stat   file;

  d = opendir(av[1]);
  if (d)
    {
      while ((dir = readdir(d)) != NULL)
        {
          printf("%s ->", dir->d_name);
          if (lstat(dir->d_name, &file) < 0)
          printf(" can't read file %s!", dir->d_name);
          printf("\n");
        }
    }
  closedir(d);
  return (0);
}

When running ./a.out . or any subfolder, it works correctly. But if I write ./a.out .. , it fails to open files...

~/Desktop/ls$ ./a.out ..
.. ->
fkdkfdjkfdkfjdfkdfjkdfjkdjkfdkjf -> can't read file fkdkfdjkfdkfjdfkdfjkdfjkdjkfdkjf!
ss -> can't read file ss!
ls -> can't read file ls!
. ->
tg -> can't read file tg!

./a.out /home/login/Desktop doesn't work either, but ./a.out /home/login/Desktop/ls/ display correctly the content of the current folder.

It looks like a.out can't open parents dir, but ls -l gives :

-rwxrwxr-x 1 hellomynameis hellomynameis 13360 nov.  25 09:56 a.out

Am I doing it the wrong way ?

Thanks !


Solution

  • Your lstat call is wrong. When you get a name from the opened directory, it is a relative name, so you need to convert it to a correct path to let lstat locate the file:

    char path[...];
    sprintf(path,"%s/%s",av[1],dir->d_name);
    lstat(path,...);