summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmdline.h4
-rw-r--r--color.c2
-rw-r--r--expr.h4
-rw-r--r--main.c4
-rw-r--r--parse.c37
-rwxr-xr-xtests.sh20
6 files changed, 60 insertions, 11 deletions
diff --git a/cmdline.h b/cmdline.h
index a1dadc3..9a46f7f 100644
--- a/cmdline.h
+++ b/cmdline.h
@@ -117,7 +117,9 @@ int eval_cmdline(const struct cmdline *cmdline);
/**
* Free the parsed command line.
+ *
+ * @return 0 if successful, -1 on error.
*/
-void free_cmdline(struct cmdline *cmdline);
+int free_cmdline(struct cmdline *cmdline);
#endif // CMDLINE_H
diff --git a/color.c b/color.c
index 8df6a1f..1025c9e 100644
--- a/color.c
+++ b/color.c
@@ -288,6 +288,8 @@ int cfclose(CFILE *cfile) {
if (cfile) {
if (cfile->close) {
ret = fclose(cfile->file);
+ } else if (cfile->file) {
+ ret = fflush(cfile->file);
}
free(cfile);
}
diff --git a/expr.h b/expr.h
index 0eba0da..c0e2b92 100644
--- a/expr.h
+++ b/expr.h
@@ -219,7 +219,9 @@ void dump_expr(CFILE *cfile, const struct expr *expr, bool verbose);
/**
* Free an expression tree.
+ *
+ * @return 0 if successful, -1 on error.
*/
-void free_expr(struct expr *expr);
+int free_expr(struct expr *expr);
#endif // EXPR_H
diff --git a/main.c b/main.c
index 9e8fdbf..2734aaf 100644
--- a/main.c
+++ b/main.c
@@ -60,7 +60,9 @@ int main(int argc, char *argv[]) {
ret = eval_cmdline(cmdline);
}
- free_cmdline(cmdline);
+ if (free_cmdline(cmdline) != 0 && ret == EXIT_SUCCESS) {
+ ret = EXIT_FAILURE;
+ }
done:
return ret;
diff --git a/parse.c b/parse.c
index 46c860c..b4b7ddc 100644
--- a/parse.c
+++ b/parse.c
@@ -80,11 +80,14 @@ struct expr expr_false = {
/**
* Free an expression.
*/
-void free_expr(struct expr *expr) {
+int free_expr(struct expr *expr) {
+ int ret = 0;
+
if (expr && expr != &expr_true && expr != &expr_false) {
if (expr->cfile && expr->cfile->close) {
if (cfclose(expr->cfile) != 0) {
perror("cfclose()");
+ ret = -1;
}
}
@@ -96,10 +99,17 @@ void free_expr(struct expr *expr) {
free_bfs_printf(expr->printf);
free_bfs_exec(expr->execbuf);
- free_expr(expr->lhs);
- free_expr(expr->rhs);
+ if (free_expr(expr->lhs) != 0) {
+ ret = -1;
+ }
+ if (free_expr(expr->rhs) != 0) {
+ ret = -1;
+ }
+
free(expr);
}
+
+ return ret;
}
struct expr *new_expr(eval_fn *eval, size_t argc, char **argv) {
@@ -224,14 +234,25 @@ void dump_expr(CFILE *cfile, const struct expr *expr, bool verbose) {
/**
* Free the parsed command line.
*/
-void free_cmdline(struct cmdline *cmdline) {
+int free_cmdline(struct cmdline *cmdline) {
+ int ret = 0;
+
if (cmdline) {
- free_expr(cmdline->expr);
+ if (free_expr(cmdline->expr) != 0) {
+ ret = -1;
+ }
free_bfs_mtab(cmdline->mtab);
- cfclose(cmdline->cerr);
- cfclose(cmdline->cout);
+ if (cfclose(cmdline->cerr) != 0) {
+ perror("cfclose()");
+ ret = -1;
+ }
+ if (cfclose(cmdline->cout) != 0) {
+ perror("cfclose()");
+ ret = -1;
+ }
+
free_colors(cmdline->colors);
struct root *root = cmdline->roots;
@@ -244,6 +265,8 @@ void free_cmdline(struct cmdline *cmdline) {
free(cmdline->argv);
free(cmdline);
}
+
+ return ret;
}
/**
diff --git a/tests.sh b/tests.sh
index 57aa47b..0f52581 100755
--- a/tests.sh
+++ b/tests.sh
@@ -376,6 +376,8 @@ gnu_tests=(
test_or_purity
test_not_reachability
test_comma_reachability
+ test_print_error
+ test_fprint_error
)
bfs_tests=(
@@ -1410,6 +1412,18 @@ function test_data_flow_type() {
bfs_diff basic \! \( -type f -o \! -type f \)
}
+function test_print_error() {
+ if [ -e /dev/full ]; then
+ ! invoke_bfs basic -maxdepth 0 >/dev/full 2>/dev/null
+ fi
+}
+
+function test_fprint_error() {
+ if [ -e /dev/full ]; then
+ ! invoke_bfs basic -maxdepth 0 -fprint /dev/full 2>/dev/null
+ fi
+}
+
if [ -t 1 -a ! "$VERBOSE" ]; then
in_place=yes
fi
@@ -1433,7 +1447,11 @@ for test in ${!run_*}; do
((++passed))
else
((++failed))
- echo "$test failed!"
+ if [ "$in_place" ]; then
+ printf '\r\033[J%s\n' "$test failed!"
+ else
+ echo "$test failed!"
+ fi
fi
done