* src/remove.c (AD_ensure_initialized): New function.
[platform/upstream/coreutils.git] / src / remove.c
1 /* remove.c -- core functions for removing files and directories
2    Copyright (C) 88, 90, 91, 1994-2006 Free Software Foundation, Inc.
3
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)
7    any later version.
8
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.
13
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Extracted from rm.c and librarified, then rewritten by Jim Meyering.  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <setjmp.h>
24 #include <assert.h>
25
26 #include "system.h"
27 #include "cycle-check.h"
28 #include "dirfd.h"
29 #include "error.h"
30 #include "euidaccess.h"
31 #include "euidaccess-stat.h"
32 #include "file-type.h"
33 #include "hash.h"
34 #include "hash-pjw.h"
35 #include "lstat.h"
36 #include "obstack.h"
37 #include "openat.h"
38 #include "quote.h"
39 #include "remove.h"
40 #include "root-dev-ino.h"
41 #include "unlinkdir.h"
42 #include "yesno.h"
43
44 /* Avoid shadowing warnings because these are functions declared
45    in dirname.h as well as locals used below.  */
46 #define dir_name rm_dir_name
47 #define dir_len rm_dir_len
48
49 #define obstack_chunk_alloc malloc
50 #define obstack_chunk_free free
51
52 /* This is the maximum number of consecutive readdir/unlink calls that
53    can be made (with no intervening rewinddir or closedir/opendir) before
54    triggering a bug that makes readdir return NULL even though some
55    directory entries have not been processed.  The bug afflicts SunOS's
56    readdir when applied to ufs file systems and Darwin 6.5's (and OSX
57    v.10.3.8's) HFS+.  This maximum is conservative in that demonstrating
58    the problem requires a directory containing at least 16 deletable
59    entries (which doesn't count . and ..).
60    This problem also affects Darwin 7.9.0 (aka MacOS X 10.3.9) on HFS+
61    and NFS-mounted file systems, but not vfat ones.  */
62 enum
63   {
64     CONSECUTIVE_READDIR_UNLINK_THRESHOLD = 10
65   };
66
67 /* FIXME: in 2009, or whenever Darwin 7.9.0 (aka MacOS X 10.3.9) is no
68    longer relevant, remove this work-around code.  Then, there will be
69    no need to perform the extra rewinddir call, ever.  */
70 #define NEED_REWIND(readdir_unlink_count) \
71   (CONSECUTIVE_READDIR_UNLINK_THRESHOLD <= (readdir_unlink_count))
72
73 enum Ternary
74   {
75     T_UNKNOWN = 2,
76     T_NO,
77     T_YES
78   };
79 typedef enum Ternary Ternary;
80
81 /* The prompt function may be called twice for a given directory.
82    The first time, we ask whether to descend into it, and the
83    second time, we ask whether to remove it.  */
84 enum Prompt_action
85   {
86     PA_DESCEND_INTO_DIR = 2,
87     PA_REMOVE_DIR
88   };
89
90 /* Initial capacity of per-directory hash table of entries that have
91    been processed but not been deleted.  */
92 enum { HT_UNREMOVABLE_INITIAL_CAPACITY = 13 };
93
94 /* An entry in the active directory stack.
95    Each entry corresponds to an `active' directory.  */
96 struct AD_ent
97 {
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;
103
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;
108
109   /* The directory's dev/ino.  Used to ensure that a malicious user does
110      not replace a directory we're about to process with a symlink to
111      some other directory.  */
112   struct dev_ino dev_ino;
113 };
114
115 extern char *program_name;
116
117 struct dirstack_state
118 {
119   /* The name of the directory (starting with and relative to a command
120      line argument) being processed.  When a subdirectory is entered, a new
121      component is appended (pushed).  Remove (pop) the top component
122      upon chdir'ing out of a directory.  This is used to form the full
123      name of the current directory or a file therein, when necessary.  */
124   struct obstack dir_stack;
125
126   /* Stack of lengths of directory names (including trailing slash)
127      appended to dir_stack.  We have to have a separate stack of lengths
128      (rather than just popping back to previous slash) because the first
129      element pushed onto the dir stack may contain slashes.  */
130   struct obstack len_stack;
131
132   /* Stack of active directory entries.
133      The first `active' directory is the initial working directory.
134      Additional active dirs are pushed onto the stack as we `chdir'
135      into each directory to be processed.  When finished with the
136      hierarchy under a directory, pop the active dir stack.  */
137   struct obstack Active_dir;
138
139   /* Used to detect cycles.  */
140   struct cycle_check_state cycle_check_state;
141
142   /* Target of a longjmp in case rm has to stop processing the current
143      command-line argument.  This happens 1) when rm detects a directory
144      cycle or 2) when it has processed one or more directories, but then
145      is unable to return to the initial working directory to process
146      additional `.'-relative command-line arguments.  */
147   jmp_buf current_arg_jumpbuf;
148 };
149 typedef struct dirstack_state Dirstack_state;
150
151 /* Just like close(fd), but don't modify errno. */
152 static inline int
153 close_preserve_errno (int fd)
154 {
155   int saved_errno = errno;
156   int result = close (fd);
157   errno = saved_errno;
158   return result;
159 }
160
161 /* Like fstatat, but cache the result.  If ST->st_size is -1, the
162    status has not been gotten yet.  If less than -1, fstatat failed
163    with errno == -1 - ST->st_size.  Otherwise, the status has already
164    been gotten, so return 0.  */
165 static int
166 cache_fstatat (int fd, char const *file, struct stat *st, int flag)
167 {
168   if (st->st_size == -1 && fstatat (fd, file, st, flag) != 0)
169     st->st_size = -1 - errno;
170   if (0 <= st->st_size)
171     return 0;
172   errno = -1 - st->st_size;
173   return -1;
174 }
175
176 /* Initialize a fstatat cache *ST.  Return ST for convenience.  */
177 static inline struct stat *
178 cache_stat_init (struct stat *st)
179 {
180   st->st_size = -1;
181   return st;
182 }
183
184 /* Return true if *ST has been statted.  */
185 static inline bool
186 cache_statted (struct stat *st)
187 {
188   return (st->st_size != -1);
189 }
190
191 /* Return true if *ST has been statted successfully.  */
192 static inline bool
193 cache_stat_ok (struct stat *st)
194 {
195   return (0 <= st->st_size);
196 }
197
198
199 static void
200 hash_freer (void *x)
201 {
202   free (x);
203 }
204
205 static bool
206 hash_compare_strings (void const *x, void const *y)
207 {
208   return STREQ (x, y) ? true : false;
209 }
210
211 static inline void
212 push_dir (Dirstack_state *ds, const char *dir_name)
213 {
214   size_t len = strlen (dir_name);
215
216   /* Append the string onto the stack.  */
217   obstack_grow (&ds->dir_stack, dir_name, len);
218
219   /* Append a trailing slash.  */
220   obstack_1grow (&ds->dir_stack, '/');
221
222   /* Add one for the slash.  */
223   ++len;
224
225   /* Push the length (including slash) onto its stack.  */
226   obstack_grow (&ds->len_stack, &len, sizeof (len));
227 }
228
229 /* Return the entry name of the directory on the top of the stack
230    in malloc'd storage.  */
231 static inline char *
232 top_dir (Dirstack_state const *ds)
233 {
234   size_t n_lengths = obstack_object_size (&ds->len_stack) / sizeof (size_t);
235   size_t *length = obstack_base (&ds->len_stack);
236   size_t top_len = length[n_lengths - 1];
237   char const *p = obstack_next_free (&ds->dir_stack) - top_len;
238   char *q = xmalloc (top_len);
239   memcpy (q, p, top_len - 1);
240   q[top_len - 1] = 0;
241   return q;
242 }
243
244 static inline void
245 pop_dir (Dirstack_state *ds)
246 {
247   size_t n_lengths = obstack_object_size (&ds->len_stack) / sizeof (size_t);
248   size_t *length = obstack_base (&ds->len_stack);
249
250   assert (n_lengths > 0);
251   size_t top_len = length[n_lengths - 1];
252   assert (top_len >= 2);
253
254   /* Pop the specified length of file name.  */
255   assert (obstack_object_size (&ds->dir_stack) >= top_len);
256   obstack_blank (&ds->dir_stack, -top_len);
257
258   /* Pop the length stack, too.  */
259   assert (obstack_object_size (&ds->len_stack) >= sizeof (size_t));
260   obstack_blank (&ds->len_stack, -(int) sizeof (size_t));
261 }
262
263 /* Copy the SRC_LEN bytes of data beginning at SRC into the DST_LEN-byte
264    buffer, DST, so that the last source byte is at the end of the destination
265    buffer.  If SRC_LEN is longer than DST_LEN, then set *TRUNCATED.
266    Set *RESULT to point to the beginning of (the portion of) the source data
267    in DST.  Return the number of bytes remaining in the destination buffer.  */
268
269 static size_t
270 right_justify (char *dst, size_t dst_len, const char *src, size_t src_len,
271                char **result, bool *truncated)
272 {
273   const char *sp;
274   char *dp;
275
276   if (src_len <= dst_len)
277     {
278       sp = src;
279       dp = dst + (dst_len - src_len);
280       *truncated = false;
281     }
282   else
283     {
284       sp = src + (src_len - dst_len);
285       dp = dst;
286       src_len = dst_len;
287       *truncated = true;
288     }
289
290   *result = memcpy (dp, sp, src_len);
291   return dst_len - src_len;
292 }
293
294 /* Using the global directory name obstack, create the full name FILENAME.
295    Return it in sometimes-realloc'd space that should not be freed by the
296    caller.  Realloc as necessary.  If realloc fails, use a static buffer
297    and put as long a suffix in that buffer as possible.  */
298
299 #define full_filename(Filename) full_filename_ (ds, Filename)
300 static char *
301 full_filename_ (Dirstack_state const *ds, const char *filename)
302 {
303   static char *buf = NULL;
304   static size_t n_allocated = 0;
305
306   size_t dir_len = obstack_object_size (&ds->dir_stack);
307   char *dir_name = obstack_base (&ds->dir_stack);
308   size_t n_bytes_needed;
309   size_t filename_len;
310
311   filename_len = strlen (filename);
312   n_bytes_needed = dir_len + filename_len + 1;
313
314   if (n_allocated < n_bytes_needed)
315     {
316       /* This code requires that realloc accept NULL as the first arg.
317          This function must not use xrealloc.  Otherwise, an out-of-memory
318          error involving a file name to be expanded here wouldn't ever
319          be issued.  Use realloc and fall back on using a static buffer
320          if memory allocation fails.  */
321       char *new_buf = realloc (buf, n_bytes_needed);
322       n_allocated = n_bytes_needed;
323
324       if (new_buf == NULL)
325         {
326 #define SBUF_SIZE 512
327 #define ELLIPSES_PREFIX "[...]"
328           static char static_buf[SBUF_SIZE];
329           bool truncated;
330           size_t len;
331           char *p;
332
333           free (buf);
334           len = right_justify (static_buf, SBUF_SIZE, filename,
335                                filename_len + 1, &p, &truncated);
336           right_justify (static_buf, len, dir_name, dir_len, &p, &truncated);
337           if (truncated)
338             {
339               memcpy (static_buf, ELLIPSES_PREFIX,
340                       sizeof (ELLIPSES_PREFIX) - 1);
341             }
342           return p;
343         }
344
345       buf = new_buf;
346     }
347
348   if (filename_len == 1 && *filename == '.' && dir_len)
349     {
350       /* FILENAME is just `.' and dir_len is nonzero.
351          Copy the directory part, omitting the trailing slash,
352          and append a trailing zero byte.  */
353       char *p = mempcpy (buf, dir_name, dir_len - 1);
354       *p = 0;
355     }
356   else
357     {
358       /* Copy the directory part, including trailing slash, and then
359          append the filename part, including a trailing zero byte.  */
360       memcpy (mempcpy (buf, dir_name, dir_len), filename, filename_len + 1);
361       assert (strlen (buf) + 1 == n_bytes_needed);
362     }
363
364   return buf;
365 }
366
367 static inline size_t
368 AD_stack_height (Dirstack_state const *ds)
369 {
370   return obstack_object_size (&ds->Active_dir) / sizeof (struct AD_ent);
371 }
372
373 static inline struct AD_ent *
374 AD_stack_top (Dirstack_state const *ds)
375 {
376   return (struct AD_ent *)
377     ((char *) obstack_next_free (&ds->Active_dir) - sizeof (struct AD_ent));
378 }
379
380 static void
381 AD_stack_pop (Dirstack_state *ds)
382 {
383   assert (0 < AD_stack_height (ds));
384
385   /* operate on Active_dir.  pop and free top entry */
386   struct AD_ent *top = AD_stack_top (ds);
387   if (top->unremovable)
388     hash_free (top->unremovable);
389   obstack_blank (&ds->Active_dir, -(int) sizeof (struct AD_ent));
390 }
391
392 static void
393 AD_stack_clear (Dirstack_state *ds)
394 {
395   while (0 < AD_stack_height (ds))
396     {
397       AD_stack_pop (ds);
398     }
399 }
400
401 static Dirstack_state *
402 ds_init (void)
403 {
404   Dirstack_state *ds = xmalloc (sizeof *ds);
405   obstack_init (&ds->dir_stack);
406   obstack_init (&ds->len_stack);
407   obstack_init (&ds->Active_dir);
408   return ds;
409 }
410
411 static void
412 ds_clear (Dirstack_state *ds)
413 {
414   obstack_free (&ds->dir_stack, obstack_finish (&ds->dir_stack));
415   obstack_free (&ds->len_stack, obstack_finish (&ds->len_stack));
416   while (0 < AD_stack_height (ds))
417     AD_stack_pop (ds);
418   obstack_free (&ds->Active_dir, obstack_finish (&ds->Active_dir));
419 }
420
421 static void
422 ds_free (Dirstack_state *ds)
423 {
424   obstack_free (&ds->dir_stack, NULL);
425   obstack_free (&ds->len_stack, NULL);
426   obstack_free (&ds->Active_dir, NULL);
427   free (ds);
428 }
429
430 /* Pop the active directory (AD) stack and move *DIRP `up' one level,
431    safely.  Moving `up' usually means opening `..', but when we've just
432    finished recursively processing a command-line directory argument,
433    there's nothing left on the stack, so set *DIRP to NULL in that case.
434    The idea is to return with *DIRP opened on the parent directory,
435    assuming there are entries in that directory that we need to remove.
436
437    Whenever using chdir '..' (virtually, now, via openat), verify
438    that the post-chdir dev/ino numbers for `.' match the saved ones.
439    If any system call fails or if dev/ino don't match then give a
440    diagnostic and longjump out.
441    Return the name (in malloc'd storage) of the
442    directory (usually now empty) from which we're coming, and which
443    corresponds to the input value of *DIRP.  */
444 static char *
445 AD_pop_and_chdir (DIR **dirp, Dirstack_state *ds)
446 {
447   struct AD_ent *leaf_dir_ent = AD_stack_top(ds);
448   struct dev_ino leaf_dev_ino = leaf_dir_ent->dev_ino;
449   enum RM_status old_status = leaf_dir_ent->status;
450   struct AD_ent *top;
451
452   /* Get the name of the current (but soon to be `previous') directory
453      from the top of the stack.  */
454   char *prev_dir = top_dir (ds);
455
456   AD_stack_pop (ds);
457   pop_dir (ds);
458   top = AD_stack_top (ds);
459
460   /* If the directory we're about to leave (and try to rmdir)
461      is the one whose dev_ino is being used to detect a cycle,
462      reset cycle_check_state.dev_ino to that of the parent.
463      Otherwise, once that directory is removed, its dev_ino
464      could be reused in the creation (by some other process)
465      of a directory that this rm process would encounter,
466      which would result in a false-positive cycle indication.  */
467   CYCLE_CHECK_REFLECT_CHDIR_UP (&ds->cycle_check_state,
468                                 top->dev_ino, leaf_dev_ino);
469
470   /* Propagate any failure to parent.  */
471   UPDATE_STATUS (top->status, old_status);
472
473   assert (AD_stack_height (ds));
474
475   if (1 < AD_stack_height (ds))
476     {
477       struct stat sb;
478       int fd = openat (dirfd (*dirp), "..", O_RDONLY);
479       if (closedir (*dirp) != 0)
480         {
481           error (0, errno, _("FATAL: failed to close directory %s"),
482                  quote (full_filename (prev_dir)));
483           goto next_cmdline_arg;
484         }
485
486       /* The above fails with EACCES when *DIRP is readable but not
487          searchable, when using Solaris' openat.  Without this openat
488          call, tests/rm2 would fail to remove directories a/2 and a/3.  */
489       if (fd < 0)
490         fd = openat (AT_FDCWD, full_filename ("."), O_RDONLY);
491
492       if (fd < 0)
493         {
494           error (0, errno, _("FATAL: cannot open .. from %s"),
495                  quote (full_filename (prev_dir)));
496           goto next_cmdline_arg;
497         }
498
499       if (fstat (fd, &sb))
500         {
501           error (0, errno,
502                  _("FATAL: cannot ensure %s (returned to via ..) is safe"),
503                  quote (full_filename (".")));
504           goto close_and_next;
505         }
506
507       /*  Ensure that post-chdir dev/ino match the stored ones.  */
508       if ( ! SAME_INODE (sb, top->dev_ino))
509         {
510           error (0, 0, _("FATAL: directory %s changed dev/ino"),
511                  quote (full_filename (".")));
512           goto close_and_next;
513         }
514
515       *dirp = fdopendir (fd);
516       if (*dirp == NULL)
517         {
518           error (0, errno, _("FATAL: cannot return to .. from %s"),
519                  quote (full_filename (".")));
520
521         close_and_next:;
522           close (fd);
523
524         next_cmdline_arg:;
525           free (prev_dir);
526           longjmp (ds->current_arg_jumpbuf, 1);
527         }
528     }
529   else
530     {
531       if (closedir (*dirp) != 0)
532         {
533           error (0, errno, _("FATAL: failed to close directory %s"),
534                  quote (full_filename (prev_dir)));
535           goto next_cmdline_arg;
536         }
537       *dirp = NULL;
538     }
539
540   return prev_dir;
541 }
542
543 /* Initialize *HT if it is NULL.  Return *HT.  */
544 static Hash_table *
545 AD_ensure_initialized (Hash_table **ht)
546 {
547   if (*ht == NULL)
548     {
549       *ht = hash_initialize (HT_UNREMOVABLE_INITIAL_CAPACITY, NULL, hash_pjw,
550                              hash_compare_strings, hash_freer);
551       if (*ht == NULL)
552         xalloc_die ();
553     }
554
555   return *ht;
556 }
557
558 /* Initialize *HT if it is NULL.
559    Insert FILENAME into HT.  */
560 static void
561 AD_mark_helper (Hash_table **ht, char *filename)
562 {
563   void *ent = hash_insert (AD_ensure_initialized (ht), filename);
564   if (ent == NULL)
565     xalloc_die ();
566   else
567     {
568       if (ent != filename)
569         free (filename);
570     }
571 }
572
573 /* Mark FILENAME (in current directory) as unremovable.  */
574 static void
575 AD_mark_as_unremovable (Dirstack_state *ds, char const *filename)
576 {
577   AD_mark_helper (&AD_stack_top(ds)->unremovable, xstrdup (filename));
578 }
579
580 /* Mark the current directory as unremovable.  I.e., mark the entry
581    in the parent directory corresponding to `.'.
582    This happens e.g., when an opendir fails and the only name
583    the caller has conveniently at hand is `.'.  */
584 static void
585 AD_mark_current_as_unremovable (Dirstack_state *ds)
586 {
587   struct AD_ent *top = AD_stack_top (ds);
588   char *curr = top_dir (ds);
589
590   assert (1 < AD_stack_height (ds));
591
592   --top;
593   AD_mark_helper (&top->unremovable, curr);
594 }
595
596 /* Push an initial dummy entry onto the stack.
597    This will always be the bottommost entry on the stack.  */
598 static void
599 AD_push_initial (Dirstack_state *ds)
600 {
601   struct AD_ent *top;
602
603   /* Extend the stack.  */
604   obstack_blank (&ds->Active_dir, sizeof (struct AD_ent));
605
606   /* Fill in the new values.  */
607   top = AD_stack_top (ds);
608   top->unremovable = NULL;
609
610   /* These should never be used.
611      Give them values that might look suspicious
612      in a debugger or in a diagnostic.  */
613   top->dev_ino.st_dev = TYPE_MAXIMUM (dev_t);
614   top->dev_ino.st_ino = TYPE_MAXIMUM (ino_t);
615 }
616
617 /* Push info about the current working directory (".") onto the
618    active directory stack.  DIR is the ./-relative name through
619    which we've just `chdir'd to this directory.  DIR_SB_FROM_PARENT
620    is the result of calling lstat on DIR from the parent of DIR.
621    Longjump out (skipping the entire command line argument we're
622    dealing with) if `fstat (FD_CWD, ...' fails or if someone has
623    replaced DIR with e.g., a symlink to some other directory.  */
624 static void
625 AD_push (int fd_cwd, Dirstack_state *ds, char const *dir,
626          struct stat const *dir_sb_from_parent)
627 {
628   struct AD_ent *top;
629
630   push_dir (ds, dir);
631
632   /* If our uses of openat are guaranteed not to
633      follow a symlink, then we can skip this check.  */
634   if (! HAVE_WORKING_O_NOFOLLOW)
635     {
636       struct stat sb;
637       if (fstat (fd_cwd, &sb) != 0)
638         {
639           error (0, errno, _("FATAL: cannot enter directory %s"),
640                  quote (full_filename (".")));
641           longjmp (ds->current_arg_jumpbuf, 1);
642         }
643
644       if ( ! SAME_INODE (sb, *dir_sb_from_parent))
645         {
646           error (0, 0,
647                  _("FATAL: just-changed-to directory %s changed dev/ino"),
648                  quote (full_filename (".")));
649           longjmp (ds->current_arg_jumpbuf, 1);
650         }
651     }
652
653   if (cycle_check (&ds->cycle_check_state, dir_sb_from_parent))
654     {
655       error (0, 0, _("\
656 WARNING: Circular directory structure.\n\
657 This almost certainly means that you have a corrupted file system.\n\
658 NOTIFY YOUR SYSTEM MANAGER.\n\
659 The following directory is part of the cycle:\n  %s\n"),
660              quote (full_filename (".")));
661       longjmp (ds->current_arg_jumpbuf, 1);
662     }
663
664   /* Extend the stack.  */
665   obstack_blank (&ds->Active_dir, sizeof (struct AD_ent));
666
667   /* The active directory stack must be one larger than the length stack.  */
668   assert (AD_stack_height (ds) ==
669           1 + obstack_object_size (&ds->len_stack) / sizeof (size_t));
670
671   /* Fill in the new values.  */
672   top = AD_stack_top (ds);
673   top->dev_ino.st_dev = dir_sb_from_parent->st_dev;
674   top->dev_ino.st_ino = dir_sb_from_parent->st_ino;
675   top->unremovable = NULL;
676 }
677
678 static inline bool
679 AD_is_removable (Dirstack_state const *ds, char const *file)
680 {
681   struct AD_ent *top = AD_stack_top (ds);
682   return ! (top->unremovable && hash_lookup (top->unremovable, file));
683 }
684
685 /* Return true if DIR is determined to be an empty directory.  */
686 static bool
687 is_empty_dir (int fd_cwd, char const *dir)
688 {
689   DIR *dirp;
690   struct dirent const *dp;
691   int saved_errno;
692   int fd = openat (fd_cwd, dir,
693                    (O_RDONLY | O_DIRECTORY
694                     | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK));
695
696   if (fd < 0)
697     return false;
698
699   dirp = fdopendir (fd);
700   if (dirp == NULL)
701     {
702       close (fd);
703       return false;
704     }
705
706   errno = 0;
707   dp = readdir_ignoring_dot_and_dotdot (dirp);
708   saved_errno = errno;
709   closedir (dirp);
710   if (dp != NULL)
711     return false;
712   return saved_errno == 0 ? true : false;
713 }
714
715 /* Return true if FILE is determined to be an unwritable non-symlink.
716    Otherwise, return false (including when lstat'ing it fails).
717    Set *BUF to the file status.
718    This is to avoid calling euidaccess when FILE is a symlink.  */
719 static bool
720 write_protected_non_symlink (int fd_cwd,
721                              char const *file,
722                              Dirstack_state const *ds,
723                              struct stat *buf)
724 {
725   if (cache_fstatat (fd_cwd, file, buf, AT_SYMLINK_NOFOLLOW) != 0)
726     return false;
727   if (S_ISLNK (buf->st_mode))
728     return false;
729   /* Here, we know FILE is not a symbolic link.  */
730
731   /* In order to be reentrant -- i.e., to avoid changing the working
732      directory, and at the same time to be able to deal with alternate
733      access control mechanisms (ACLs, xattr-style attributes) and
734      arbitrarily deep trees -- we need a function like eaccessat, i.e.,
735      like Solaris' eaccess, but fd-relative, in the spirit of openat.  */
736
737   /* In the absence of a native eaccessat function, here are some of
738      the implementation choices [#4 and #5 were suggested by Paul Eggert]:
739      1) call openat with O_WRONLY|O_NOCTTY
740         Disadvantage: may create the file and doesn't work for directory,
741         may mistakenly report `unwritable' for EROFS or ACLs even though
742         perm bits say the file is writable.
743
744      2) fake eaccessat (save_cwd, fchdir, call euidaccess, restore_cwd)
745         Disadvantage: changes working directory (not reentrant) and can't
746         work if save_cwd fails.
747
748      3) if (euidaccess (full_filename (file), W_OK) == 0)
749         Disadvantage: doesn't work if full_filename is too long.
750         Inefficient for very deep trees (O(Depth^2)).
751
752      4) If the full pathname is sufficiently short (say, less than
753         PATH_MAX or 8192 bytes, whichever is shorter):
754         use method (3) (i.e., euidaccess (full_filename (file), W_OK));
755         Otherwise: vfork, fchdir in the child, run euidaccess in the
756         child, then the child exits with a status that tells the parent
757         whether euidaccess succeeded.
758
759         This avoids the O(N**2) algorithm of method (3), and it also avoids
760         the failure-due-to-too-long-file-names of method (3), but it's fast
761         in the normal shallow case.  It also avoids the lack-of-reentrancy
762         and the save_cwd problems.
763         Disadvantage; it uses a process slot for very-long file names,
764         and would be very slow for hierarchies with many such files.
765
766      5) If the full file name is sufficiently short (say, less than
767         PATH_MAX or 8192 bytes, whichever is shorter):
768         use method (3) (i.e., euidaccess (full_filename (file), W_OK));
769         Otherwise: look just at the file bits.  Perhaps issue a warning
770         the first time this occurs.
771
772         This is like (4), except for the "Otherwise" case where it isn't as
773         "perfect" as (4) but is considerably faster.  It conforms to current
774         POSIX, and is uniformly better than what Solaris and FreeBSD do (they
775         mess up with long file names). */
776
777   {
778     /* This implements #5: */
779     size_t file_name_len
780       = obstack_object_size (&ds->dir_stack) + strlen (file);
781
782     return (file_name_len < MIN (PATH_MAX, 8192)
783             ? euidaccess (full_filename (file), W_OK) != 0 && errno == EACCES
784             : euidaccess_stat (buf, W_OK) != 0);
785   }
786 }
787
788 /* Prompt whether to remove FILENAME, if required via a combination of
789    the options specified by X and/or file attributes.  If the file may
790    be removed, return RM_OK.  If the user declines to remove the file,
791    return RM_USER_DECLINED.  If not ignoring missing files and we
792    cannot lstat FILENAME, then return RM_ERROR.
793
794    Depending on MODE, ask whether to `descend into' or to `remove' the
795    directory FILENAME.  MODE is ignored when FILENAME is not a directory.
796    Set *IS_EMPTY to T_YES if FILENAME is an empty directory, and it is
797    appropriate to try to remove it with rmdir (e.g. recursive mode).
798    Don't even try to set *IS_EMPTY when MODE == PA_REMOVE_DIR.  */
799 static enum RM_status
800 prompt (int fd_cwd, Dirstack_state const *ds, char const *filename,
801         struct stat *sbuf,
802         struct rm_options const *x, enum Prompt_action mode,
803         Ternary *is_empty)
804 {
805   bool write_protected = false;
806
807   *is_empty = T_UNKNOWN;
808
809   if (((!x->ignore_missing_files & (x->interactive | x->stdin_tty))
810        && (write_protected = write_protected_non_symlink (fd_cwd, filename,
811                                                           ds, sbuf)))
812       || x->interactive)
813     {
814       if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) != 0)
815         {
816           /* This happens, e.g., with `rm '''.  */
817           error (0, errno, _("cannot remove %s"),
818                  quote (full_filename (filename)));
819           return RM_ERROR;
820         }
821
822       if (S_ISDIR (sbuf->st_mode) && !x->recursive)
823         {
824           error (0, EISDIR, _("cannot remove %s"),
825                  quote (full_filename (filename)));
826           return RM_ERROR;
827         }
828
829       /* Using permissions doesn't make sense for symlinks.  */
830       if (S_ISLNK (sbuf->st_mode))
831         {
832           if ( ! x->interactive)
833             return RM_OK;
834           write_protected = false;
835         }
836
837       /* Issue the prompt.  */
838       {
839         char const *quoted_name = quote (full_filename (filename));
840
841         /* FIXME: use a variant of error (instead of fprintf) that doesn't
842            append a newline.  Then we won't have to declare program_name in
843            this file.  */
844         if (S_ISDIR (sbuf->st_mode)
845             && x->recursive
846             && mode == PA_DESCEND_INTO_DIR
847             && ((*is_empty = (is_empty_dir (fd_cwd, filename) ? T_YES : T_NO))
848                 == T_NO))
849           fprintf (stderr,
850                    (write_protected
851                     ? _("%s: descend into write-protected directory %s? ")
852                     : _("%s: descend into directory %s? ")),
853                    program_name, quoted_name);
854         else
855           {
856             /* TRANSLATORS: You may find it more convenient to translate
857                the equivalent of _("%s: remove %s (write-protected) %s? ").
858                It should avoid grammatical problems with the output
859                of file_type.  */
860             fprintf (stderr,
861                      (write_protected
862                       ? _("%s: remove write-protected %s %s? ")
863                       : _("%s: remove %s %s? ")),
864                      program_name, file_type (sbuf), quoted_name);
865           }
866
867         if (!yesno ())
868           return RM_USER_DECLINED;
869       }
870     }
871   return RM_OK;
872 }
873
874 /* Return true if FILENAME is a directory (and not a symlink to a directory).
875    Otherwise, including the case in which lstat fails, return false.
876    *ST is FILENAME's tstatus.
877    Do not modify errno.  */
878 static inline bool
879 is_dir_lstat (char const *filename, struct stat *st)
880 {
881   int saved_errno = errno;
882   bool is_dir =
883     (cache_fstatat (AT_FDCWD, filename, st, AT_SYMLINK_NOFOLLOW) == 0
884      && S_ISDIR (st->st_mode));
885   errno = saved_errno;
886   return is_dir;
887 }
888
889 #if HAVE_STRUCT_DIRENT_D_TYPE
890
891 /* True if the type of the directory entry D is known.  */
892 # define DT_IS_KNOWN(d) ((d)->d_type != DT_UNKNOWN)
893
894 /* True if the type of the directory entry D must be T.  */
895 # define DT_MUST_BE(d, t) ((d)->d_type == (t))
896
897 #else
898 # define DT_IS_KNOWN(d) false
899 # define DT_MUST_BE(d, t) false
900 #endif
901
902 #define DO_UNLINK(Fd_cwd, Filename, X)                                  \
903   do                                                                    \
904     {                                                                   \
905       if (unlinkat (Fd_cwd, Filename, 0) == 0)                          \
906         {                                                               \
907           if ((X)->verbose)                                             \
908             printf (_("removed %s\n"), quote (full_filename (Filename))); \
909           return RM_OK;                                                 \
910         }                                                               \
911                                                                         \
912       if (ignorable_missing (X, errno))                                 \
913         return RM_OK;                                                   \
914     }                                                                   \
915   while (0)
916
917 #define DO_RMDIR(Fd_cwd, Filename, X)                   \
918   do                                                    \
919     {                                                   \
920       if (unlinkat (Fd_cwd, Filename, AT_REMOVEDIR) == 0) /* rmdir */ \
921         {                                               \
922           if ((X)->verbose)                             \
923             printf (_("removed directory: %s\n"),       \
924                     quote (full_filename (Filename)));  \
925           return RM_OK;                                 \
926         }                                               \
927                                                         \
928       if (ignorable_missing (X, errno))                 \
929         return RM_OK;                                   \
930                                                         \
931       if (errno == ENOTEMPTY || errno == EEXIST)        \
932         return RM_NONEMPTY_DIR;                         \
933     }                                                   \
934   while (0)
935
936 /* When a function like unlink, rmdir, or fstatat fails with an errno
937    value of ERRNUM, return true if the specified file system object
938    is guaranteed not to exist;  otherwise, return false.  */
939 static inline bool
940 nonexistent_file_errno (int errnum)
941 {
942   /* Do not include ELOOP here, since the specified file may indeed
943      exist, but be (in)accessible only via too long a symlink chain.
944      Likewise for ENAMETOOLONG, since rm -f ./././.../foo may fail
945      if the "..." part expands to a long enough sequence of "./"s,
946      even though ./foo does indeed exist.  */
947
948   switch (errnum)
949     {
950     case ENOENT:
951     case ENOTDIR:
952       return true;
953     default:
954       return false;
955     }
956 }
957
958 /* Encapsulate the test for whether the errno value, ERRNUM, is ignorable.  */
959 static inline bool
960 ignorable_missing (struct rm_options const *x, int errnum)
961 {
962   return x->ignore_missing_files && nonexistent_file_errno (errnum);
963 }
964
965 /* Remove the file or directory specified by FILENAME.
966    Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
967    But if FILENAME specifies a non-empty directory, return RM_NONEMPTY_DIR. */
968
969 static enum RM_status
970 remove_entry (int fd_cwd, Dirstack_state const *ds, char const *filename,
971               struct stat *st,
972               struct rm_options const *x, struct dirent const *dp)
973 {
974   Ternary is_empty_directory;
975   enum RM_status s = prompt (fd_cwd, ds, filename, st, x, PA_DESCEND_INTO_DIR,
976                              &is_empty_directory);
977   bool known_to_be_dir = (cache_stat_ok (st) && S_ISDIR (st->st_mode));
978
979   if (s != RM_OK)
980     return s;
981
982   /* Why bother with the following if/else block?  Because on systems with
983      an unlink function that *can* unlink directories, we must determine the
984      type of each entry before removing it.  Otherwise, we'd risk unlinking
985      an entire directory tree simply by unlinking a single directory;  then
986      all the storage associated with that hierarchy would not be freed until
987      the next fsck.  Not nice.  To avoid that, on such slightly losing
988      systems, we need to call lstat to determine the type of each entry,
989      and that represents extra overhead that -- it turns out -- we can
990      avoid on non-losing systems, since there, unlink will never remove
991      a directory.  Also, on systems where unlink may unlink directories,
992      we're forced to allow a race condition: we lstat a non-directory, then
993      go to unlink it, but in the mean time, a malicious someone could have
994      replaced it with a directory.  */
995
996   if (cannot_unlink_dir ())
997     {
998       if (known_to_be_dir && ! x->recursive)
999         {
1000           error (0, EISDIR, _("cannot remove %s"),
1001                  quote (full_filename (filename)));
1002           return RM_ERROR;
1003         }
1004
1005       /* is_empty_directory is set iff it's ok to use rmdir.
1006          Note that it's set only in interactive mode -- in which case it's
1007          an optimization that arranges so that the user is asked just
1008          once whether to remove the directory.  */
1009       if (is_empty_directory == T_YES)
1010         DO_RMDIR (fd_cwd, filename, x);
1011
1012       /* If we happen to know that FILENAME is a directory, return now
1013          and let the caller remove it -- this saves the overhead of a failed
1014          unlink call.  If FILENAME is a command-line argument, then dp is NULL,
1015          so we'll first try to unlink it.  Using unlink here is ok, because it
1016          cannot remove a directory.  */
1017       if ((dp && DT_MUST_BE (dp, DT_DIR)) || known_to_be_dir)
1018         return RM_NONEMPTY_DIR;
1019
1020       DO_UNLINK (fd_cwd, filename, x);
1021
1022       /* Upon a failed attempt to unlink a directory, most non-Linux systems
1023          set errno to the POSIX-required value EPERM.  In that case, change
1024          errno to EISDIR so that we emit a better diagnostic.  */
1025       if (! x->recursive && errno == EPERM && is_dir_lstat (filename, st))
1026         errno = EISDIR;
1027
1028       if (! x->recursive
1029           || errno == ENOENT || errno == ENOTDIR
1030           || errno == ELOOP || errno == ENAMETOOLONG)
1031         {
1032           if (ignorable_missing (x, errno))
1033             return RM_OK;
1034
1035           /* Either --recursive is not in effect, or the file cannot be a
1036              directory.  Report the unlink problem and fail.  */
1037           error (0, errno, _("cannot remove %s"),
1038                  quote (full_filename (filename)));
1039           return RM_ERROR;
1040         }
1041     }
1042   else
1043     {
1044       /* If we don't already know whether FILENAME is a directory,
1045          find out now.  Then, if it's a non-directory, we can use
1046          unlink on it.  */
1047       bool is_dir;
1048
1049       if (cache_statted (st))
1050         is_dir = known_to_be_dir;
1051       else
1052         {
1053           if (dp && DT_IS_KNOWN (dp))
1054             is_dir = DT_MUST_BE (dp, DT_DIR);
1055           else
1056             {
1057               if (fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW))
1058                 {
1059                   if (ignorable_missing (x, errno))
1060                     return RM_OK;
1061
1062                   error (0, errno, _("cannot remove %s"),
1063                          quote (full_filename (filename)));
1064                   return RM_ERROR;
1065                 }
1066
1067               is_dir = !! S_ISDIR (st->st_mode);
1068             }
1069         }
1070
1071       if (! is_dir)
1072         {
1073           /* At this point, barring race conditions, FILENAME is known
1074              to be a non-directory, so it's ok to try to unlink it.  */
1075           DO_UNLINK (fd_cwd, filename, x);
1076
1077           /* unlink failed with some other error code.  report it.  */
1078           error (0, errno, _("cannot remove %s"),
1079                  quote (full_filename (filename)));
1080           return RM_ERROR;
1081         }
1082
1083       if (! x->recursive)
1084         {
1085           error (0, EISDIR, _("cannot remove %s"),
1086                  quote (full_filename (filename)));
1087           return RM_ERROR;
1088         }
1089
1090       if (is_empty_directory == T_YES)
1091         {
1092           DO_RMDIR (fd_cwd, filename, x);
1093           /* Don't diagnose any failure here.
1094              It'll be detected when the caller tries another way.  */
1095         }
1096     }
1097
1098   return RM_NONEMPTY_DIR;
1099 }
1100
1101 /* Given FD_CWD, the file descriptor for an open directory,
1102    open its subdirectory F (F is already `known' to be a directory,
1103    so if it is no longer one, someone is playing games), return a DIR*
1104    pointer for F, and put F's `stat' data in *SUBDIR_SB.
1105    Upon failure give a diagnostic and return NULL.
1106    If PREV_ERRNO is nonzero, it is the errno value from a preceding failed
1107    unlink- or rmdir-like system call -- use that value instead of ENOTDIR
1108    if an opened file turns out not to be a directory.  This is important
1109    when the preceding non-dir-unlink failed due to e.g., EPERM or EACCES.
1110    The caller must use a nonnnull CWD_ERRNO the first
1111    time this function is called for each command-line-specified directory.
1112    If CWD_ERRNO is not null, set *CWD_ERRNO to the appropriate error number
1113    if this function fails to restore the initial working directory.
1114    If it is null, report an error and exit if the working directory
1115    isn't restored.  */
1116 static DIR *
1117 fd_to_subdirp (int fd_cwd, char const *f,
1118                struct rm_options const *x, int prev_errno,
1119                struct stat *subdir_sb, Dirstack_state *ds,
1120                int *cwd_errno ATTRIBUTE_UNUSED)
1121 {
1122   int open_flags = O_RDONLY | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK;
1123   int fd_sub = openat_permissive (fd_cwd, f, open_flags, 0, cwd_errno);
1124
1125   /* Record dev/ino of F.  We may compare them against saved values
1126      to thwart any attempt to subvert the traversal.  They are also used
1127      to detect directory cycles.  */
1128   if (fd_sub < 0 || fstat (fd_sub, subdir_sb) != 0)
1129     {
1130       if (0 <= fd_sub)
1131         close_preserve_errno (fd_sub);
1132       return NULL;
1133     }
1134
1135   if (! S_ISDIR (subdir_sb->st_mode))
1136     {
1137       errno = prev_errno ? prev_errno : ENOTDIR;
1138       close_preserve_errno (fd_sub);
1139       return NULL;
1140     }
1141
1142   DIR *subdir_dirp = fdopendir (fd_sub);
1143   if (subdir_dirp == NULL)
1144     {
1145       close_preserve_errno (fd_sub);
1146       return NULL;
1147     }
1148
1149   return subdir_dirp;
1150 }
1151
1152 /* Remove entries in the directory open on DIRP
1153    Upon finding a directory that is both non-empty and that can be chdir'd
1154    into, return RM_OK and set *SUBDIR and fill in SUBDIR_SB, where
1155    SUBDIR is the malloc'd name of the subdirectory if the chdir succeeded,
1156    NULL otherwise (e.g., if opendir failed or if there was no subdirectory).
1157    Likewise, SUBDIR_SB is the result of calling lstat on SUBDIR.
1158    Return RM_OK if all entries are removed.  Return RM_ERROR if any
1159    entry cannot be removed.  Otherwise, return RM_USER_DECLINED if
1160    the user declines to remove at least one entry.  Remove as much as
1161    possible, continuing even if we fail to remove some entries.  */
1162 static enum RM_status
1163 remove_cwd_entries (DIR **dirp,
1164                     Dirstack_state *ds, char **subdir, struct stat *subdir_sb,
1165                     struct rm_options const *x)
1166 {
1167   struct AD_ent *top = AD_stack_top (ds);
1168   enum RM_status status = top->status;
1169   size_t n_unlinked_since_opendir_or_last_rewind = 0;
1170
1171   assert (VALID_STATUS (status));
1172   *subdir = NULL;
1173
1174   while (1)
1175     {
1176       struct dirent const *dp;
1177       enum RM_status tmp_status;
1178       const char *f;
1179
1180       /* Set errno to zero so we can distinguish between a readdir failure
1181          and when readdir simply finds that there are no more entries.  */
1182       errno = 0;
1183       dp = readdir_ignoring_dot_and_dotdot (*dirp);
1184       if (dp == NULL)
1185         {
1186           if (errno)
1187             {
1188               /* fall through */
1189             }
1190           else if (NEED_REWIND (n_unlinked_since_opendir_or_last_rewind))
1191             {
1192               /* Call rewinddir if we've called unlink or rmdir so many times
1193                  (since the opendir or the previous rewinddir) that this
1194                  NULL-return may be the symptom of a buggy readdir.  */
1195               rewinddir (*dirp);
1196               n_unlinked_since_opendir_or_last_rewind = 0;
1197               continue;
1198             }
1199           break;
1200         }
1201
1202       f = dp->d_name;
1203
1204       /* Skip files we've already tried/failed to remove.  */
1205       if ( ! AD_is_removable (ds, f))
1206         continue;
1207
1208       /* Pass dp->d_type info to remove_entry so the non-glibc
1209          case can decide whether to use unlink or chdir.
1210          Systems without the d_type member will have to endure
1211          the performance hit of first calling lstat F. */
1212       cache_stat_init (subdir_sb);
1213       tmp_status = remove_entry (dirfd (*dirp), ds, f, subdir_sb, x, dp);
1214       switch (tmp_status)
1215         {
1216         case RM_OK:
1217           /* Count how many files we've unlinked since the initial
1218              opendir or the last rewinddir.  On buggy systems, if you
1219              remove too many, readdir returns NULL even though there
1220              remain unprocessed directory entries.  */
1221           ++n_unlinked_since_opendir_or_last_rewind;
1222           break;
1223
1224         case RM_ERROR:
1225         case RM_USER_DECLINED:
1226           AD_mark_as_unremovable (ds, f);
1227           UPDATE_STATUS (status, tmp_status);
1228           break;
1229
1230         case RM_NONEMPTY_DIR:
1231           {
1232             DIR *subdir_dirp = fd_to_subdirp (dirfd (*dirp), f,
1233                                               x, errno, subdir_sb, ds, NULL);
1234             if (subdir_dirp == NULL)
1235               {
1236                 status = RM_ERROR;
1237
1238                 /* CAUTION: this test and diagnostic are identical to
1239                    those following the other use of fd_to_subdirp.  */
1240                 if (ignorable_missing (x, errno))
1241                   {
1242                     /* With -f, don't report "file not found".  */
1243                   }
1244                 else
1245                   {
1246                     /* Upon fd_to_subdirp failure, try to remove F directly,
1247                        in case it's just an empty directory.  */
1248                     int saved_errno = errno;
1249                     if (unlinkat (dirfd (*dirp), f, AT_REMOVEDIR) == 0)
1250                       status = RM_OK;
1251                     else
1252                       error (0, saved_errno,
1253                              _("cannot remove %s"), quote (full_filename (f)));
1254                   }
1255
1256                 if (status == RM_ERROR)
1257                   AD_mark_as_unremovable (ds, f);
1258                 break;
1259               }
1260
1261             *subdir = xstrdup (f);
1262             if (closedir (*dirp) != 0)
1263               {
1264                 error (0, 0, _("failed to close directory %s"),
1265                        quote (full_filename (".")));
1266                 status = RM_ERROR;
1267               }
1268             *dirp = subdir_dirp;
1269
1270             break;
1271           }
1272         }
1273
1274       /* Record status for this directory.  */
1275       UPDATE_STATUS (top->status, status);
1276
1277       if (*subdir)
1278         break;
1279     }
1280
1281   /* Ensure that *dirp is not NULL and that its file descriptor is valid.  */
1282   assert (*dirp != NULL);
1283   assert (0 <= fcntl (dirfd (*dirp), F_GETFD));
1284
1285   return status;
1286 }
1287
1288 /* Do this after each call to AD_push or AD_push_initial.
1289    Because the status = RM_OK bit is too remove-specific to
1290    go into the general-purpose AD_* package.  */
1291 #define AD_INIT_OTHER_MEMBERS()                 \
1292   do                                            \
1293     {                                           \
1294       AD_stack_top(ds)->status = RM_OK;         \
1295     }                                           \
1296   while (0)
1297
1298 /*  Remove the hierarchy rooted at DIR.
1299     Do that by changing into DIR, then removing its contents, then
1300     returning to the original working directory and removing DIR itself.
1301     Don't use recursion.  Be careful when using chdir ".." that we
1302     return to the same directory from which we came, if necessary.
1303     Return an RM_status value to indicate success or failure.  */
1304
1305 static enum RM_status
1306 remove_dir (int fd_cwd, Dirstack_state *ds, char const *dir,
1307             struct stat *dir_st,
1308             struct rm_options const *x, int *cwd_errno)
1309 {
1310   enum RM_status status;
1311   dev_t current_dev = dir_st->st_dev;
1312
1313   /* There is a race condition in that an attacker could replace the nonempty
1314      directory, DIR, with a symlink between the preceding call to rmdir
1315      (unlinkat, in our caller) and fd_to_subdirp's openat call.  But on most
1316      systems, even those without openat, this isn't a problem, since we ensure
1317      that opening a symlink will fail, when that is possible.  Otherwise,
1318      fd_to_subdirp's fstat, along with the `fstat' and the dev/ino
1319      comparison in AD_push ensure that we detect it and fail.  */
1320
1321   DIR *dirp = fd_to_subdirp (fd_cwd, dir, x, 0, dir_st, ds, cwd_errno);
1322
1323   if (dirp == NULL)
1324     {
1325       /* CAUTION: this test and diagnostic are identical to
1326          those following the other use of fd_to_subdirp.  */
1327       if (ignorable_missing (x, errno))
1328         {
1329           /* With -f, don't report "file not found".  */
1330         }
1331       else
1332         {
1333           /* Upon fd_to_subdirp failure, try to remove DIR directly,
1334              in case it's just an empty directory.  */
1335           int saved_errno = errno;
1336           if (unlinkat (fd_cwd, dir, AT_REMOVEDIR) == 0)
1337             return RM_OK;
1338
1339           error (0, saved_errno,
1340                  _("cannot remove %s"), quote (full_filename (dir)));
1341         }
1342
1343       return RM_ERROR;
1344     }
1345
1346   if (ROOT_DEV_INO_CHECK (x->root_dev_ino, dir_st))
1347     {
1348       ROOT_DEV_INO_WARN (full_filename (dir));
1349       status = RM_ERROR;
1350       goto closedir_and_return;
1351     }
1352
1353   AD_push (dirfd (dirp), ds, dir, dir_st);
1354   AD_INIT_OTHER_MEMBERS ();
1355
1356   status = RM_OK;
1357
1358   while (1)
1359     {
1360       char *subdir = NULL;
1361       struct stat subdir_sb;
1362       enum RM_status tmp_status;
1363
1364       tmp_status = remove_cwd_entries (&dirp, ds, &subdir, &subdir_sb, x);
1365
1366       if (tmp_status != RM_OK)
1367         {
1368           UPDATE_STATUS (status, tmp_status);
1369           AD_mark_current_as_unremovable (ds);
1370         }
1371       if (subdir)
1372         {
1373           if ( ! x->one_file_system
1374                || subdir_sb.st_dev == current_dev)
1375             {
1376               AD_push (dirfd (dirp), ds, subdir, &subdir_sb);
1377               AD_INIT_OTHER_MEMBERS ();
1378               free (subdir);
1379               continue;
1380             }
1381
1382           /* Here, --one-file-system is in effect, and with remove_cwd_entries'
1383              traversal into the current directory, (known as SUBDIR, from ..),
1384              DIRP's device number is different from CURRENT_DEV.  Arrange not
1385              to do anything more with this hierarchy.  */
1386           error (0, errno, _("skipping %s, since it's on a different device"),
1387                  quote (full_filename (subdir)));
1388           free (subdir);
1389           AD_mark_current_as_unremovable (ds);
1390           tmp_status = RM_ERROR;
1391           UPDATE_STATUS (status, tmp_status);
1392         }
1393
1394       /* Execution reaches this point when we've removed the last
1395          removable entry from the current directory -- or, with
1396          --one-file-system, when the current directory is on a
1397          different file system.  */
1398       {
1399         /* The name of the directory that we have just processed,
1400            nominally removing all of its contents.  */
1401         char *empty_dir = AD_pop_and_chdir (&dirp, ds);
1402         int fd = (dirp != NULL ? dirfd (dirp) : AT_FDCWD);
1403         assert (dirp != NULL || AD_stack_height (ds) == 1);
1404
1405         /* Try to remove EMPTY_DIR only if remove_cwd_entries succeeded.  */
1406         if (tmp_status == RM_OK)
1407           {
1408             /* This does a little more work than necessary when it actually
1409                prompts the user.  E.g., we already know that D is a directory
1410                and that it's almost certainly empty, yet we lstat it.
1411                But that's no big deal since we're interactive.  */
1412             struct stat empty_st;
1413             Ternary is_empty;
1414             enum RM_status s = prompt (fd, ds, empty_dir,
1415                                        cache_stat_init (&empty_st), x,
1416                                        PA_REMOVE_DIR, &is_empty);
1417
1418             if (s != RM_OK)
1419               {
1420                 free (empty_dir);
1421                 status = s;
1422                 goto closedir_and_return;
1423               }
1424
1425             if (unlinkat (fd, empty_dir, AT_REMOVEDIR) == 0)
1426               {
1427                 if (x->verbose)
1428                   printf (_("removed directory: %s\n"),
1429                           quote (full_filename (empty_dir)));
1430               }
1431             else
1432               {
1433                 error (0, errno, _("cannot remove directory %s"),
1434                        quote (full_filename (empty_dir)));
1435                 AD_mark_as_unremovable (ds, empty_dir);
1436                 status = RM_ERROR;
1437                 UPDATE_STATUS (AD_stack_top(ds)->status, status);
1438               }
1439           }
1440
1441         free (empty_dir);
1442
1443         if (AD_stack_height (ds) == 1)
1444           break;
1445       }
1446     }
1447
1448   /* If the first/final hash table of unremovable entries was used,
1449      free it here.  */
1450   AD_stack_pop (ds);
1451
1452  closedir_and_return:;
1453   if (dirp != NULL && closedir (dirp) != 0)
1454     {
1455       error (0, 0, _("failed to close directory %s"),
1456              quote (full_filename (".")));
1457       status = RM_ERROR;
1458     }
1459
1460   return status;
1461 }
1462
1463 /* Remove the file or directory specified by FILENAME.
1464    Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.  */
1465
1466 static enum RM_status
1467 rm_1 (Dirstack_state *ds, char const *filename,
1468       struct rm_options const *x, int *cwd_errno)
1469 {
1470   char const *base = last_component (filename);
1471   if (dot_or_dotdot (base))
1472     {
1473       error (0, 0, _(base == filename
1474                      ? "cannot remove directory %s"
1475                      : "cannot remove %s directory %s"),
1476              quote_n (0, base), quote_n (1, filename));
1477       return RM_ERROR;
1478     }
1479
1480   struct stat st;
1481   cache_stat_init (&st);
1482   if (x->root_dev_ino)
1483     {
1484       if (cache_fstatat (AT_FDCWD, filename, &st, AT_SYMLINK_NOFOLLOW) != 0)
1485         {
1486           if (ignorable_missing (x, errno))
1487             return RM_OK;
1488           error (0, errno, _("cannot remove %s"), quote (filename));
1489           return RM_ERROR;
1490         }
1491       if (SAME_INODE (st, *(x->root_dev_ino)))
1492         {
1493           error (0, 0, _("cannot remove root directory %s"), quote (filename));
1494           return RM_ERROR;
1495         }
1496     }
1497
1498   AD_push_initial (ds);
1499   AD_INIT_OTHER_MEMBERS ();
1500
1501   enum RM_status status = remove_entry (AT_FDCWD, ds, filename, &st, x, NULL);
1502   if (status == RM_NONEMPTY_DIR)
1503     {
1504       /* In the event that remove_dir->remove_cwd_entries detects
1505          a directory cycle, arrange to fail, give up on this FILE, but
1506          continue on with any other arguments.  */
1507       if (setjmp (ds->current_arg_jumpbuf))
1508         status = RM_ERROR;
1509       else
1510         status = remove_dir (AT_FDCWD, ds, filename, &st, x, cwd_errno);
1511
1512       AD_stack_clear (ds);
1513     }
1514
1515   ds_clear (ds);
1516   return status;
1517 }
1518
1519 /* Remove all files and/or directories specified by N_FILES and FILE.
1520    Apply the options in X.  */
1521 extern enum RM_status
1522 rm (size_t n_files, char const *const *file, struct rm_options const *x)
1523 {
1524   enum RM_status status = RM_OK;
1525   Dirstack_state *ds = ds_init ();
1526   int cwd_errno = 0;
1527   size_t i;
1528
1529   for (i = 0; i < n_files; i++)
1530     {
1531       if (cwd_errno && IS_RELATIVE_FILE_NAME (file[i]))
1532         {
1533           error (0, 0, _("cannot remove relative-named %s"), quote (file[i]));
1534           status = RM_ERROR;
1535           continue;
1536         }
1537
1538       cycle_check_init (&ds->cycle_check_state);
1539       enum RM_status s = rm_1 (ds, file[i], x, &cwd_errno);
1540       assert (VALID_STATUS (s));
1541       UPDATE_STATUS (status, s);
1542     }
1543
1544   if (x->require_restore_cwd && cwd_errno)
1545     {
1546       error (0, cwd_errno,
1547              _("cannot restore current working directory"));
1548       status = RM_ERROR;
1549     }
1550
1551   ds_free (ds);
1552
1553   return status;
1554 }