Skip to content
Snippets Groups Projects
Commit c4616ff1 authored by Yorhel's avatar Yorhel
Browse files

Added simple error checking & handling when exporting

parent 7ccb9800
No related branches found
No related tags found
No related merge requests found
...@@ -64,8 +64,11 @@ struct dir_output { ...@@ -64,8 +64,11 @@ struct dir_output {
* All other fields/flags should be initialzed to NULL or 0. * All other fields/flags should be initialzed to NULL or 0.
* *item may be overwritten or freed in subsequent calls, so this function * *item may be overwritten or freed in subsequent calls, so this function
* should make a copy if necessary. * 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 /* 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() * after item(NULL) has been called for the root item or before any item()
......
...@@ -100,15 +100,19 @@ static void output_info(struct dir *d) { ...@@ -100,15 +100,19 @@ static void output_info(struct dir *d) {
} }
/* TODO: Error handling / reporting! */ /* Note on error handling: For convenience, we just keep writing to *stream
static void item(struct dir *item) { * 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(!item) {
if(!--level) { /* closing of the root item */ if(!--level) { /* closing of the root item */
fputs("]]", stream); fputs("]]", stream);
fclose(stream); return fclose(stream);
} else /* closing of a regular directory item */ } else /* closing of a regular directory item */
fputs("]", stream); fputs("]", stream);
return; return ferror(stream);
} }
dir_output.items++; dir_output.items++;
...@@ -123,6 +127,7 @@ static void item(struct dir *item) { ...@@ -123,6 +127,7 @@ static void item(struct dir *item) {
fputc('[', stream); fputc('[', stream);
output_info(item); output_info(item);
return ferror(stream);
} }
......
...@@ -128,13 +128,13 @@ static void item_add(struct dir *item) { ...@@ -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; struct dir *t;
/* Go back to parent dir */ /* Go back to parent dir */
if(!item) { if(!item) {
curdir = curdir->parent; curdir = curdir->parent;
return; return 0;
} }
item = item_copy(item); item = item_copy(item);
...@@ -165,6 +165,8 @@ static void item(struct dir *item) { ...@@ -165,6 +165,8 @@ static void item(struct dir *item) {
dir_output.size = root->size; dir_output.size = root->size;
dir_output.items = root->items; dir_output.items = root->items;
return 0;
} }
......
...@@ -125,16 +125,20 @@ static int dir_scan_recurse(struct dir *d) { ...@@ -125,16 +125,20 @@ static int dir_scan_recurse(struct dir *d) {
if(chdir(d->name)) { if(chdir(d->name)) {
dir_setlasterr(dir_curpath); dir_setlasterr(dir_curpath);
d->flags |= FF_ERR; d->flags |= FF_ERR;
dir_output.item(d); if(dir_output.item(d) || dir_output.item(NULL)) {
dir_output.item(NULL); dir_seterr("Output error: %s", strerror(errno));
return 1;
}
return 0; return 0;
} }
if((dir = dir_read(&fail)) == NULL) { if((dir = dir_read(&fail)) == NULL) {
dir_setlasterr(dir_curpath); dir_setlasterr(dir_curpath);
d->flags |= FF_ERR; d->flags |= FF_ERR;
dir_output.item(d); if(dir_output.item(d) || dir_output.item(NULL)) {
dir_output.item(NULL); dir_seterr("Output error: %s", strerror(errno));
return 1;
}
if(chdir("..")) { if(chdir("..")) {
dir_seterr("Error going back to parent directory: %s", strerror(errno)); dir_seterr("Error going back to parent directory: %s", strerror(errno));
return 1; return 1;
...@@ -146,9 +150,15 @@ static int dir_scan_recurse(struct dir *d) { ...@@ -146,9 +150,15 @@ static int dir_scan_recurse(struct dir *d) {
if(fail) if(fail)
d->flags |= FF_ERR; 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); 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 */ /* Not being able to chdir back is fatal */
if(!fail && chdir("..")) { if(!fail && chdir("..")) {
...@@ -190,10 +200,14 @@ static int dir_scan_item(struct dir *d) { ...@@ -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))) if(d->flags & FF_DIR && !(d->flags & (FF_ERR|FF_EXL|FF_OTHFS)))
fail = dir_scan_recurse(d); fail = dir_scan_recurse(d);
else if(d->flags & FF_DIR) { else if(d->flags & FF_DIR) {
dir_output.item(d); if(dir_output.item(d) || dir_output.item(NULL)) {
dir_output.item(NULL); dir_seterr("Output error: %s", strerror(errno));
} else fail = 1;
dir_output.item(d); }
} else if(dir_output.item(d)) {
dir_seterr("Output error: %s", strerror(errno));
fail = 1;
}
return fail || input_handle(1); return fail || input_handle(1);
} }
...@@ -260,9 +274,16 @@ int dir_scan_process() { ...@@ -260,9 +274,16 @@ int dir_scan_process() {
d->flags |= FF_ERR; d->flags |= FF_ERR;
stat_to_dir(d, &fs); stat_to_dir(d, &fs);
dir_output.item(d); if(dir_output.item(d)) {
dir_seterr("Output error: %s", strerror(errno));
fail = 1;
}
if(!fail)
fail = dir_walk(dir); fail = dir_walk(dir);
dir_output.item(NULL); if(!fail && dir_output.item(NULL)) {
dir_seterr("Output error: %s", strerror(errno));
fail = 1;
}
} }
while(dir_fatalerr && !input_handle(0)) while(dir_fatalerr && !input_handle(0))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment