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