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