Question

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

Was it helpful?

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);
}

OTHER TIPS

readdir is reading the directory, so when you say

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

you are actually asking to have the name of the first entry inside .. printed for you, not the name of the .. directory.

Depending on what you are trying to do, perhaps parsing the output of getcwd might be a better approach?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top