int os_dirent_ls(const char *dirname, struct os_dirent_node **headp) { struct dirent entry, *result; struct os_dirent_node *head, *node, *next; struct stat buf; DIR *dir; int ret; char *fname; int len; *headp = NULL; dir = opendir(dirname); if (!dir) return -1; /* Create a buffer for the maximum filename length */ len = sizeof(entry.d_name) + strlen(dirname) + 2; fname = malloc(len); if (!fname) { ret = -ENOMEM; goto done; } for (node = head = NULL;; node = next) { ret = readdir_r(dir, &entry, &result); if (ret || !result) break; next = malloc(sizeof(*node) + strlen(entry.d_name) + 1); if (!next) { os_dirent_free(head); ret = -ENOMEM; goto done; } strcpy(next->name, entry.d_name); switch (entry.d_type) { case DT_REG: next->type = OS_FILET_REG; break; case DT_DIR: next->type = OS_FILET_DIR; break; case DT_LNK: next->type = OS_FILET_LNK; break; } next->size = 0; snprintf(fname, len, "%s/%s", dirname, next->name); if (!stat(fname, &buf)) next->size = buf.st_size; if (node) node->next = next; if (!head) head = node; } *headp = head; done: closedir(dir); return ret; }
int sandbox_fs_ls(const char *dirname) { struct os_dirent_node *head, *node; int ret; ret = os_dirent_ls(dirname, &head); if (ret) goto out; for (node = head; node; node = node->next) { printf("%s %10lu %s\n", os_dirent_get_typename(node->type), node->size, node->name); } out: os_dirent_free(head); return ret; }
int os_dirent_ls(const char *dirname, struct os_dirent_node **headp) { struct dirent *entry; struct os_dirent_node *head, *node, *next; struct stat buf; DIR *dir; int ret; char *fname; char *old_fname; int len; int dirlen; *headp = NULL; dir = opendir(dirname); if (!dir) return -1; /* Create a buffer upfront, with typically sufficient size */ dirlen = strlen(dirname) + 2; len = dirlen + 256; fname = malloc(len); if (!fname) { ret = -ENOMEM; goto done; } for (node = head = NULL;; node = next) { errno = 0; entry = readdir(dir); if (!entry) { ret = errno; break; } next = malloc(sizeof(*node) + strlen(entry->d_name) + 1); if (!next) { os_dirent_free(head); ret = -ENOMEM; goto done; } if (dirlen + strlen(entry->d_name) > len) { len = dirlen + strlen(entry->d_name); old_fname = fname; fname = realloc(fname, len); if (!fname) { free(old_fname); free(next); os_dirent_free(head); ret = -ENOMEM; goto done; } } next->next = NULL; strcpy(next->name, entry->d_name); switch (entry->d_type) { case DT_REG: next->type = OS_FILET_REG; break; case DT_DIR: next->type = OS_FILET_DIR; break; case DT_LNK: next->type = OS_FILET_LNK; break; default: next->type = OS_FILET_UNKNOWN; } next->size = 0; snprintf(fname, len, "%s/%s", dirname, next->name); if (!stat(fname, &buf)) next->size = buf.st_size; if (node) node->next = next; else head = next; } *headp = head; done: closedir(dir); free(fname); return ret; }