Если у вас есть запись в каталоге для рекурсии, вы должны создать путь путем объединения каталога и имени записи с разделителем /
и рекурсивным вызовом do_ls
.
Чтобы вычислить размеры файлов, вы можете использовать системный вызов stat
, но вам также понадобится и путь, поэтому конструкция перед проверкой на тип записи (используйте malloc
, чтобы выделить место для объединенной строки) и не забудьте освободить его после использования.
Также игнорируйте записи .
и ..
и выведите closedir()
из цикла while
.
Вот улучшенная версия, которая не использует глобальную переменную для
total
size, но вместо этого возвращает совокупный размер вызывающей стороне:
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
long long do_ls(const char *name) {
DIR *dir_ptr;
struct dirent *direntp;
struct stat info;
long long total = 0;
int output = 1;
if (stat(name, &info)) {
fprintf(stderr, "ls01: cannot stat %s\n", name);
return 0;
}
if (S_ISDIR(info.st_mode)) {
if ((dir_ptr = opendir(name)) == NULL) {
fprintf(stderr, "ls01: cannot open directory %s\n", name);
} else {
while ((direntp = readdir(dir_ptr)) != NULL) {
char *pathname;
/* ignore current and parent directories */
if (!strcmp(direntp->d_name, ".") || !strcmp(direntp->d_name, ".."))
continue;
pathname = malloc(strlen(name) + 1 + strlen(direntp->d_name) + 1);
if (pathname == NULL) {
fprintf(stderr, "ls01: cannot allocated memory\n");
exit(1);
}
sprintf(pathname, "%s/%s", name, direntp->d_name);
total += do_ls(pathname);
free(pathname);
}
closedir(dir_ptr);
}
} else {
total = info.st_size;
}
printf("%10lld %s\n", total, name);
return total;
}
int main(int ac, char *av[]) {
int i = 1;
if (i >= ac) {
do_ls(".");
} else {
long long total = 0;
while (i < ac) {
total += do_ls(av[i++]);
}
printf("total is: %lld\n", total);
}
return 0;
}