From 25c49ccc1c0a6b0d2bacbf527072fc4c14926371 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 17 Dec 2005 06:55:54 +0000 Subject: (OPENAT_CWD_RESTORE__REQUIRE): Remove. (OPENAT_CWD_RESTORE__ALLOW_FAILURE): Likewise. (fd_to_subdirp): Remove openat_cwd_restore_allow_failure arg; its value is now signified by whether cwd_errno is null. (fd_to_subdirp, remove_dir, rm_1); Change cwd failure indicator from pointer-to-bool to pointer-to-errno-value. All callers changed. (rm_1): Don't bother setting a local cwd failure flag and then ORing it into the caller's. Just set the caller's. (rm): Use cwd failure errno value to print a slightly-better diagnostic. --- src/remove.c | 57 +++++++++++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 38 deletions(-) (limited to 'src/remove.c') diff --git a/src/remove.c b/src/remove.c index 5997467d7..f96ca840c 100644 --- a/src/remove.c +++ b/src/remove.c @@ -74,12 +74,6 @@ enum CONSECUTIVE_READDIR_UNLINK_THRESHOLD = 200 }; -enum - { - OPENAT_CWD_RESTORE__REQUIRE = false, - OPENAT_CWD_RESTORE__ALLOW_FAILURE = true - }; - enum Ternary { T_UNKNOWN = 2, @@ -991,30 +985,25 @@ remove_entry (int fd_cwd, Dirstack_state const *ds, char const *filename, unlink- or rmdir-like system call -- use that value instead of ENOTDIR if an opened file turns out not to be a directory. This is important when the preceding non-dir-unlink failed due to e.g., EPERM or EACCES. - The caller must set OPENAT_CWD_RESTORE_ALLOW_FAILURE to true the first + The caller must use a nonnnull CWD_ERRNO the first time this function is called for each command-line-specified directory. - Set *CWD_RESTORE_FAILED if OPENAT_CWD_RESTORE_ALLOW_FAILURE is true - and openat_ro fails to restore the initial working directory. - CWD_RESTORE_FAILED may be NULL. */ + If CWD_ERRNO is not null, set *CWD_ERRNO to the appropriate error number + if this function fails to restore the initial working directory. + If it is null, report an error and exit if the working directory + isn't restored. */ static DIR * fd_to_subdirp (int fd_cwd, char const *f, struct rm_options const *x, int prev_errno, struct stat *subdir_sb, Dirstack_state *ds, - bool openat_cwd_restore_allow_failure, - bool *cwd_restore_failed) + int *cwd_errno ATTRIBUTE_UNUSED) { - int fd_sub; - bool dummy; + int fd_sub = openat_permissive (fd_cwd, f, O_RDONLY | OPEN_NO_FOLLOW_SYMLINK, + 0, cwd_errno); /* Record dev/ino of F. We may compare them against saved values to thwart any attempt to subvert the traversal. They are also used to detect directory cycles. */ - if ((fd_sub = (openat_cwd_restore_allow_failure - ? openat_ro (fd_cwd, f, O_RDONLY | OPEN_NO_FOLLOW_SYMLINK, - (cwd_restore_failed - ? cwd_restore_failed : &dummy)) - : openat (fd_cwd, f, O_RDONLY | OPEN_NO_FOLLOW_SYMLINK))) < 0 - || fstat (fd_sub, subdir_sb) != 0) + if (fd_sub < 0 || fstat (fd_sub, subdir_sb) != 0) { if (errno != ENOENT || !x->ignore_missing_files) error (0, errno, @@ -1126,9 +1115,7 @@ remove_cwd_entries (DIR **dirp, case RM_NONEMPTY_DIR: { DIR *subdir_dirp = fd_to_subdirp (dirfd (*dirp), f, - x, errno, subdir_sb, ds, - OPENAT_CWD_RESTORE__REQUIRE, - NULL); + x, errno, subdir_sb, ds, NULL); if (subdir_dirp == NULL) { AD_mark_as_unremovable (ds, f); @@ -1193,7 +1180,7 @@ The following directory is part of the cycle:\n %s\n"), static enum RM_status remove_dir (int fd_cwd, Dirstack_state *ds, char const *dir, - struct rm_options const *x, bool *cwd_restore_failed) + struct rm_options const *x, int *cwd_errno) { enum RM_status status; struct stat dir_sb; @@ -1206,9 +1193,7 @@ remove_dir (int fd_cwd, Dirstack_state *ds, char const *dir, fd_to_subdirp's fstat, along with the `fstat' and the dev/ino comparison in AD_push ensure that we detect it and fail. */ - DIR *dirp = fd_to_subdirp (fd_cwd, dir, x, 0, &dir_sb, ds, - OPENAT_CWD_RESTORE__ALLOW_FAILURE, - cwd_restore_failed); + DIR *dirp = fd_to_subdirp (fd_cwd, dir, x, 0, &dir_sb, ds, cwd_errno); if (dirp == NULL) return RM_ERROR; @@ -1320,7 +1305,7 @@ remove_dir (int fd_cwd, Dirstack_state *ds, char const *dir, static enum RM_status rm_1 (Dirstack_state *ds, char const *filename, - struct rm_options const *x, bool *cwd_restore_failed) + struct rm_options const *x, int *cwd_errno) { char const *base = base_name (filename); if (DOT_OR_DOTDOT (base)) @@ -1345,11 +1330,7 @@ rm_1 (Dirstack_state *ds, char const *filename, if (setjmp (ds->current_arg_jumpbuf)) status = RM_ERROR; else - { - bool t_cwd_restore_failed = false; - status = remove_dir (fd_cwd, ds, filename, x, &t_cwd_restore_failed); - *cwd_restore_failed |= t_cwd_restore_failed; - } + status = remove_dir (fd_cwd, ds, filename, x, cwd_errno); } ds_clear (ds); @@ -1364,12 +1345,12 @@ rm (size_t n_files, char const *const *file, struct rm_options const *x) { enum RM_status status = RM_OK; Dirstack_state *ds = ds_init (); - bool cwd_restore_failed = false; + int cwd_errno = 0; size_t i; for (i = 0; i < n_files; i++) { - if (cwd_restore_failed && IS_RELATIVE_FILE_NAME (file[i])) + if (cwd_errno && IS_RELATIVE_FILE_NAME (file[i])) { error (0, 0, _("cannot remove relative-named %s"), quote (file[i])); status = RM_ERROR; @@ -1377,14 +1358,14 @@ rm (size_t n_files, char const *const *file, struct rm_options const *x) } cycle_check_init (&ds->cycle_check_state); - enum RM_status s = rm_1 (ds, file[i], x, &cwd_restore_failed); + enum RM_status s = rm_1 (ds, file[i], x, &cwd_errno); assert (VALID_STATUS (s)); UPDATE_STATUS (status, s); } - if (x->require_restore_cwd && cwd_restore_failed) + if (x->require_restore_cwd && cwd_errno) { - error (0, 0, + error (0, cwd_errno, _("cannot restore current working directory")); status = RM_ERROR; } -- cgit v1.2.3-54-g00ecf