11 #include <stdatomic.h>
14 struct subdir *parent;
17 int rv, subjobs, summary;
20 static int summary = 0;
21 static int retval = 0;
23 static char *sprintf2(char *fmt, ...)
30 fp = open_memstream(&ret, &sz);
32 vfprintf(fp, fmt, args);
38 static void printres(struct subdir *job)
40 printf("%ji\t%s\n", (intmax_t)(job->sum / 1024), job->path);
43 static void finish(struct subdir *job)
45 if(atomic_fetch_sub(&job->subjobs, 1) == 1) {
49 atomic_fetch_add(&job->parent->sum, job->sum);
57 static void dodir(void *jobp)
59 struct subdir *job = jobp;
61 struct dirent *dent, dbuf;
66 if((dp = opendir(job->path)) == NULL) {
67 fprintf(stderr, "pdu: %s: %s\n", job->path, strerror(errno));
73 if(readdir_r(dp, &dbuf, &dent)) {
74 fprintf(stderr, "pdu: reading %s: %s\n", job->path, strerror(errno));
80 if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
82 ep = sprintf2("%s/%s", job->path, dent->d_name);
84 fprintf(stderr, "pdu: stat %s: %s\n", ep, strerror(errno));
86 if(S_ISDIR(sb.st_mode)) {
87 *(nj = malloc(sizeof(*nj))) = (struct subdir) {
92 atomic_fetch_add(&job->subjobs, 1);
93 atomic_fetch_add(&job->sum, (off_t)sb.st_blocks * 512);
94 submitiowork(dodir, nj);
95 } else if(S_ISREG(sb.st_mode)) {
96 atomic_fetch_add(&job->sum, (off_t)sb.st_blocks * 512);
105 static void dodu(char *path)
109 *(job = malloc(sizeof(*job))) = (struct subdir) {
110 .path = strdup(path),
113 submitiowork(dodir, job);
116 static void usage(FILE *out)
118 fprintf(out, "usage: pdu [-sh] [DIRECTORY...]\n");
121 int main(int argc, char **argv)
125 while((c = getopt(argc, argv, "hs")) != -1) {
139 for(i = optind; i < argc; i++)
150 * compile-command: "gcc -Wall -g -o pdu pdu.c -ldpar"