diff options
author | Yorhel <git@yorhel.nl> | 2012-08-29 10:27:12 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2012-08-29 10:27:12 +0200 |
commit | c4616ff186495d1591430bc2dc1a911e1884e28a (patch) | |
tree | 39ab92674cbc528b07d77b07b231c0147c92f90b /src | |
parent | 7ccb98006a8da1fdaeab59efa3bc0520707d623f (diff) |
Added simple error checking & handling when exporting
Diffstat (limited to 'src')
-rw-r--r-- | src/dir.h | 5 | ||||
-rw-r--r-- | src/dir_export.c | 13 | ||||
-rw-r--r-- | src/dir_mem.c | 6 | ||||
-rw-r--r-- | src/dir_scan.c | 47 |
4 files changed, 51 insertions, 20 deletions
@@ -64,8 +64,11 @@ struct dir_output { * All other fields/flags should be initialzed to NULL or 0. * *item may be overwritten or freed in subsequent calls, so this function * should make a copy if necessary. + * + * The function should return non-zero on error, at which point errno is + * assumed to be set to something sensible. */ - void (*item)(struct dir *); + int (*item)(struct dir *); /* Finalizes the output to go to the next program state or exit ncdu. Called * after item(NULL) has been called for the root item or before any item() diff --git a/src/dir_export.c b/src/dir_export.c index a9d2751..3d32c1a 100644 --- a/src/dir_export.c +++ b/src/dir_export.c @@ -100,15 +100,19 @@ static void output_info(struct dir *d) { } -/* TODO: Error handling / reporting! */ -static void item(struct dir *item) { +/* Note on error handling: For convenience, we just keep writing to *stream + * without checking the return values of the functions. Only at the and of each + * item() call do we check for ferror(). This greatly simplifies the code, but + * assumes that calls to fwrite()/fput./etc don't do any weird stuff when + * called with a stream that's in an error state. */ +static int item(struct dir *item) { if(!item) { if(!--level) { /* closing of the root item */ fputs("]]", stream); - fclose(stream); + return fclose(stream); } else /* closing of a regular directory item */ fputs("]", stream); - return; + return ferror(stream); } dir_output.items++; @@ -123,6 +127,7 @@ static void item(struct dir *item) { fputc('[', stream); output_info(item); + return ferror(stream); } diff --git a/src/dir_mem.c b/src/dir_mem.c index ce67525..3001c01 100644 --- a/src/dir_mem.c +++ b/src/dir_mem.c @@ -128,13 +128,13 @@ static void item_add(struct dir *item) { } -static void item(struct dir *item) { +static int item(struct dir *item) { struct dir *t; /* Go back to parent dir */ if(!item) { curdir = curdir->parent; - return; + return 0; } item = item_copy(item); @@ -165,6 +165,8 @@ static void item(struct dir *item) { dir_output.size = root->size; dir_output.items = root->items; + + return 0; } diff --git a/src/dir_scan.c b/src/dir_scan.c index a0efcb3..ee9b41d 100644 --- a/src/dir_scan.c +++ b/src/dir_scan.c @@ -125,16 +125,20 @@ static int dir_scan_recurse(struct dir *d) { if(chdir(d->name)) { dir_setlasterr(dir_curpath); d->flags |= FF_ERR; - dir_output.item(d); - dir_output.item(NULL); + if(dir_output.item(d) || dir_output.item(NULL)) { + dir_seterr("Output error: %s", strerror(errno)); + return 1; + } return 0; } if((dir = dir_read(&fail)) == NULL) { dir_setlasterr(dir_curpath); d->flags |= FF_ERR; - dir_output.item(d); - dir_output.item(NULL); + if(dir_output.item(d) || dir_output.item(NULL)) { + dir_seterr("Output error: %s", strerror(errno)); + return 1; + } if(chdir("..")) { dir_seterr("Error going back to parent directory: %s", strerror(errno)); return 1; @@ -146,9 +150,15 @@ static int dir_scan_recurse(struct dir *d) { if(fail) d->flags |= FF_ERR; - dir_output.item(d); + if(dir_output.item(d)) { + dir_seterr("Output error: %s", strerror(errno)); + return 1; + } fail = dir_walk(dir); - dir_output.item(NULL); + if(dir_output.item(NULL)) { + dir_seterr("Output error: %s", strerror(errno)); + return 1; + } /* Not being able to chdir back is fatal */ if(!fail && chdir("..")) { @@ -190,10 +200,14 @@ static int dir_scan_item(struct dir *d) { if(d->flags & FF_DIR && !(d->flags & (FF_ERR|FF_EXL|FF_OTHFS))) fail = dir_scan_recurse(d); else if(d->flags & FF_DIR) { - dir_output.item(d); - dir_output.item(NULL); - } else - dir_output.item(d); + if(dir_output.item(d) || dir_output.item(NULL)) { + dir_seterr("Output error: %s", strerror(errno)); + fail = 1; + } + } else if(dir_output.item(d)) { + dir_seterr("Output error: %s", strerror(errno)); + fail = 1; + } return fail || input_handle(1); } @@ -260,9 +274,16 @@ int dir_scan_process() { d->flags |= FF_ERR; stat_to_dir(d, &fs); - dir_output.item(d); - fail = dir_walk(dir); - dir_output.item(NULL); + if(dir_output.item(d)) { + dir_seterr("Output error: %s", strerror(errno)); + fail = 1; + } + if(!fail) + fail = dir_walk(dir); + if(!fail && dir_output.item(NULL)) { + dir_seterr("Output error: %s", strerror(errno)); + fail = 1; + } } while(dir_fatalerr && !input_handle(0)) |