X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/agedu/blobdiff_plain/dcf1fcc0405ed9d74f73a2cde910aa0ce95bd777..652a371240a0b12ca1eb8c81cee5648e86320e63:/du.c diff --git a/du.c b/du.c index 1a375bf..6d26c34 100644 --- a/du.c +++ b/du.c @@ -2,26 +2,24 @@ * du.c: implementation of du.h. */ -#include "agedu.h" /* for config.h */ - -#ifdef HAVE_FEATURES_H -#define _GNU_SOURCE -#include -#endif - -#include -#include -#include -#include - -#include -#include -#include - +#include "agedu.h" #include "du.h" #include "alloc.h" -#if !defined __linux__ || defined HAVE_FDOPENDIR +#if !defined __linux__ || !defined O_NOATIME || defined HAVE_FDOPENDIR + +#ifdef HAVE_DIRENT_H +# include +#endif +#ifdef HAVE_NDIR_H +# include +#endif +#ifdef HAVE_SYS_DIR_H +# include +#endif +#ifdef HAVE_SYS_NDIR_H +# include +#endif /* * Wrappers around POSIX opendir, readdir and closedir, which @@ -29,7 +27,6 @@ * circumstances. */ -#include typedef DIR *dirhandle; int open_dir(const char *path, dirhandle *dh) @@ -106,8 +103,6 @@ void close_dir(dirhandle *dh) */ #define __KERNEL__ -#include -#include #include #include #include @@ -175,16 +170,26 @@ static int str_cmp(const void *av, const void *bv) } static void du_recurse(char **path, size_t pathlen, size_t *pathsize, - gotdata_fn_t gotdata, void *gotdata_ctx) + gotdata_fn_t gotdata, err_fn_t err, void *gotdata_ctx, + int toplevel) { const char *name; dirhandle d; STRUCT_STAT st; char **names; size_t i, nnames, namesize; + int statret; - if (LSTAT(*path, &st) < 0) { - fprintf(stderr, "%s: lstat: %s\n", *path, strerror(errno)); + /* + * Special case: at the very top of the scan, we follow a + * symlink. + */ + if (toplevel) + statret = STAT(*path, &st); + else + statret = LSTAT(*path, &st); + if (statret < 0) { + err(gotdata_ctx, "%s: lstat: %s\n", *path, strerror(errno)); return; } @@ -198,7 +203,7 @@ static void du_recurse(char **path, size_t pathlen, size_t *pathsize, nnames = namesize = 0; if (open_dir(*path, &d) < 0) { - fprintf(stderr, "%s: opendir: %s\n", *path, strerror(errno)); + err(gotdata_ctx, "%s: opendir: %s\n", *path, strerror(errno)); return; } while ((name = read_dir(&d)) != NULL) { @@ -236,14 +241,15 @@ static void du_recurse(char **path, size_t pathlen, size_t *pathsize, sprintf(*path + pathlen, "/%s", names[i]); } - du_recurse(path, newpathlen, pathsize, gotdata, gotdata_ctx); + du_recurse(path, newpathlen, pathsize, gotdata, err, gotdata_ctx, 0); sfree(names[i]); } sfree(names); } -void du(const char *inpath, gotdata_fn_t gotdata, void *gotdata_ctx) +void du(const char *inpath, gotdata_fn_t gotdata, err_fn_t err, + void *gotdata_ctx) { char *path; size_t pathlen, pathsize; @@ -253,5 +259,5 @@ void du(const char *inpath, gotdata_fn_t gotdata, void *gotdata_ctx) path = snewn(pathsize, char); strcpy(path, inpath); - du_recurse(&path, pathlen, &pathsize, gotdata, gotdata_ctx); + du_recurse(&path, pathlen, &pathsize, gotdata, err, gotdata_ctx, 1); }