Search code examples
creaddir

readdir()->d_name giving weird values


I am trying to get the name of the parent directory by using this code:

dirp=opendir(cur_spot);
printf("parent name: %s\n", readdir(dirp)->d_name);
closedir(dirp);

cur_spot holds '..'.

i do this in a loop and it keeps climbing up the directories to the root, the sequence of my output it:

.
.bash_logout
.
.
srv

I know that it is traversing correctly because i am checking the inodes along the way.

Do i need to use something different than d_name?

Thanks


Solution

  • I came up with this based on the ideas in the comments under sjs' answer:

    #include <dirent.h>
    #include <stdio.h>
    #include <assert.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <limits.h>
    #include <errno.h>
    
    int LookupName(const char* parent, ino_t ino, char *name, size_t size)
    {
      DIR *dp = opendir(parent);
      if (!dp) return -1;
    
      int ret = -1;
      struct dirent *de;
      while (de = readdir(dp))
      {
        if (de->d_ino == ino)
        {
          strncpy(name, de->d_name, size);
          ret = 0;
          break;
        }
      }
    
      closedir(dp);
      if (ret == -1) errno = ENOENT;
      return ret;
    }
    
    int GetWorkdir(char *workdir, size_t size)
    {
      struct stat st;
      if (stat(".", &st)) return -1;
    
      char path[PATH_MAX];
      strncpy(path, "..", sizeof(path));
    
      memset(workdir, '\0', sizeof(workdir));
    
      char name[PATH_MAX];
      while (1)
      {
        if (LookupName(path, st.st_ino, name, sizeof(name))) return -1;
        if (!strcmp(name, "..") || !strcmp(name, "."))
        {
          strncpy(name, "/", sizeof(name));
          strncat(name, workdir, sizeof(name));
          strncpy(workdir, name, size);
          break;
        }
    
        if (workdir[0] != '\0')
        {
          strncat(name, "/", sizeof(name));
        }
    
        strncat(name, workdir, sizeof(name));
        strncpy(workdir, name, size);
    
        if (stat(path, &st)) return -1;
    
        strncat(path, "/..", sizeof(path));
      }
    
      return 0;
    }
    
    int main(int argc, char **argv)
    {
      char workDir[PATH_MAX];
    
      assert(!GetWorkdir(workDir, sizeof(workDir)));
      printf("%s\n", workDir);
    }