1 /* remove.c -- core functions for removing files and directories
2 Copyright (C) 88, 90, 91, 1994-2003 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Extracted from rm.c and librarified, then rewritten by Jim Meyering. */
26 #include <sys/types.h>
32 #include "cycle-check.h"
35 #include "euidaccess.h"
36 #include "file-type.h"
43 /* Avoid shadowing warnings because these are functions declared
44 in dirname.h as well as locals used below. */
45 #define dir_name rm_dir_name
46 #define dir_len rm_dir_len
48 #define obstack_chunk_alloc malloc
49 #define obstack_chunk_free free
51 /* FIXME: if possible, use autoconf... */
53 # define ROOT_CAN_UNLINK_DIRS 0
55 # define ROOT_CAN_UNLINK_DIRS 1
64 typedef enum Ternary Ternary
;
66 /* The prompt function may be called twice a given directory.
67 The first time, we ask whether to descend into it, and the
68 second time, we ask whether to remove it. */
71 PA_DESCEND_INTO_DIR
= 2,
75 /* On systems with an lstat function that accepts the empty string,
76 arrange to make lstat calls go through the wrapper function. */
77 #if HAVE_LSTAT_EMPTY_STRING_BUG
78 int rpl_lstat (const char *, struct stat
*);
79 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
82 #ifdef D_INO_IN_DIRENT
83 # define D_INO(dp) ((dp)->d_ino)
84 # define ENABLE_CYCLE_CHECK
86 /* Some systems don't have inodes, so fake them to avoid lots of ifdefs. */
90 /* Initial capacity of per-directory hash table of entries that have
91 been processed but not been deleted. */
92 #define HT_UNREMOVABLE_INITIAL_CAPACITY 13
94 /* An entry in the active directory stack.
95 Each entry corresponds to an `active' directory. */
98 /* For a given active directory, this is the set of names of
99 entries in that directory that could/should not be removed.
100 For example, `.' and `..', as well as files/dirs for which
101 unlink/rmdir failed e.g., due to access restrictions. */
102 Hash_table
*unremovable
;
104 /* Record the status for a given active directory; we need to know
105 whether an entry was not removed, either because of an error or
106 because the user declined. */
107 enum RM_status status
;
111 /* The directory's dev/ino. Used to ensure that `chdir some-subdir', then
112 `chdir ..' takes us back to the same directory from which we started).
113 (valid for all but the bottommost entry on the stack. */
116 /* Enough information to restore the initial working directory.
117 (valid only for the bottommost entry on the stack) */
118 struct saved_cwd saved_cwd
;
124 extern char *program_name
;
126 struct dirstack_state
128 /* The name of the directory (starting with and relative to a command
129 line argument) being processed. When a subdirectory is entered, a new
130 component is appended (pushed). Remove (pop) the top component
131 upon chdir'ing out of a directory. This is used to form the full
132 name of the current directory or a file therein, when necessary. */
133 struct obstack dir_stack
;
135 /* Stack of lengths of directory names (including trailing slash)
136 appended to dir_stack. We have to have a separate stack of lengths
137 (rather than just popping back to previous slash) because the first
138 element pushed onto the dir stack may contain slashes. */
139 struct obstack len_stack
;
141 /* Stack of active directory entries.
142 The first `active' directory is the initial working directory.
143 Additional active dirs are pushed onto the stack as we `chdir'
144 into each directory to be processed. When finished with the
145 hierarchy under a directory, pop the active dir stack. */
146 struct obstack Active_dir
;
148 /* Used to detect cycles. */
149 struct cycle_check_state cycle_check_state
;
151 /* Target of a longjmp in case rm detects a directory cycle. */
152 jmp_buf current_arg_jumpbuf
;
154 typedef struct dirstack_state Dirstack_state
;
159 Dirstack_state
*ds
= XMALLOC (struct dirstack_state
, 1);
160 obstack_init (&ds
->dir_stack
);
161 obstack_init (&ds
->len_stack
);
162 obstack_init (&ds
->Active_dir
);
167 ds_free (Dirstack_state
*ds
)
169 obstack_free (&ds
->dir_stack
, NULL
);
170 obstack_free (&ds
->len_stack
, NULL
);
171 obstack_free (&ds
->Active_dir
, NULL
);
181 hash_compare_strings (void const *x
, void const *y
)
183 return STREQ (x
, y
) ? true : false;
187 push_dir (Dirstack_state
*ds
, const char *dir_name
)
191 len
= strlen (dir_name
);
193 /* Append the string onto the stack. */
194 obstack_grow (&ds
->dir_stack
, dir_name
, len
);
196 /* Append a trailing slash. */
197 obstack_1grow (&ds
->dir_stack
, '/');
199 /* Add one for the slash. */
202 /* Push the length (including slash) onto its stack. */
203 obstack_grow (&ds
->len_stack
, &len
, sizeof (len
));
206 /* Return the entry name of the directory on the top of the stack
207 in malloc'd storage. */
209 top_dir (Dirstack_state
const *ds
)
211 int n_lengths
= obstack_object_size (&ds
->len_stack
) / sizeof (size_t);
212 size_t *length
= (size_t *) obstack_base (&ds
->len_stack
);
213 size_t top_len
= length
[n_lengths
- 1];
214 char const *p
= obstack_next_free (&ds
->dir_stack
) - top_len
;
215 char *q
= xmalloc (top_len
);
216 memcpy (q
, p
, top_len
- 1);
222 pop_dir (Dirstack_state
*ds
)
224 int n_lengths
= obstack_object_size (&ds
->len_stack
) / sizeof (size_t);
225 size_t *length
= (size_t *) obstack_base (&ds
->len_stack
);
228 assert (n_lengths
> 0);
229 top_len
= length
[n_lengths
- 1];
230 assert (top_len
>= 2);
232 /* Pop off the specified length of pathname. */
233 assert (obstack_object_size (&ds
->dir_stack
) >= top_len
);
234 obstack_blank (&ds
->dir_stack
, -top_len
);
236 /* Pop the length stack, too. */
237 assert (obstack_object_size (&ds
->len_stack
) >= sizeof (size_t));
238 obstack_blank (&ds
->len_stack
, (int) -(sizeof (size_t)));
241 /* Copy the SRC_LEN bytes of data beginning at SRC into the DST_LEN-byte
242 buffer, DST, so that the last source byte is at the end of the destination
243 buffer. If SRC_LEN is longer than DST_LEN, then set *TRUNCATED to non-zero.
244 Set *RESULT to point to the beginning of (the portion of) the source data
245 in DST. Return the number of bytes remaining in the destination buffer. */
248 right_justify (char *dst
, size_t dst_len
, const char *src
, size_t src_len
,
249 char **result
, int *truncated
)
254 if (src_len
<= dst_len
)
257 dp
= dst
+ (dst_len
- src_len
);
262 sp
= src
+ (src_len
- dst_len
);
268 *result
= memcpy (dp
, sp
, src_len
);
269 return dst_len
- src_len
;
272 /* Using the global directory name obstack, create the full path to FILENAME.
273 Return it in sometimes-realloc'd space that should not be freed by the
274 caller. Realloc as necessary. If realloc fails, use a static buffer
275 and put as long a suffix in that buffer as possible. */
277 #define full_filename(Filename) full_filename_ (ds, Filename)
279 full_filename_ (Dirstack_state
const *ds
, const char *filename
)
281 static char *buf
= NULL
;
282 static size_t n_allocated
= 0;
284 int dir_len
= obstack_object_size (&ds
->dir_stack
);
285 char *dir_name
= (char *) obstack_base (&ds
->dir_stack
);
286 size_t n_bytes_needed
;
289 filename_len
= strlen (filename
);
290 n_bytes_needed
= dir_len
+ filename_len
+ 1;
292 if (n_allocated
< n_bytes_needed
)
294 /* This code requires that realloc accept NULL as the first arg.
295 This function must not use xrealloc. Otherwise, an out-of-memory
296 error involving a file name to be expanded here wouldn't ever
297 be issued. Use realloc and fall back on using a static buffer
298 if memory allocation fails. */
299 buf
= realloc (buf
, n_bytes_needed
);
300 n_allocated
= n_bytes_needed
;
304 #define SBUF_SIZE 512
305 #define ELLIPSES_PREFIX "[...]"
306 static char static_buf
[SBUF_SIZE
];
311 len
= right_justify (static_buf
, SBUF_SIZE
, filename
,
312 filename_len
+ 1, &p
, &truncated
);
313 right_justify (static_buf
, len
, dir_name
, dir_len
, &p
, &truncated
);
316 memcpy (static_buf
, ELLIPSES_PREFIX
,
317 sizeof (ELLIPSES_PREFIX
) - 1);
323 if (filename_len
== 1 && *filename
== '.' && dir_len
)
325 /* FILENAME is just `.' and dir_len is nonzero.
326 Copy the directory part, omitting the trailing slash,
327 and append a trailing zero byte. */
328 char *p
= mempcpy (buf
, dir_name
, dir_len
- 1);
333 /* Copy the directory part, including trailing slash, and then
334 append the filename part, including a trailing zero byte. */
335 memcpy (mempcpy (buf
, dir_name
, dir_len
), filename
, filename_len
+ 1);
336 assert (strlen (buf
) + 1 == n_bytes_needed
);
343 AD_stack_height (Dirstack_state
const *ds
)
345 return obstack_object_size (&ds
->Active_dir
) / sizeof (struct AD_ent
);
348 static struct AD_ent
*
349 AD_stack_top (Dirstack_state
const *ds
)
351 return (struct AD_ent
*)
352 ((char *) obstack_next_free (&ds
->Active_dir
) - sizeof (struct AD_ent
));
356 AD_stack_pop (Dirstack_state
*ds
)
358 /* operate on Active_dir. pop and free top entry */
359 struct AD_ent
*top
= AD_stack_top (ds
);
360 if (top
->unremovable
)
361 hash_free (top
->unremovable
);
362 obstack_blank (&ds
->Active_dir
, -sizeof (struct AD_ent
));
366 /* chdir `up' one level.
367 Whenever using chdir '..', verify that the post-chdir
368 dev/ino numbers for `.' match the saved ones.
369 Return the name (in malloc'd storage) of the
370 directory (usually now empty) from which we're coming. */
372 AD_pop_and_chdir (Dirstack_state
*ds
)
374 /* Get the name of the current directory from the top of the stack. */
375 char *dir
= top_dir (ds
);
376 enum RM_status old_status
= AD_stack_top(ds
)->status
;
382 /* Propagate any failure to parent. */
383 UPDATE_STATUS (AD_stack_top(ds
)->status
, old_status
);
385 assert (AD_stack_height (ds
));
387 top
= AD_stack_top (ds
);
388 if (1 < AD_stack_height (ds
))
390 /* We can give a better diagnostic here, since the target is relative. */
393 error (EXIT_FAILURE
, errno
,
394 _("cannot chdir from %s to .."),
395 quote (full_filename (".")));
400 if (restore_cwd (&top
->u
.saved_cwd
))
401 error (EXIT_FAILURE
, errno
,
402 _("failed to return to initial working directory"));
405 if (lstat (".", &sb
))
406 error (EXIT_FAILURE
, errno
,
407 _("cannot lstat `.' in %s"), quote (full_filename (".")));
409 if (1 < AD_stack_height (ds
))
411 /* Ensure that post-chdir dev/ino match the stored ones. */
412 if ( ! SAME_INODE (sb
, top
->u
.a
))
413 error (EXIT_FAILURE
, 0,
414 _("%s changed dev/ino"), quote (full_filename (".")));
420 /* Initialize *HT if it is NULL.
421 Insert FILENAME into HT. */
423 AD_mark_helper (Hash_table
**ht
, char const *filename
)
426 *ht
= hash_initialize (HT_UNREMOVABLE_INITIAL_CAPACITY
, NULL
, hash_pjw
,
427 hash_compare_strings
, hash_freer
);
430 if (! hash_insert (*ht
, filename
))
434 /* Mark FILENAME (in current directory) as unremovable. */
436 AD_mark_as_unremovable (Dirstack_state
*ds
, char const *filename
)
438 AD_mark_helper (&AD_stack_top(ds
)->unremovable
, xstrdup (filename
));
441 /* Mark the current directory as unremovable. I.e., mark the entry
442 in the parent directory corresponding to `.'.
443 This happens e.g., when an opendir fails and the only name
444 the caller has conveniently at hand is `.'. */
446 AD_mark_current_as_unremovable (Dirstack_state
*ds
)
448 struct AD_ent
*top
= AD_stack_top (ds
);
449 const char *curr
= top_dir (ds
);
451 assert (1 < AD_stack_height (ds
));
454 AD_mark_helper (&top
->unremovable
, curr
);
457 /* Push the initial cwd info onto the stack.
458 This will always be the bottommost entry on the stack. */
460 AD_push_initial (Dirstack_state
*ds
, struct saved_cwd
const *cwd
)
464 /* Extend the stack. */
465 obstack_blank (&ds
->Active_dir
, sizeof (struct AD_ent
));
467 /* Fill in the new values. */
468 top
= AD_stack_top (ds
);
469 top
->u
.saved_cwd
= *cwd
;
470 top
->unremovable
= NULL
;
473 /* Push info about the current working directory (".") onto the
474 active directory stack. DIR is the ./-relative name through
475 which we've just `chdir'd to this directory. DIR_SB_FROM_PARENT
476 is the result of calling lstat on DIR from the parent of DIR. */
478 AD_push (Dirstack_state
*ds
, char const *dir
,
479 struct stat
const *dir_sb_from_parent
)
486 if (lstat (".", &sb
))
487 error (EXIT_FAILURE
, errno
,
488 _("cannot lstat `.' in %s"), quote (full_filename (".")));
490 if ( ! SAME_INODE (sb
, *dir_sb_from_parent
))
491 error (EXIT_FAILURE
, errno
,
492 _("%s changed dev/ino"), quote (full_filename (".")));
494 /* Extend the stack. */
495 obstack_blank (&ds
->Active_dir
, sizeof (struct AD_ent
));
497 /* Fill in the new values. */
498 top
= AD_stack_top (ds
);
499 top
->u
.a
.st_dev
= sb
.st_dev
;
500 top
->u
.a
.st_ino
= sb
.st_ino
;
501 top
->unremovable
= NULL
;
505 AD_is_removable (Dirstack_state
const *ds
, char const *file
)
507 struct AD_ent
*top
= AD_stack_top (ds
);
508 return ! (top
->unremovable
&& hash_lookup (top
->unremovable
, file
));
512 is_empty_dir (char const *dir
)
514 DIR *dirp
= opendir (dir
);
531 return errno
== 0 ? true : false;
535 if ( ! DOT_OR_DOTDOT (f
))
543 /* Prompt whether to remove FILENAME, if required via a combination of
544 the options specified by X and/or file attributes. If the file may
545 be removed, return RM_OK. If the user declines to remove the file,
546 return RM_USER_DECLINED. If not ignoring missing files and we
547 cannot lstat FILENAME, then return RM_ERROR.
549 Depending on MODE, ask whether to `descend into' or to `remove' the
550 directory FILENAME. MODE is ignored when FILENAME is not a directory.
551 Set *IS_EMPTY to T_YES if FILENAME is an empty directory, and it is
552 appropriate to try to remove it with rmdir (e.g. recursive mode).
553 Don't even try to set *IS_EMPTY when MODE == PA_REMOVE_DIR.
554 Set *IS_DIR to T_YES or T_NO if we happen to determine whether
555 FILENAME is a directory. */
556 static enum RM_status
557 prompt (Dirstack_state
const *ds
, char const *filename
,
558 struct rm_options
const *x
, enum Prompt_action mode
,
559 Ternary
*is_dir
, Ternary
*is_empty
)
561 int write_protected
= 0;
562 *is_empty
= T_UNKNOWN
;
565 if ((!x
->ignore_missing_files
&& (x
->interactive
|| x
->stdin_tty
)
566 && (write_protected
= (euidaccess (filename
, W_OK
) && errno
== EACCES
)))
570 if (lstat (filename
, &sbuf
))
572 /* lstat failed. This happens e.g., with `rm '''. */
573 error (0, errno
, _("cannot lstat %s"),
574 quote (full_filename (filename
)));
578 /* Using permissions doesn't make sense for symlinks. */
579 if (S_ISLNK (sbuf
.st_mode
))
581 if ( ! x
->interactive
)
586 /* Issue the prompt. */
588 char const *quoted_name
= quote (full_filename (filename
));
590 *is_dir
= (S_ISDIR (sbuf
.st_mode
) ? T_YES
: T_NO
);
592 /* FIXME: use a variant of error (instead of fprintf) that doesn't
593 append a newline. Then we won't have to declare program_name in
595 if (S_ISDIR (sbuf
.st_mode
)
597 && mode
== PA_DESCEND_INTO_DIR
598 && ((*is_empty
= (is_empty_dir (filename
) ? T_YES
: T_NO
))
602 ? _("%s: descend into write-protected directory %s? ")
603 : _("%s: descend into directory %s? ")),
604 program_name
, quoted_name
);
607 /* TRANSLATORS: You may find it more convenient to translate
608 the equivalent of _("%s: remove %s (write-protected) %s? ").
609 It should avoid grammatical problems with the output
613 ? _("%s: remove write-protected %s %s? ")
614 : _("%s: remove %s %s? ")),
615 program_name
, file_type (&sbuf
), quoted_name
);
619 return RM_USER_DECLINED
;
625 #if HAVE_STRUCT_DIRENT_D_TYPE
626 # define DT_IS_DIR(D) ((D)->d_type == DT_DIR)
628 /* Use this only if the member exists -- i.e., don't return 0. */
629 # define DT_IS_DIR(D) do_not_use_this_macro
632 #define DO_UNLINK(Filename, X) \
635 if (unlink (Filename) == 0) \
638 printf (_("removed %s\n"), quote (full_filename (Filename))); \
642 if (errno == ENOENT && (X)->ignore_missing_files) \
647 #define DO_RMDIR(Filename, X) \
650 if (rmdir (Filename) == 0) \
653 printf (_("removed directory: %s\n"), \
654 quote (full_filename (Filename))); \
658 if (errno == ENOENT && (X)->ignore_missing_files) \
661 if (errno == ENOTEMPTY || errno == EEXIST) \
662 return RM_NONEMPTY_DIR; \
666 /* Remove the file or directory specified by FILENAME.
667 Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
668 But if FILENAME specifies a non-empty directory, return RM_NONEMPTY_DIR. */
670 static enum RM_status
671 remove_entry (Dirstack_state
const *ds
, char const *filename
,
672 struct rm_options
const *x
, struct dirent
const *dp
)
675 Ternary is_empty_directory
;
676 enum RM_status s
= prompt (ds
, filename
, x
, PA_DESCEND_INTO_DIR
,
677 &is_dir
, &is_empty_directory
);
682 /* Why bother with the following #if/#else block? Because on systems with
683 an unlink function that *can* unlink directories, we must determine the
684 type of each entry before removing it. Otherwise, we'd risk unlinking an
685 entire directory tree simply by unlinking a single directory; then all
686 the storage associated with that hierarchy would not be freed until the
687 next reboot. Not nice. To avoid that, on such slightly losing systems, we
688 need to call lstat to determine the type of each entry, and that represents
689 extra overhead that -- it turns out -- we can avoid on GNU-libc-based
690 systems, since there, unlink will never remove a directory. */
692 #if ROOT_CAN_UNLINK_DIRS
694 /* If we don't already know whether FILENAME is a directory, find out now.
695 Then, if it's a non-directory, we can use unlink on it. */
696 if (is_dir
== T_UNKNOWN
)
698 # if HAVE_STRUCT_DIRENT_D_TYPE
699 if (dp
&& dp
->d_type
!= DT_UNKNOWN
)
700 is_dir
= DT_IS_DIR (dp
) ? T_YES
: T_NO
;
705 if (lstat (filename
, &sbuf
))
707 if (errno
== ENOENT
&& x
->ignore_missing_files
)
711 _("cannot lstat %s"), quote (full_filename (filename
)));
715 is_dir
= S_ISDIR (sbuf
.st_mode
) ? T_YES
: T_NO
;
721 /* At this point, barring race conditions, FILENAME is known
722 to be a non-directory, so it's ok to try to unlink it. */
723 DO_UNLINK (filename
, x
);
725 /* unlink failed with some other error code. report it. */
726 error (0, errno
, _("cannot remove %s"),
727 quote (full_filename (filename
)));
733 error (0, EISDIR
, _("cannot remove directory %s"),
734 quote (full_filename (filename
)));
738 if (is_empty_directory
== T_YES
)
740 DO_RMDIR (filename
, x
);
741 /* Don't diagnose any failure here.
742 It'll be detected when the caller tries another way. */
746 #else /* ! ROOT_CAN_UNLINK_DIRS */
748 if (is_dir
== T_YES
&& ! x
->recursive
)
750 error (0, EISDIR
, _("cannot remove directory %s"),
751 quote (full_filename (filename
)));
755 /* is_empty_directory is set iff it's ok to use rmdir.
756 Note that it's set only in interactive mode -- in which case it's
757 an optimization that arranges so that the user is asked just
758 once whether to remove the directory. */
759 if (is_empty_directory
== T_YES
)
760 DO_RMDIR (filename
, x
);
762 /* If we happen to know that FILENAME is a directory, return now
763 and let the caller remove it -- this saves the overhead of a failed
764 unlink call. If FILENAME is a command-line argument, then dp is NULL,
765 so we'll first try to unlink it. Using unlink here is ok, because it
766 cannot remove a directory. */
767 if ((dp
&& DT_IS_DIR (dp
)) || is_dir
== T_YES
)
768 return RM_NONEMPTY_DIR
;
770 DO_UNLINK (filename
, x
);
772 /* Accept either EISDIR or EPERM as an indication that FILENAME may be
773 a directory. POSIX says that unlink must set errno to EPERM when it
774 fails to remove a directory, while Linux-2.4.18 sets it to EISDIR. */
775 if ((errno
!= EISDIR
&& errno
!= EPERM
) || ! x
->recursive
)
777 /* some other error code. Report it and fail.
778 Likewise, if we're trying to remove a directory without
779 the --recursive option. */
780 error (0, errno
, _("cannot remove %s"),
781 quote (full_filename (filename
)));
786 return RM_NONEMPTY_DIR
;
789 /* Remove entries in `.', the current working directory (cwd).
790 Upon finding a directory that is both non-empty and that can be chdir'd
791 into, return RM_OK and set *SUBDIR and fill in SUBDIR_SB, where
792 SUBDIR is the malloc'd name of the subdirectory if the chdir succeeded,
793 NULL otherwise (e.g., if opendir failed or if there was no subdirectory).
794 Likewise, SUBDIR_SB is the result of calling lstat on SUBDIR.
795 Return RM_OK if all entries are removed. Return RM_ERROR if any
796 entry cannot be removed. Otherwise, return RM_USER_DECLINED if
797 the user declines to remove at least one entry. Remove as much as
798 possible, continuing even if we fail to remove some entries. */
799 static enum RM_status
800 remove_cwd_entries (Dirstack_state
*ds
, char **subdir
, struct stat
*subdir_sb
,
801 struct rm_options
const *x
)
803 DIR *dirp
= opendir (".");
804 struct AD_ent
*top
= AD_stack_top (ds
);
805 enum RM_status status
= top
->status
;
807 assert (VALID_STATUS (status
));
812 if (errno
!= ENOENT
|| !x
->ignore_missing_files
)
814 error (0, errno
, _("cannot open directory %s"),
815 quote (full_filename (".")));
823 enum RM_status tmp_status
;
826 /* Set errno to zero so we can distinguish between a readdir failure
827 and when readdir simply finds that there are no more entries. */
829 if ((dp
= readdir (dirp
)) == NULL
)
833 /* Save/restore errno across closedir call. */
838 /* Arrange to give a diagnostic after exiting this loop. */
845 if (DOT_OR_DOTDOT (f
))
848 /* Skip files we've already tried/failed to remove. */
849 if ( ! AD_is_removable (ds
, f
))
852 /* Pass dp->d_type info to remove_entry so the non-glibc
853 case can decide whether to use unlink or chdir.
854 Systems without the d_type member will have to endure
855 the performance hit of first calling lstat F. */
856 tmp_status
= remove_entry (ds
, f
, x
, dp
);
864 case RM_USER_DECLINED
:
865 AD_mark_as_unremovable (ds
, f
);
866 UPDATE_STATUS (status
, tmp_status
);
869 case RM_NONEMPTY_DIR
:
871 /* Save a copy of errno, in case the preceding unlink (from
872 remove_entry's DO_UNLINK) of a non-directory failed due
874 int saved_errno
= errno
;
876 /* Record dev/ino of F so that we can compare
877 that with dev/ino of `.' after the chdir.
878 This dev/ino pair is also used in cycle detection. */
879 if (lstat (f
, subdir_sb
))
880 error (EXIT_FAILURE
, errno
, _("cannot lstat %s"),
881 quote (full_filename (f
)));
885 /* It is much more common that we reach this point for an
886 inaccessible directory. Hence the second diagnostic, below.
887 However it is also possible that F is a non-directory.
888 That can happen when we use the `! ROOT_CAN_UNLINK_DIRS'
889 block of code and when DO_UNLINK fails due to EPERM.
890 In that case, give a better diagnostic. */
891 if (errno
== ENOTDIR
)
892 error (0, saved_errno
, _("cannot remove %s"),
893 quote (full_filename (f
)));
895 error (0, errno
, _("cannot chdir from %s to %s"),
896 quote_n (0, full_filename (".")), quote_n (1, f
));
897 AD_mark_as_unremovable (ds
, f
);
901 if (cycle_check (&ds
->cycle_check_state
, subdir_sb
))
904 WARNING: Circular directory structure.\n\
905 This almost certainly means that you have a corrupted file system.\n\
906 NOTIFY YOUR SYSTEM MANAGER.\n\
907 The following directory is part of the cycle:\n %s\n"),
908 quote (full_filename (".")));
909 longjmp (ds
->current_arg_jumpbuf
, 1);
912 *subdir
= xstrdup (f
);
917 /* Record status for this directory. */
918 UPDATE_STATUS (top
->status
, status
);
924 if (dirp
== NULL
|| CLOSEDIR (dirp
) != 0)
926 /* Note that this diagnostic serves for both readdir
927 and closedir failures. */
928 error (0, errno
, _("reading directory %s"), quote (full_filename (".")));
935 /* Do this after each call to AD_push or AD_push_initial.
936 Because the status = RM_OK bit is too remove-specific to
937 go into the general-purpose AD_* package. */
938 #define AD_INIT_OTHER_MEMBERS() \
941 AD_stack_top(ds)->status = RM_OK; \
945 /* Remove the hierarchy rooted at DIR.
946 Do that by changing into DIR, then removing its contents, then
947 returning to the original working directory and removing DIR itself.
948 Don't use recursion. Be careful when using chdir ".." that we
949 return to the same directory from which we came, if necessary.
950 Return 1 for success, 0 if some file cannot be removed or if
952 If the working directory cannot be restored, exit immediately. */
954 static enum RM_status
955 remove_dir (Dirstack_state
*ds
, char const *dir
, struct saved_cwd
**cwd_state
,
956 struct rm_options
const *x
)
958 enum RM_status status
;
961 /* Save any errno (from caller's failed remove_entry call), in case DIR
962 is not a directory, so that we can give a reasonable diagnostic. */
963 int saved_errno
= errno
;
965 if (*cwd_state
== NULL
)
967 *cwd_state
= XMALLOC (struct saved_cwd
, 1);
968 if (save_cwd (*cwd_state
))
970 AD_push_initial (ds
, *cwd_state
);
971 AD_INIT_OTHER_MEMBERS ();
974 /* There is a race condition in that an attacker could replace the nonempty
975 directory, DIR, with a symlink between the preceding call to rmdir
976 (in our caller) and the chdir below. However, the following lstat,
977 along with the `stat (".",...' and dev/ino comparison in AD_push
978 ensure that we detect it and fail. */
980 if (lstat (dir
, &dir_sb
))
983 _("cannot lstat %s"), quote (full_filename (dir
)));
989 if (! S_ISDIR (dir_sb
.st_mode
))
991 /* This happens on Linux-2.4.18 when a non-privileged user tries
992 to delete a file that is owned by another user in a directory
993 like /tmp that has the S_ISVTX flag set. */
994 assert (saved_errno
== EPERM
);
995 error (0, saved_errno
,
996 _("cannot remove %s"), quote (full_filename (dir
)));
1001 _("cannot chdir from %s to %s"),
1002 quote_n (0, full_filename (".")), quote_n (1, dir
));
1007 AD_push (ds
, dir
, &dir_sb
);
1008 AD_INIT_OTHER_MEMBERS ();
1014 char *subdir
= NULL
;
1015 struct stat subdir_sb
;
1016 enum RM_status tmp_status
= remove_cwd_entries (ds
,
1017 &subdir
, &subdir_sb
, x
);
1018 if (tmp_status
!= RM_OK
)
1020 UPDATE_STATUS (status
, tmp_status
);
1021 AD_mark_current_as_unremovable (ds
);
1025 AD_push (ds
, subdir
, &subdir_sb
);
1026 AD_INIT_OTHER_MEMBERS ();
1032 /* Execution reaches this point when we've removed the last
1033 removable entry from the current directory. */
1035 char *d
= AD_pop_and_chdir (ds
);
1037 /* Try to remove D only if remove_cwd_entries succeeded. */
1038 if (tmp_status
== RM_OK
)
1040 /* This does a little more work than necessary when it actually
1041 prompts the user. E.g., we already know that D is a directory
1042 and that it's almost certainly empty, yet we lstat it.
1043 But that's no big deal since we're interactive. */
1046 enum RM_status s
= prompt (ds
, d
, x
, PA_REMOVE_DIR
,
1047 &is_dir
, &is_empty
);
1058 printf (_("removed directory: %s\n"),
1059 quote (full_filename (d
)));
1063 error (0, errno
, _("cannot remove directory %s"),
1064 quote (full_filename (d
)));
1065 AD_mark_as_unremovable (ds
, d
);
1067 UPDATE_STATUS (AD_stack_top(ds
)->status
, status
);
1073 if (AD_stack_height (ds
) == 1)
1081 /* Remove the file or directory specified by FILENAME.
1082 Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
1083 On input, the first time this function is called, CWD_STATE should be
1084 the address of a NULL pointer. Do not modify it for any subsequent calls.
1085 On output, it is either that same NULL pointer or the address of
1086 a malloc'd `struct saved_cwd' that may be freed. */
1088 static enum RM_status
1089 rm_1 (Dirstack_state
*ds
, char const *filename
,
1090 struct rm_options
const *x
, struct saved_cwd
**cwd_state
)
1092 char *base
= base_name (filename
);
1093 enum RM_status status
;
1095 if (DOT_OR_DOTDOT (base
))
1097 error (0, 0, _("cannot remove `.' or `..'"));
1101 status
= remove_entry (ds
, filename
, x
, NULL
);
1102 if (status
!= RM_NONEMPTY_DIR
)
1105 return remove_dir (ds
, filename
, cwd_state
, x
);
1108 /* Remove all files and/or directories specified by N_FILES and FILE.
1109 Apply the options in X. */
1111 rm (size_t n_files
, char const *const *file
, struct rm_options
const *x
)
1113 struct saved_cwd
*cwd_state
= NULL
;
1114 enum RM_status status
= RM_OK
;
1120 for (i
= 0; i
< n_files
; i
++)
1123 cycle_check_init (&ds
->cycle_check_state
);
1124 /* In the event that rm_1->remove_dir->remove_cwd_entries detects
1125 a directory cycle, arrange to fail, give up on this FILE, but
1126 continue on with any other arguments. */
1127 if (setjmp (ds
->current_arg_jumpbuf
))
1130 s
= rm_1 (ds
, file
[i
], x
, &cwd_state
);
1131 assert (VALID_STATUS (s
));
1132 UPDATE_STATUS (status
, s
);