Question

The function below basically emulates mkdir -p, recursively creating directories for a given path. With Linux I have no issues, however running under OSX it always segfaults with the error pointer being freed was not allocated during the call to free(dir). Can anyone spot an error? When I step through execution in gdb I don't see any obvious problems, dir is populated and the directory structure is created without error.

static int
mkpath(const char *path)
{
  int result = 0;
  struct stat st;
  char *p = NULL, *dir = strdup(path);
  char *tmp = g_malloc0(sizeof(char) * strlen(cache.path) + strlen(dir) + 1);

  dir = dirname(dir);
  tmp = strcpy(tmp, cache.path);
  p = strtok(dir, "/");
  while(p != NULL) {
    tmp = strncat(tmp, "/", 1);
    tmp = strncat(tmp, p, strlen(p));

    if(stat(tmp, &st) == 0) {
      if(S_ISDIR(st.st_mode)) {
        p = strtok(NULL, "/");
        continue;
      }

      result = -ENOTDIR;
      break;
    }

    if(mkdir(tmp, S_IRWXU) == -1) {
      result = -errno;
      break;
    }

    p = strtok(NULL, "/");
  }

  free(tmp);
  free(dir);

  return result;
}
Was it helpful?

Solution

Take a look at the man page for dirname: http://linux.die.net/man/3/dirname. "Both dirname() and basename() return pointers to null-terminated strings. (Do not pass these pointers to free(3).)" Also, you should probably not being doing dir = dirname(dir) as you've then lost the pointer to the memory allocated by strdup (strdup allocated memory should be passed to free).

OTHER TIPS

The man page for dirname says that you should not pass the return value to free(). Yet that is exactly what you are doing.

according to the man page:

WARNINGS The dirname() function returns a pointer to internal static storage space that will be overwritten by subsequent calls (each function has its own separate storage).

so you probably don't want to be freeing it. i'm guessing that's different on linux?

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