/* * Rewritten from example here: * https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopendir.html * * A simple 'du' (Disk Usage) clone. */ #include #include #include #include #include #include #include #include uint64_t walk_tmp_dir (const char *dir) { struct stat st; struct dirent *dp; char full_name [1000]; char dir_name [1000], *p; int dfd; DIR *d; uint64_t sum = 0; strncpy (dir_name, dir, sizeof(dir_name)-1); for (p = dir_name; *p; p++) if (*p == '\\') *p = '/'; dfd = open (dir_name, O_RDONLY); d = fdopendir (dfd); if (!d) { fprintf (stderr, "Cannot open '%s' directory\n", dir_name); exit (1); } while ((dp = readdir(d)) != NULL) { int ffd; if (dp->d_name[0] == '.') continue; snprintf (full_name, sizeof(full_name), "%s/%s", dir_name, dp->d_name); #if 0 ffd = openat (dfd, dp->d_name, O_RDONLY); // does not work #else ffd = openat (dfd, full_name, O_RDONLY); // does work #endif if (ffd < 0) { printf (" %s: %s\n", full_name, strerror(errno)); continue; } if (fstat(ffd, &st) == 0) { if (S_ISDIR(st.st_mode)) { sum += walk_tmp_dir (full_name); } else { sum += st.st_size; printf ("%5jdK: %s\n", st.st_size/1024, full_name); } } close (ffd); } closedir (d); return (sum); } int main (int argc, char **argv) { uint64_t sum = walk_tmp_dir (argc > 1 ? argv[1] : "c:/temp"); printf ("total size: %llu kB\n", sum/1024); return (0); }