From 3ce7c9bd6b442bfbc19e21e071af5f4d81da6dbb Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 27 Feb 2018 13:38:23 -0500 Subject: [PATCH] src/apply-default-acl.c: update the CLI to match documented exit codes. --- src/apply-default-acl.c | 74 +++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/src/apply-default-acl.c b/src/apply-default-acl.c index 7a67052..ea3ef64 100644 --- a/src/apply-default-acl.c +++ b/src/apply-default-acl.c @@ -19,6 +19,9 @@ #include "libadacl.h" +/* We exit with EXIT_FAILURE for small errors, but we need something + * else for big ones. */ +#define EXIT_ERROR 2 #define NFTW_ERROR -1 @@ -93,12 +96,13 @@ int apply_default_acl_nftw(const char *target, int info, struct FTW *ftw) { - if (apply_default_acl_ex(target, sp, false)) { - return FTW_CONTINUE; - } - else { - return FTW_STOP; + if (apply_default_acl_ex(target, sp, false) == ACL_ERROR) { + /* I guess we do want to bail out for serious/unexpected errors? */ + return ACL_ERROR; } + + /* We don't want to kill the tree walk because we it a symlink. */ + return 0; } @@ -115,12 +119,13 @@ int apply_default_acl_nftw_x(const char *target, int info, struct FTW *ftw) { - if (apply_default_acl_ex(target, sp, true)) { - return FTW_CONTINUE; - } - else { - return FTW_STOP; + if (apply_default_acl_ex(target, sp, true) == ACL_ERROR) { + /* I guess we do want to bail out for serious/unexpected errors? */ + return ACL_ERROR; } + + /* We don't want to kill the tree walk because we it a symlink. */ + return 0; } @@ -132,8 +137,6 @@ int apply_default_acl_nftw_x(const char *target, * apply_default_acl() recursively on all of its children. Otherwise, * we just delegate to @c apply_default_acl(). * - * We ignore symlinks for consistency with chmod -r. - * * @param target * The root (path) of the recursive application. * @@ -141,17 +144,12 @@ int apply_default_acl_nftw_x(const char *target, * The value (either true or false) of the --no-exec-mask flag. * * @return - * If @c target is not a directory, we return the result of - * calling @c apply_default_acl() on @c target. Otherwise, we convert - * the return value of @c nftw(). If @c nftw() succeeds (returns 0), - * then we return @c true. Otherwise, we return @c false. - * \n\n - * If there is an error, it will be reported via @c perror, but - * we still return @c false. + * If @c nftw() fails with a serious error (returns NFTW_ERROR), + * then we return @c ACL_ERROR. Otherwise, we return @c ACL_SUCCESS. */ -bool apply_default_acl_recursive(const char *target, bool no_exec_mask) { +int apply_default_acl_recursive(const char *target, bool no_exec_mask) { int max_levels = 256; - int flags = FTW_PHYS; /* Don't follow links. */ + int flags = FTW_MOUNT | FTW_PHYS; /* There are two separate functions that could be passed to nftw(). One passes no_exec_mask = true to apply_default_acl(), @@ -163,20 +161,16 @@ bool apply_default_acl_recursive(const char *target, bool no_exec_mask) { int nftw_result = nftw(target, fn, max_levels, flags); - if (nftw_result == 0) { - /* Success */ - return true; - } - - /* nftw will return NFTW_ERROR on error, or if the supplied function - * (apply_default_acl_nftw) returns a non-zero result, nftw will - * return that. - */ + /* nftw will itself return NFTW_ERROR on errors like malloc failure, + and since the only non-success value that "fn" can return us + ACL_ERROR == NFTW_ERROR, this covers all error cases. */ if (nftw_result == NFTW_ERROR) { perror("apply_default_acl_recursive (nftw)"); + return ACL_ERROR; } - return false; + /* Beware: nftw indicates success with 0, but ACL_SUCCESS != 0. */ + return ACL_SUCCESS; } @@ -231,7 +225,6 @@ int main(int argc, char* argv[]) { int arg_index = 1; for (arg_index = optind; arg_index < argc; arg_index++) { const char* target = argv[arg_index]; - bool reapp_result = false; /* Make sure we can access the given path before we go out of our * way to please it. Doing this check outside of @@ -244,17 +237,18 @@ int main(int argc, char* argv[]) { continue; } - if (recursive) { - reapp_result = apply_default_acl_recursive(target, no_exec_mask); - } - else { - /* It's either a normal file, or we're not operating recursively. */ - reapp_result = apply_default_acl(target, no_exec_mask); - } + int (*f)(const char *, bool) = recursive ? apply_default_acl_recursive + : apply_default_acl; + int reapp_result = f(target, no_exec_mask); - if (!reapp_result) { + if (result == EXIT_SUCCESS && reapp_result == ACL_FAILURE) { + /* We don't want to turn an error into a (less-severe) failure. */ result = EXIT_FAILURE; } + if (reapp_result == ACL_ERROR) { + /* Turn both success and failure into an error, if we encounter one. */ + result = EXIT_ERROR; + } } return result; -- 2.44.2