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 "file-type.h"
42 /* Avoid shadowing warnings because these are functions declared
43 in dirname.h as well as locals used below. */
44 #define dir_name rm_dir_name
45 #define dir_len rm_dir_len
47 #define obstack_chunk_alloc malloc
48 #define obstack_chunk_free free
50 /* FIXME: if possible, use autoconf... */
52 # define ROOT_CAN_UNLINK_DIRS 0
54 # define ROOT_CAN_UNLINK_DIRS 1
63 typedef enum Ternary Ternary
;
65 /* The prompt function may be called twice a given directory.
66 The first time, we ask whether to descend into it, and the
67 second time, we ask whether to remove it. */
70 PA_DESCEND_INTO_DIR
= 2,
74 /* On systems with an lstat function that accepts the empty string,
75 arrange to make lstat calls go through the wrapper function. */
76 #if HAVE_LSTAT_EMPTY_STRING_BUG
77 int rpl_lstat (const char *, struct stat
*);
78 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
81 #ifdef D_INO_IN_DIRENT
82 # define D_INO(dp) ((dp)->d_ino)
83 # define ENABLE_CYCLE_CHECK
85 /* Some systems don't have inodes, so fake them to avoid lots of ifdefs. */
89 /* Initial capacity of per-directory hash table of entries that have
90 been processed but not been deleted. */
91 #define HT_UNREMOVABLE_INITIAL_CAPACITY 13
93 /* An entry in the active directory stack.
94 Each entry corresponds to an `active' directory. */
97 /* For a given active directory, this is the set of names of
98 entries in that directory that could/should not be removed.
99 For example, `.' and `..', as well as files/dirs for which
100 unlink/rmdir failed e.g., due to access restrictions. */
101 Hash_table
*unremovable
;
103 /* Record the status for a given active directory; we need to know
104 whether an entry was not removed, either because of an error or
105 because the user declined. */
106 enum RM_status status
;
110 /* The directory's dev/ino. Used to ensure that `chdir some-subdir', then
111 `chdir ..' takes us back to the same directory from which we started).
112 (valid for all but the bottommost entry on the stack. */
115 /* Enough information to restore the initial working directory.
116 (valid only for the bottommost entry on the stack) */
117 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
, NULL
, NULL
))
404 if (lstat (".", &sb
))
405 error (EXIT_FAILURE
, errno
,
406 _("cannot lstat `.' in %s"), quote (full_filename (".")));
408 if (1 < AD_stack_height (ds
))
410 /* Ensure that post-chdir dev/ino match the stored ones. */
411 if ( ! SAME_INODE (sb
, top
->u
.a
))
412 error (EXIT_FAILURE
, 0,
413 _("%s changed dev/ino"), quote (full_filename (".")));
419 /* Initialize *HT if it is NULL.
420 Insert FILENAME into HT. */
422 AD_mark_helper (Hash_table
**ht
, char const *filename
)
425 *ht
= hash_initialize (HT_UNREMOVABLE_INITIAL_CAPACITY
, NULL
, hash_pjw
,
426 hash_compare_strings
, hash_freer
);
429 if (! hash_insert (*ht
, filename
))
433 /* Mark FILENAME (in current directory) as unremovable. */
435 AD_mark_as_unremovable (Dirstack_state
*ds
, char const *filename
)
437 AD_mark_helper (&AD_stack_top(ds
)->unremovable
, xstrdup (filename
));
440 /* Mark the current directory as unremovable. I.e., mark the entry
441 in the parent directory corresponding to `.'.
442 This happens e.g., when an opendir fails and the only name
443 the caller has conveniently at hand is `.'. */
445 AD_mark_current_as_unremovable (Dirstack_state
*ds
)
447 struct AD_ent
*top
= AD_stack_top (ds
);
448 const char *curr
= top_dir (ds
);
450 assert (1 < AD_stack_height (ds
));
453 AD_mark_helper (&top
->unremovable
, curr
);
456 /* Push the initial cwd info onto the stack.
457 This will always be the bottommost entry on the stack. */
459 AD_push_initial (Dirstack_state
*ds
, struct saved_cwd
const *cwd
)
463 /* Extend the stack. */
464 obstack_blank (&ds
->Active_dir
, sizeof (struct AD_ent
));
466 /* Fill in the new values. */
467 top
= AD_stack_top (ds
);
468 top
->u
.saved_cwd
= *cwd
;
469 top
->unremovable
= NULL
;
472 /* Push info about the current working directory (".") onto the
473 active directory stack. DIR is the ./-relative name through
474 which we've just `chdir'd to this directory. DIR_SB_FROM_PARENT
475 is the result of calling lstat on DIR from the parent of DIR. */
477 AD_push (Dirstack_state
*ds
, char const *dir
,
478 struct stat
const *dir_sb_from_parent
)
485 if (lstat (".", &sb
))
486 error (EXIT_FAILURE
, errno
,
487 _("cannot lstat `.' in %s"), quote (full_filename (".")));
489 if ( ! SAME_INODE (sb
, *dir_sb_from_parent
))
490 error (EXIT_FAILURE
, errno
,
491 _("%s changed dev/ino"), quote (full_filename (".")));
493 /* Extend the stack. */
494 obstack_blank (&ds
->Active_dir
, sizeof (struct AD_ent
));
496 /* Fill in the new values. */
497 top
= AD_stack_top (ds
);
498 top
->u
.a
.st_dev
= sb
.st_dev
;
499 top
->u
.a
.st_ino
= sb
.st_ino
;
500 top
->unremovable
= NULL
;
504 AD_is_removable (Dirstack_state
const *ds
, char const *file
)
506 struct AD_ent
*top
= AD_stack_top (ds
);
507 return ! (top
->unremovable
&& hash_lookup (top
->unremovable
, file
));
511 is_empty_dir (char const *dir
)
513 DIR *dirp
= opendir (dir
);
530 return errno
== 0 ? true : false;
534 if ( ! DOT_OR_DOTDOT (f
))
542 /* Prompt whether to remove FILENAME, if required via a combination of
543 the options specified by X and/or file attributes. If the file may
544 be removed, return RM_OK. If the user declines to remove the file,
545 return RM_USER_DECLINED. If not ignoring missing files and we
546 cannot lstat FILENAME, then return RM_ERROR.
548 Depending on MODE, ask whether to `descend into' or to `remove' the
549 directory FILENAME. MODE is ignored when FILENAME is not a directory.
550 Set *IS_EMPTY to T_YES if FILENAME is an empty directory, and it is
551 appropriate to try to remove it with rmdir (e.g. recursive mode).
552 Don't even try to set *IS_EMPTY when MODE == PA_REMOVE_DIR.
553 Set *IS_DIR to T_YES or T_NO if we happen to determine whether
554 FILENAME is a directory. */
555 static enum RM_status
556 prompt (Dirstack_state
const *ds
, char const *filename
,
557 struct rm_options
const *x
, enum Prompt_action mode
,
558 Ternary
*is_dir
, Ternary
*is_empty
)
560 int write_protected
= 0;
561 *is_empty
= T_UNKNOWN
;
564 if ((!x
->ignore_missing_files
&& (x
->interactive
|| x
->stdin_tty
)
565 && (write_protected
= (euidaccess (filename
, W_OK
) && errno
== EACCES
)))
569 if (lstat (filename
, &sbuf
))
571 /* lstat failed. This happens e.g., with `rm '''. */
572 error (0, errno
, _("cannot lstat %s"),
573 quote (full_filename (filename
)));
577 /* Using permissions doesn't make sense for symlinks. */
578 if (S_ISLNK (sbuf
.st_mode
))
580 if ( ! x
->interactive
)
585 /* Issue the prompt. */
587 char const *quoted_name
= quote (full_filename (filename
));
589 *is_dir
= (S_ISDIR (sbuf
.st_mode
) ? T_YES
: T_NO
);
591 /* FIXME: use a variant of error (instead of fprintf) that doesn't
592 append a newline. Then we won't have to declare program_name in
594 if (S_ISDIR (sbuf
.st_mode
)
596 && mode
== PA_DESCEND_INTO_DIR
597 && ((*is_empty
= (is_empty_dir (filename
) ? T_YES
: T_NO
))
601 ? _("%s: descend into write-protected directory %s? ")
602 : _("%s: descend into directory %s? ")),
603 program_name
, quoted_name
);
606 /* TRANSLATORS: You may find it more convenient to translate
607 the equivalent of _("%s: remove %s (write-protected) %s? ").
608 It should avoid grammatical problems with the output
612 ? _("%s: remove write-protected %s %s? ")
613 : _("%s: remove %s %s? ")),
614 program_name
, file_type (&sbuf
), quoted_name
);
618 return RM_USER_DECLINED
;
624 #if HAVE_STRUCT_DIRENT_D_TYPE
625 # define DT_IS_DIR(D) ((D)->d_type == DT_DIR)
627 /* Use this only if the member exists -- i.e., don't return 0. */
628 # define DT_IS_DIR(D) do_not_use_this_macro
631 #define DO_UNLINK(Filename, X) \
634 if (unlink (Filename) == 0) \
637 printf (_("removed %s\n"), quote (full_filename (Filename))); \
641 if (errno == ENOENT && (X)->ignore_missing_files) \
646 #define DO_RMDIR(Filename, X) \
649 if (rmdir (Filename) == 0) \
652 printf (_("removed directory: %s\n"), \
653 quote (full_filename (Filename))); \
657 if (errno == ENOENT && (X)->ignore_missing_files) \
660 if (errno == ENOTEMPTY || errno == EEXIST) \
661 return RM_NONEMPTY_DIR; \
665 /* Remove the file or directory specified by FILENAME.
666 Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
667 But if FILENAME specifies a non-empty directory, return RM_NONEMPTY_DIR. */
669 static enum RM_status
670 remove_entry (Dirstack_state
const *ds
, char const *filename
,
671 struct rm_options
const *x
, struct dirent
const *dp
)
674 Ternary is_empty_directory
;
675 enum RM_status s
= prompt (ds
, filename
, x
, PA_DESCEND_INTO_DIR
,
676 &is_dir
, &is_empty_directory
);
681 /* Why bother with the following #if/#else block? Because on systems with
682 an unlink function that *can* unlink directories, we must determine the
683 type of each entry before removing it. Otherwise, we'd risk unlinking an
684 entire directory tree simply by unlinking a single directory; then all
685 the storage associated with that hierarchy would not be freed until the
686 next reboot. Not nice. To avoid that, on such slightly losing systems, we
687 need to call lstat to determine the type of each entry, and that represents
688 extra overhead that -- it turns out -- we can avoid on GNU-libc-based
689 systems, since there, unlink will never remove a directory. */
691 #if ROOT_CAN_UNLINK_DIRS
693 /* If we don't already know whether FILENAME is a directory, find out now.
694 Then, if it's a non-directory, we can use unlink on it. */
695 if (is_dir
== T_UNKNOWN
)
697 # if HAVE_STRUCT_DIRENT_D_TYPE
698 if (dp
&& dp
->d_type
!= DT_UNKNOWN
)
699 is_dir
= DT_IS_DIR (dp
) ? T_YES
: T_NO
;
704 if (lstat (filename
, &sbuf
))
706 if (errno
== ENOENT
&& x
->ignore_missing_files
)
710 _("cannot lstat %s"), quote (full_filename (filename
)));
714 is_dir
= S_ISDIR (sbuf
.st_mode
) ? T_YES
: T_NO
;
720 /* At this point, barring race conditions, FILENAME is known
721 to be a non-directory, so it's ok to try to unlink it. */
722 DO_UNLINK (filename
, x
);
724 /* unlink failed with some other error code. report it. */
725 error (0, errno
, _("cannot remove %s"),
726 quote (full_filename (filename
)));
732 error (0, EISDIR
, _("cannot remove directory %s"),
733 quote (full_filename (filename
)));
737 if (is_empty_directory
== T_YES
)
739 DO_RMDIR (filename
, x
);
740 /* Don't diagnose any failure here.
741 It'll be detected when the caller tries another way. */
747 if (is_dir
== T_YES
&& ! x
->recursive
)
749 error (0, EISDIR
, _("cannot remove directory %s"),
750 quote (full_filename (filename
)));
754 /* is_empty_directory is set iff it's ok to use rmdir.
755 Note that it's set only in interactive mode -- in which case it's
756 an optimization that arranges so that the user is asked just
757 once whether to remove the directory. */
758 if (is_empty_directory
== T_YES
)
759 DO_RMDIR (filename
, x
);
761 /* If we happen to know that FILENAME is a directory, return now
762 and let the caller remove it -- this saves the overhead of a failed
763 unlink call. If FILENAME is a command-line argument, then dp is NULL,
764 so we'll first try to unlink it. Using unlink here is ok, because it
765 cannot remove a directory. */
766 if ((dp
&& DT_IS_DIR (dp
)) || is_dir
== T_YES
)
767 return RM_NONEMPTY_DIR
;
769 DO_UNLINK (filename
, x
);
771 /* Accept either EISDIR or EPERM as an indication that FILENAME may be
772 a directory. POSIX says that unlink must set errno to EPERM when it
773 fails to remove a directory, while Linux-2.4.18 sets it to EISDIR. */
774 if ((errno
!= EISDIR
&& errno
!= EPERM
) || ! x
->recursive
)
776 /* some other error code. Report it and fail.
777 Likewise, if we're trying to remove a directory without
778 the --recursive option. */
779 error (0, errno
, _("cannot remove %s"),
780 quote (full_filename (filename
)));
785 return RM_NONEMPTY_DIR
;
788 /* Remove entries in `.', the current working directory (cwd).
789 Upon finding a directory that is both non-empty and that can be chdir'd
790 into, return RM_OK and set *SUBDIR and fill in SUBDIR_SB, where
791 SUBDIR is the malloc'd name of the subdirectory if the chdir succeeded,
792 NULL otherwise (e.g., if opendir failed or if there was no subdirectory).
793 Likewise, SUBDIR_SB is the result of calling lstat on SUBDIR.
794 Return RM_OK if all entries are removed. Return RM_ERROR if any
795 entry cannot be removed. Otherwise, return RM_USER_DECLINED if
796 the user declines to remove at least one entry. Remove as much as
797 possible, continuing even if we fail to remove some entries. */
798 static enum RM_status
799 remove_cwd_entries (Dirstack_state
*ds
, char **subdir
, struct stat
*subdir_sb
,
800 struct rm_options
const *x
)
802 DIR *dirp
= opendir (".");
803 struct AD_ent
*top
= AD_stack_top (ds
);
804 enum RM_status status
= top
->status
;
806 assert (VALID_STATUS (status
));
811 if (errno
!= ENOENT
|| !x
->ignore_missing_files
)
813 error (0, errno
, _("cannot open directory %s"),
814 quote (full_filename (".")));
822 enum RM_status tmp_status
;
825 /* Set errno to zero so we can distinguish between a readdir failure
826 and when readdir simply finds that there are no more entries. */
828 if ((dp
= readdir (dirp
)) == NULL
)
832 /* Save/restore errno across closedir call. */
837 /* Arrange to give a diagnostic after exiting this loop. */
844 if (DOT_OR_DOTDOT (f
))
847 /* Skip files we've already tried/failed to remove. */
848 if ( ! AD_is_removable (ds
, f
))
851 /* Pass dp->d_type info to remove_entry so the non-glibc
852 case can decide whether to use unlink or chdir.
853 Systems without the d_type member will have to endure
854 the performance hit of first calling lstat F. */
855 tmp_status
= remove_entry (ds
, f
, x
, dp
);
863 case RM_USER_DECLINED
:
864 AD_mark_as_unremovable (ds
, f
);
865 UPDATE_STATUS (status
, tmp_status
);
868 case RM_NONEMPTY_DIR
:
869 /* Record dev/ino of F so that we can compare
870 that with dev/ino of `.' after the chdir.
871 This dev/ino pair is also used in cycle detection. */
872 if (lstat (f
, subdir_sb
))
873 error (EXIT_FAILURE
, errno
, _("cannot lstat %s"),
874 quote (full_filename (f
)));
878 error (0, errno
, _("cannot chdir from %s to %s"),
879 quote_n (0, full_filename (".")), quote_n (1, f
));
880 AD_mark_as_unremovable (ds
, f
);
884 if (cycle_check (&ds
->cycle_check_state
, subdir_sb
))
887 WARNING: Circular directory structure.\n\
888 This almost certainly means that you have a corrupted file system.\n\
889 NOTIFY YOUR SYSTEM MANAGER.\n\
890 The following directory is part of the cycle:\n %s\n"),
891 quote (full_filename (".")));
892 longjmp (ds
->current_arg_jumpbuf
, 1);
895 *subdir
= xstrdup (f
);
899 /* Record status for this directory. */
900 UPDATE_STATUS (top
->status
, status
);
906 if (dirp
== NULL
|| CLOSEDIR (dirp
) != 0)
908 /* Note that this diagnostic serves for both readdir
909 and closedir failures. */
910 error (0, errno
, _("reading directory %s"), quote (full_filename (".")));
917 /* Do this after each call to AD_push or AD_push_initial.
918 Because the status = RM_OK bit is too remove-specific to
919 go into the general-purpose AD_* package. */
920 #define AD_INIT_OTHER_MEMBERS() \
923 AD_stack_top(ds)->status = RM_OK; \
927 /* Remove the hierarchy rooted at DIR.
928 Do that by changing into DIR, then removing its contents, then
929 returning to the original working directory and removing DIR itself.
930 Don't use recursion. Be careful when using chdir ".." that we
931 return to the same directory from which we came, if necessary.
932 Return 1 for success, 0 if some file cannot be removed or if
934 If the working directory cannot be restored, exit immediately. */
936 static enum RM_status
937 remove_dir (Dirstack_state
*ds
, char const *dir
, struct saved_cwd
**cwd_state
,
938 struct rm_options
const *x
)
940 enum RM_status status
;
943 /* Save any errno (from caller's failed remove_entry call), in case DIR
944 is not a directory, so that we can give a reasonable diagnostic. */
945 int saved_errno
= errno
;
947 if (*cwd_state
== NULL
)
949 *cwd_state
= XMALLOC (struct saved_cwd
, 1);
950 if (save_cwd (*cwd_state
))
952 AD_push_initial (ds
, *cwd_state
);
953 AD_INIT_OTHER_MEMBERS ();
956 /* There is a race condition in that an attacker could replace the nonempty
957 directory, DIR, with a symlink between the preceding call to rmdir
958 (in our caller) and the chdir below. However, the following lstat,
959 along with the `stat (".",...' and dev/ino comparison in AD_push
960 ensure that we detect it and fail. */
962 if (lstat (dir
, &dir_sb
))
965 _("cannot lstat %s"), quote (full_filename (dir
)));
971 if (! S_ISDIR (dir_sb
.st_mode
))
973 /* This happens on Linux-2.4.18 when a non-privileged user tries
974 to delete a file that is owned by another user in a directory
975 like /tmp that has the S_ISVTX flag set. */
976 assert (saved_errno
== EPERM
);
977 error (0, saved_errno
,
978 _("cannot remove %s"), quote (full_filename (dir
)));
983 _("cannot chdir from %s to %s"),
984 quote_n (0, full_filename (".")), quote_n (1, dir
));
989 AD_push (ds
, dir
, &dir_sb
);
990 AD_INIT_OTHER_MEMBERS ();
997 struct stat subdir_sb
;
998 enum RM_status tmp_status
= remove_cwd_entries (ds
,
999 &subdir
, &subdir_sb
, x
);
1000 if (tmp_status
!= RM_OK
)
1002 UPDATE_STATUS (status
, tmp_status
);
1003 AD_mark_current_as_unremovable (ds
);
1007 AD_push (ds
, subdir
, &subdir_sb
);
1008 AD_INIT_OTHER_MEMBERS ();
1014 /* Execution reaches this point when we've removed the last
1015 removable entry from the current directory. */
1017 char *d
= AD_pop_and_chdir (ds
);
1019 /* Try to remove D only if remove_cwd_entries succeeded. */
1020 if (tmp_status
== RM_OK
)
1022 /* This does a little more work than necessary when it actually
1023 prompts the user. E.g., we already know that D is a directory
1024 and that it's almost certainly empty, yet we lstat it.
1025 But that's no big deal since we're interactive. */
1028 enum RM_status s
= prompt (ds
, d
, x
, PA_REMOVE_DIR
,
1029 &is_dir
, &is_empty
);
1040 printf (_("removed directory: %s\n"),
1041 quote (full_filename (d
)));
1045 error (0, errno
, _("cannot remove directory %s"),
1046 quote (full_filename (d
)));
1047 AD_mark_as_unremovable (ds
, d
);
1049 UPDATE_STATUS (AD_stack_top(ds
)->status
, status
);
1055 if (AD_stack_height (ds
) == 1)
1063 /* Remove the file or directory specified by FILENAME.
1064 Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
1065 On input, the first time this function is called, CWD_STATE should be
1066 the address of a NULL pointer. Do not modify it for any subsequent calls.
1067 On output, it is either that same NULL pointer or the address of
1068 a malloc'd `struct saved_cwd' that may be freed. */
1070 static enum RM_status
1071 rm_1 (Dirstack_state
*ds
, char const *filename
,
1072 struct rm_options
const *x
, struct saved_cwd
**cwd_state
)
1074 char *base
= base_name (filename
);
1075 enum RM_status status
;
1077 if (DOT_OR_DOTDOT (base
))
1079 error (0, 0, _("cannot remove `.' or `..'"));
1083 status
= remove_entry (ds
, filename
, x
, NULL
);
1084 if (status
!= RM_NONEMPTY_DIR
)
1087 return remove_dir (ds
, filename
, cwd_state
, x
);
1090 /* Remove all files and/or directories specified by N_FILES and FILE.
1091 Apply the options in X. */
1093 rm (size_t n_files
, char const *const *file
, struct rm_options
const *x
)
1095 struct saved_cwd
*cwd_state
= NULL
;
1096 enum RM_status status
= RM_OK
;
1102 for (i
= 0; i
< n_files
; i
++)
1105 cycle_check_init (&ds
->cycle_check_state
);
1106 /* In the event that rm_1->remove_dir->remove_cwd_entries detects
1107 a directory cycle, arrange to fail, give up on this FILE, but
1108 continue on with any other arguments. */
1109 if (setjmp (ds
->current_arg_jumpbuf
))
1112 s
= rm_1 (ds
, file
[i
], x
, &cwd_state
);
1113 assert (VALID_STATUS (s
));
1114 UPDATE_STATUS (status
, s
);