tweak grammar in comment
[platform/upstream/coreutils.git] / src / remove.c
1 /* remove.c -- core functions for removing files and directories
2    Copyright (C) 88, 90, 91, 1994-2006 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Extracted from rm.c and librarified, then rewritten by Jim Meyering.  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <setjmp.h>
24 #include <assert.h>
25
26 #include "system.h"
27 #include "cycle-check.h"
28 #include "dirfd.h"
29 #include "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 /* This is the maximum number of consecutive readdir/unlink calls that
54    can be made (with no intervening rewinddir or closedir/opendir)
55    before triggering a bug that makes readdir return NULL even though
56    some directory entries have not been processed.  The bug afflicts
57    SunOS's readdir when applied to ufs file systems and Darwin 6.5's
58    (and OSX v.10.3.8's) HFS+.  This maximum is conservative in that
59    demonstrating the problem seems to require a directory containing
60    at least 254 deletable entries (which doesn't count . and ..), so
61    we could conceivably increase the maximum value to 254.  */
62 enum
63   {
64     CONSECUTIVE_READDIR_UNLINK_THRESHOLD = 200
65   };
66
67 enum Ternary
68   {
69     T_UNKNOWN = 2,
70     T_NO,
71     T_YES
72   };
73 typedef enum Ternary Ternary;
74
75 /* The prompt function may be called twice for a given directory.
76    The first time, we ask whether to descend into it, and the
77    second time, we ask whether to remove it.  */
78 enum Prompt_action
79   {
80     PA_DESCEND_INTO_DIR = 2,
81     PA_REMOVE_DIR
82   };
83
84 /* Initial capacity of per-directory hash table of entries that have
85    been processed but not been deleted.  */
86 enum { HT_UNREMOVABLE_INITIAL_CAPACITY = 13 };
87
88 /* An entry in the active directory stack.
89    Each entry corresponds to an `active' directory.  */
90 struct AD_ent
91 {
92   /* For a given active directory, this is the set of names of
93      entries in that directory that could/should not be removed.
94      For example, `.' and `..', as well as files/dirs for which
95      unlink/rmdir failed e.g., due to access restrictions.  */
96   Hash_table *unremovable;
97
98   /* Record the status for a given active directory; we need to know
99      whether an entry was not removed, either because of an error or
100      because the user declined.  */
101   enum RM_status status;
102
103   /* The directory's dev/ino.  Used to ensure that a malicious user does
104      not replace a directory we're about to process with a symlink to
105      some other directory.  */
106   struct dev_ino dev_ino;
107 };
108
109 extern char *program_name;
110
111 struct dirstack_state
112 {
113   /* The name of the directory (starting with and relative to a command
114      line argument) being processed.  When a subdirectory is entered, a new
115      component is appended (pushed).  Remove (pop) the top component
116      upon chdir'ing out of a directory.  This is used to form the full
117      name of the current directory or a file therein, when necessary.  */
118   struct obstack dir_stack;
119
120   /* Stack of lengths of directory names (including trailing slash)
121      appended to dir_stack.  We have to have a separate stack of lengths
122      (rather than just popping back to previous slash) because the first
123      element pushed onto the dir stack may contain slashes.  */
124   struct obstack len_stack;
125
126   /* Stack of active directory entries.
127      The first `active' directory is the initial working directory.
128      Additional active dirs are pushed onto the stack as we `chdir'
129      into each directory to be processed.  When finished with the
130      hierarchy under a directory, pop the active dir stack.  */
131   struct obstack Active_dir;
132
133   /* Used to detect cycles.  */
134   struct cycle_check_state cycle_check_state;
135
136   /* Target of a longjmp in case rm has to stop processing the current
137      command-line argument.  This happens 1) when rm detects a directory
138      cycle or 2) when it has processed one or more directories, but then
139      is unable to return to the initial working directory to process
140      additional `.'-relative command-line arguments.  */
141   jmp_buf current_arg_jumpbuf;
142 };
143 typedef struct dirstack_state Dirstack_state;
144
145 /* Just like close(fd), but don't modify errno. */
146 static inline int
147 close_preserve_errno (int fd)
148 {
149   int saved_errno = errno;
150   int result = close (fd);
151   errno = saved_errno;
152   return result;
153 }
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 inline 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 inline 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   struct AD_ent *leaf_dir_ent = AD_stack_top(ds);
395   struct dev_ino leaf_dev_ino = leaf_dir_ent->dev_ino;
396   enum RM_status old_status = leaf_dir_ent->status;
397   struct AD_ent *top;
398
399   /* Get the name of the current (but soon to be `previous') directory
400      from the top of the stack.  */
401   *prev_dir = top_dir (ds);
402
403   AD_stack_pop (ds);
404   pop_dir (ds);
405   top = AD_stack_top (ds);
406
407   /* If the directory we're about to leave (and try to rmdir)
408      is the one whose dev_ino is being used to detect a cycle,
409      reset cycle_check_state.dev_ino to that of the parent.
410      Otherwise, once that directory is removed, its dev_ino
411      could be reused in the creation (by some other process)
412      of a directory that this rm process would encounter,
413      which would result in a false-positive cycle indication.  */
414   CYCLE_CHECK_REFLECT_CHDIR_UP (&ds->cycle_check_state,
415                                 top->dev_ino, leaf_dev_ino);
416
417   /* Propagate any failure to parent.  */
418   UPDATE_STATUS (top->status, old_status);
419
420   assert (AD_stack_height (ds));
421
422   if (1 < AD_stack_height (ds))
423     {
424       struct stat sb;
425       int fd = openat (dirfd (*dirp), "..", O_RDONLY);
426       if (CLOSEDIR (*dirp) != 0)
427         {
428           error (0, errno, _("FATAL: failed to close directory %s"),
429                  quote (full_filename (*prev_dir)));
430           goto next_cmdline_arg;
431         }
432
433       /* The above fails with EACCES when *DIRP is readable but not
434          searchable, when using Solaris' openat.  Without this openat
435          call, tests/rm2 would fail to remove directories a/2 and a/3.  */
436       if (fd < 0)
437         fd = openat (AT_FDCWD, full_filename ("."), O_RDONLY);
438
439       if (fd < 0)
440         {
441           error (0, errno, _("FATAL: cannot open .. from %s"),
442                  quote (full_filename (*prev_dir)));
443           goto next_cmdline_arg;
444         }
445
446       if (fstat (fd, &sb))
447         {
448           error (0, errno,
449                  _("FATAL: cannot ensure %s (returned to via ..) is safe"),
450                  quote (full_filename (".")));
451           goto close_and_next;
452         }
453
454       /*  Ensure that post-chdir dev/ino match the stored ones.  */
455       if ( ! SAME_INODE (sb, top->dev_ino))
456         {
457           error (0, 0, _("FATAL: directory %s changed dev/ino"),
458                  quote (full_filename (".")));
459           goto close_and_next;
460         }
461
462       *dirp = fdopendir (fd);
463       if (*dirp == NULL)
464         {
465           error (0, errno, _("FATAL: cannot return to .. from %s"),
466                  quote (full_filename (".")));
467
468         close_and_next:;
469           close (fd);
470
471         next_cmdline_arg:;
472           longjmp (ds->current_arg_jumpbuf, 1);
473         }
474     }
475   else
476     {
477       if (CLOSEDIR (*dirp) != 0)
478         {
479           error (0, errno, _("FATAL: failed to close directory %s"),
480                  quote (full_filename (*prev_dir)));
481           goto next_cmdline_arg;
482         }
483       *dirp = NULL;
484     }
485 }
486
487 /* Initialize *HT if it is NULL.
488    Insert FILENAME into HT.  */
489 static void
490 AD_mark_helper (Hash_table **ht, char const *filename)
491 {
492   if (*ht == NULL)
493     {
494       *ht = hash_initialize (HT_UNREMOVABLE_INITIAL_CAPACITY, NULL, hash_pjw,
495                              hash_compare_strings, hash_freer);
496       if (*ht == NULL)
497         xalloc_die ();
498     }
499   if (! hash_insert (*ht, filename))
500     xalloc_die ();
501 }
502
503 /* Mark FILENAME (in current directory) as unremovable.  */
504 static void
505 AD_mark_as_unremovable (Dirstack_state *ds, char const *filename)
506 {
507   AD_mark_helper (&AD_stack_top(ds)->unremovable, xstrdup (filename));
508 }
509
510 /* Mark the current directory as unremovable.  I.e., mark the entry
511    in the parent directory corresponding to `.'.
512    This happens e.g., when an opendir fails and the only name
513    the caller has conveniently at hand is `.'.  */
514 static void
515 AD_mark_current_as_unremovable (Dirstack_state *ds)
516 {
517   struct AD_ent *top = AD_stack_top (ds);
518   char const *curr = top_dir (ds);
519
520   assert (1 < AD_stack_height (ds));
521
522   --top;
523   AD_mark_helper (&top->unremovable, curr);
524 }
525
526 /* Push an initial dummy entry onto the stack.
527    This will always be the bottommost entry on the stack.  */
528 static void
529 AD_push_initial (Dirstack_state *ds)
530 {
531   struct AD_ent *top;
532
533   /* Extend the stack.  */
534   obstack_blank (&ds->Active_dir, sizeof (struct AD_ent));
535
536   /* Fill in the new values.  */
537   top = AD_stack_top (ds);
538   top->unremovable = NULL;
539
540   /* These should never be used.
541      Give them values that might look suspicious
542      in a debugger or in a diagnostic.  */
543   top->dev_ino.st_dev = TYPE_MAXIMUM (dev_t);
544   top->dev_ino.st_ino = TYPE_MAXIMUM (ino_t);
545 }
546
547 /* Push info about the current working directory (".") onto the
548    active directory stack.  DIR is the ./-relative name through
549    which we've just `chdir'd to this directory.  DIR_SB_FROM_PARENT
550    is the result of calling lstat on DIR from the parent of DIR.
551    Longjump out (skipping the entire command line argument we're
552    dealing with) if `fstat (FD_CWD, ...' fails or if someone has
553    replaced DIR with e.g., a symlink to some other directory.  */
554 static void
555 AD_push (int fd_cwd, Dirstack_state *ds, char const *dir,
556          struct stat const *dir_sb_from_parent)
557 {
558   struct AD_ent *top;
559
560   push_dir (ds, dir);
561
562   /* If our uses of openat are guaranteed not to
563      follow a symlink, then we can skip this check.  */
564   if ( ! O_NOFOLLOW)
565     {
566       struct stat sb;
567       if (fstat (fd_cwd, &sb) != 0)
568         {
569           error (0, errno, _("FATAL: cannot enter directory %s"),
570                  quote (full_filename (".")));
571           longjmp (ds->current_arg_jumpbuf, 1);
572         }
573
574       if ( ! SAME_INODE (sb, *dir_sb_from_parent))
575         {
576           error (0, 0,
577                  _("FATAL: just-changed-to directory %s changed dev/ino"),
578                  quote (full_filename (".")));
579           longjmp (ds->current_arg_jumpbuf, 1);
580         }
581     }
582
583   /* Extend the stack.  */
584   obstack_blank (&ds->Active_dir, sizeof (struct AD_ent));
585
586   /* The active directory stack must be one larger than the length stack.  */
587   assert (AD_stack_height (ds) ==
588           1 + obstack_object_size (&ds->len_stack) / sizeof (size_t));
589
590   /* Fill in the new values.  */
591   top = AD_stack_top (ds);
592   top->dev_ino.st_dev = dir_sb_from_parent->st_dev;
593   top->dev_ino.st_ino = dir_sb_from_parent->st_ino;
594   top->unremovable = NULL;
595 }
596
597 static inline bool
598 AD_is_removable (Dirstack_state const *ds, char const *file)
599 {
600   struct AD_ent *top = AD_stack_top (ds);
601   return ! (top->unremovable && hash_lookup (top->unremovable, file));
602 }
603
604 /* Return true if DIR is determined to be an empty directory.  */
605 static bool
606 is_empty_dir (int fd_cwd, char const *dir)
607 {
608   DIR *dirp;
609   struct dirent const *dp;
610   int saved_errno;
611   int fd = openat (fd_cwd, dir,
612                    (O_RDONLY | O_DIRECTORY
613                     | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK));
614
615   if (fd < 0)
616     return false;
617
618   dirp = fdopendir (fd);
619   if (dirp == NULL)
620     {
621       close (fd);
622       return false;
623     }
624
625   errno = 0;
626   dp = readdir_ignoring_dot_and_dotdot (dirp);
627   saved_errno = errno;
628   closedir (dirp);
629   if (dp != NULL)
630     return false;
631   return saved_errno == 0 ? true : false;
632 }
633
634 /* Return true if FILE is determined to be an unwritable non-symlink.
635    Otherwise, return false (including when lstat'ing it fails).
636    If lstat (aka fstatat) succeeds, set *BUF_P to BUF.
637    This is to avoid calling euidaccess when FILE is a symlink.  */
638 static bool
639 write_protected_non_symlink (int fd_cwd,
640                              char const *file,
641                              Dirstack_state const *ds,
642                              struct stat **buf_p,
643                              struct stat *buf)
644 {
645   if (fstatat (fd_cwd, file, buf, AT_SYMLINK_NOFOLLOW) != 0)
646     return false;
647   *buf_p = buf;
648   if (S_ISLNK (buf->st_mode))
649     return false;
650   /* Here, we know FILE is not a symbolic link.  */
651
652   /* In order to be reentrant -- i.e., to avoid changing the working
653      directory, and at the same time to be able to deal with alternate
654      access control mechanisms (ACLs, xattr-style attributes) and
655      arbitrarily deep trees -- we need a function like eaccessat, i.e.,
656      like Solaris' eaccess, but fd-relative, in the spirit of openat.  */
657
658   /* In the absence of a native eaccessat function, here are some of
659      the implementation choices [#4 and #5 were suggested by Paul Eggert]:
660      1) call openat with O_WRONLY|O_NOCTTY
661         Disadvantage: may create the file and doesn't work for directory,
662         may mistakenly report `unwritable' for EROFS or ACLs even though
663         perm bits say the file is writable.
664
665      2) fake eaccessat (save_cwd, fchdir, call euidaccess, restore_cwd)
666         Disadvantage: changes working directory (not reentrant) and can't
667         work if save_cwd fails.
668
669      3) if (euidaccess (full_filename (file), W_OK) == 0)
670         Disadvantage: doesn't work if full_filename is too long.
671         Inefficient for very deep trees (O(Depth^2)).
672
673      4) If the full pathname 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: vfork, fchdir in the child, run euidaccess in the
677         child, then the child exits with a status that tells the parent
678         whether euidaccess succeeded.
679
680         This avoids the O(N**2) algorithm of method (3), and it also avoids
681         the failure-due-to-too-long-file-names of method (3), but it's fast
682         in the normal shallow case.  It also avoids the lack-of-reentrancy
683         and the save_cwd problems.
684         Disadvantage; it uses a process slot for very-long file names,
685         and would be very slow for hierarchies with many such files.
686
687      5) If the full file name is sufficiently short (say, less than
688         PATH_MAX or 8192 bytes, whichever is shorter):
689         use method (3) (i.e., euidaccess (full_filename (file), W_OK));
690         Otherwise: look just at the file bits.  Perhaps issue a warning
691         the first time this occurs.
692
693         This is like (4), except for the "Otherwise" case where it isn't as
694         "perfect" as (4) but is considerably faster.  It conforms to current
695         POSIX, and is uniformly better than what Solaris and FreeBSD do (they
696         mess up with long file names). */
697
698   {
699     /* This implements #5: */
700     size_t file_name_len
701       = obstack_object_size (&ds->dir_stack) + strlen (file);
702
703     return (file_name_len < MIN (PATH_MAX, 8192)
704             ? euidaccess (full_filename (file), W_OK) != 0 && errno == EACCES
705             : euidaccess_stat (buf, W_OK) != 0);
706   }
707 }
708
709 /* Prompt whether to remove FILENAME, if required via a combination of
710    the options specified by X and/or file attributes.  If the file may
711    be removed, return RM_OK.  If the user declines to remove the file,
712    return RM_USER_DECLINED.  If not ignoring missing files and we
713    cannot lstat FILENAME, then return RM_ERROR.
714
715    Depending on MODE, ask whether to `descend into' or to `remove' the
716    directory FILENAME.  MODE is ignored when FILENAME is not a directory.
717    Set *IS_EMPTY to T_YES if FILENAME is an empty directory, and it is
718    appropriate to try to remove it with rmdir (e.g. recursive mode).
719    Don't even try to set *IS_EMPTY when MODE == PA_REMOVE_DIR.
720    Set *IS_DIR to T_YES or T_NO if we happen to determine whether
721    FILENAME is a directory.  */
722 static enum RM_status
723 prompt (int fd_cwd, Dirstack_state const *ds, char const *filename,
724         struct rm_options const *x, enum Prompt_action mode,
725         Ternary *is_dir, Ternary *is_empty)
726 {
727   bool write_protected = false;
728   struct stat *sbuf = NULL;
729   struct stat buf;
730
731   *is_empty = T_UNKNOWN;
732   *is_dir = T_UNKNOWN;
733
734   if (((!x->ignore_missing_files & (x->interactive | x->stdin_tty))
735        && (write_protected = write_protected_non_symlink (fd_cwd, filename,
736                                                           ds, &sbuf, &buf)))
737       || x->interactive)
738     {
739       if (sbuf == NULL)
740         {
741           sbuf = &buf;
742           if (fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW))
743             {
744               /* lstat failed.  This happens e.g., with `rm '''.  */
745               error (0, errno, _("cannot remove %s"),
746                      quote (full_filename (filename)));
747               return RM_ERROR;
748             }
749         }
750
751       if (S_ISDIR (sbuf->st_mode) && !x->recursive)
752         {
753           error (0, EISDIR, _("cannot remove directory %s"),
754                  quote (full_filename (filename)));
755           return RM_ERROR;
756         }
757
758       /* Using permissions doesn't make sense for symlinks.  */
759       if (S_ISLNK (sbuf->st_mode))
760         {
761           if ( ! x->interactive)
762             return RM_OK;
763           write_protected = false;
764         }
765
766       /* Issue the prompt.  */
767       {
768         char const *quoted_name = quote (full_filename (filename));
769
770         *is_dir = (S_ISDIR (sbuf->st_mode) ? T_YES : T_NO);
771
772         /* FIXME: use a variant of error (instead of fprintf) that doesn't
773            append a newline.  Then we won't have to declare program_name in
774            this file.  */
775         if (S_ISDIR (sbuf->st_mode)
776             && x->recursive
777             && mode == PA_DESCEND_INTO_DIR
778             && ((*is_empty = (is_empty_dir (fd_cwd, filename) ? T_YES : T_NO))
779                 == T_NO))
780           fprintf (stderr,
781                    (write_protected
782                     ? _("%s: descend into write-protected directory %s? ")
783                     : _("%s: descend into directory %s? ")),
784                    program_name, quoted_name);
785         else
786           {
787             /* TRANSLATORS: You may find it more convenient to translate
788                the equivalent of _("%s: remove %s (write-protected) %s? ").
789                It should avoid grammatical problems with the output
790                of file_type.  */
791             fprintf (stderr,
792                      (write_protected
793                       ? _("%s: remove write-protected %s %s? ")
794                       : _("%s: remove %s %s? ")),
795                      program_name, file_type (sbuf), quoted_name);
796           }
797
798         if (!yesno ())
799           return RM_USER_DECLINED;
800       }
801     }
802   return RM_OK;
803 }
804
805 /* Return true if FILENAME is a directory (and not a symlink to a directory).
806    Otherwise, including the case in which lstat fails, return false.
807    Do not modify errno.  */
808 static inline bool
809 is_dir_lstat (char const *filename)
810 {
811   struct stat sbuf;
812   int saved_errno = errno;
813   bool is_dir = lstat (filename, &sbuf) == 0 && S_ISDIR (sbuf.st_mode);
814   errno = saved_errno;
815   return is_dir;
816 }
817
818 #if HAVE_STRUCT_DIRENT_D_TYPE
819
820 /* True if the type of the directory entry D is known.  */
821 # define DT_IS_KNOWN(d) ((d)->d_type != DT_UNKNOWN)
822
823 /* True if the type of the directory entry D must be T.  */
824 # define DT_MUST_BE(d, t) ((d)->d_type == (t))
825
826 #else
827 # define DT_IS_KNOWN(d) false
828 # define DT_MUST_BE(d, t) false
829 #endif
830
831 #define DO_UNLINK(Fd_cwd, Filename, X)                                  \
832   do                                                                    \
833     {                                                                   \
834       if (unlinkat (Fd_cwd, Filename, 0) == 0)                          \
835         {                                                               \
836           if ((X)->verbose)                                             \
837             printf (_("removed %s\n"), quote (full_filename (Filename))); \
838           return RM_OK;                                                 \
839         }                                                               \
840                                                                         \
841       if (errno == ENOENT && (X)->ignore_missing_files)                 \
842         return RM_OK;                                                   \
843     }                                                                   \
844   while (0)
845
846 #define DO_RMDIR(Fd_cwd, Filename, X)                   \
847   do                                                    \
848     {                                                   \
849       if (unlinkat (Fd_cwd, Filename, AT_REMOVEDIR) == 0) /* rmdir */ \
850         {                                               \
851           if ((X)->verbose)                             \
852             printf (_("removed directory: %s\n"),       \
853                     quote (full_filename (Filename)));  \
854           return RM_OK;                                 \
855         }                                               \
856                                                         \
857       if (errno == ENOENT && (X)->ignore_missing_files) \
858         return RM_OK;                                   \
859                                                         \
860       if (errno == ENOTEMPTY || errno == EEXIST)        \
861         return RM_NONEMPTY_DIR;                         \
862     }                                                   \
863   while (0)
864
865 /* Remove the file or directory specified by FILENAME.
866    Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
867    But if FILENAME specifies a non-empty directory, return RM_NONEMPTY_DIR. */
868
869 static enum RM_status
870 remove_entry (int fd_cwd, Dirstack_state const *ds, char const *filename,
871               struct rm_options const *x, struct dirent const *dp)
872 {
873   Ternary is_dir;
874   Ternary is_empty_directory;
875   enum RM_status s = prompt (fd_cwd, ds, filename, x, PA_DESCEND_INTO_DIR,
876                              &is_dir, &is_empty_directory);
877
878   if (s != RM_OK)
879     return s;
880
881   /* Why bother with the following if/else block?  Because on systems with
882      an unlink function that *can* unlink directories, we must determine the
883      type of each entry before removing it.  Otherwise, we'd risk unlinking
884      an entire directory tree simply by unlinking a single directory;  then
885      all the storage associated with that hierarchy would not be freed until
886      the next fsck.  Not nice.  To avoid that, on such slightly losing
887      systems, we need to call lstat to determine the type of each entry,
888      and that represents extra overhead that -- it turns out -- we can
889      avoid on non-losing systems, since there, unlink will never remove
890      a directory.  Also, on systems where unlink may unlink directories,
891      we're forced to allow a race condition: we lstat a non-directory, then
892      go to unlink it, but in the mean time, a malicious someone could have
893      replaced it with a directory.  */
894
895   if (cannot_unlink_dir ())
896     {
897       if (is_dir == T_YES && ! x->recursive)
898         {
899           error (0, EISDIR, _("cannot remove directory %s"),
900                  quote (full_filename (filename)));
901           return RM_ERROR;
902         }
903
904       /* is_empty_directory is set iff it's ok to use rmdir.
905          Note that it's set only in interactive mode -- in which case it's
906          an optimization that arranges so that the user is asked just
907          once whether to remove the directory.  */
908       if (is_empty_directory == T_YES)
909         DO_RMDIR (fd_cwd, filename, x);
910
911       /* If we happen to know that FILENAME is a directory, return now
912          and let the caller remove it -- this saves the overhead of a failed
913          unlink call.  If FILENAME is a command-line argument, then dp is NULL,
914          so we'll first try to unlink it.  Using unlink here is ok, because it
915          cannot remove a directory.  */
916       if ((dp && DT_MUST_BE (dp, DT_DIR)) || is_dir == T_YES)
917         return RM_NONEMPTY_DIR;
918
919       DO_UNLINK (fd_cwd, filename, x);
920
921       /* Upon a failed attempt to unlink a directory, most non-Linux systems
922          set errno to the POSIX-required value EPERM.  In that case, change
923          errno to EISDIR so that we emit a better diagnostic.  */
924       if (! x->recursive && errno == EPERM && is_dir_lstat (filename))
925         errno = EISDIR;
926
927       if (! x->recursive
928           || errno == ENOENT || errno == ENOTDIR
929           || errno == ELOOP || errno == ENAMETOOLONG)
930         {
931           /* Either --recursive is not in effect, or the file cannot be a
932              directory.  Report the unlink problem and fail.  */
933           error (0, errno, _("cannot remove %s"),
934                  quote (full_filename (filename)));
935           return RM_ERROR;
936         }
937     }
938   else
939     {
940       /* If we don't already know whether FILENAME is a directory, find out now.
941          Then, if it's a non-directory, we can use unlink on it.  */
942       if (is_dir == T_UNKNOWN)
943         {
944           if (dp && DT_IS_KNOWN (dp))
945             is_dir = DT_MUST_BE (dp, DT_DIR) ? T_YES : T_NO;
946           else
947             {
948               struct stat sbuf;
949               if (fstatat (fd_cwd, filename, &sbuf, AT_SYMLINK_NOFOLLOW))
950                 {
951                   if (errno == ENOENT && x->ignore_missing_files)
952                     return RM_OK;
953
954                   error (0, errno, _("cannot remove %s"),
955                          quote (full_filename (filename)));
956                   return RM_ERROR;
957                 }
958
959               is_dir = S_ISDIR (sbuf.st_mode) ? T_YES : T_NO;
960             }
961         }
962
963       if (is_dir == T_NO)
964         {
965           /* At this point, barring race conditions, FILENAME is known
966              to be a non-directory, so it's ok to try to unlink it.  */
967           DO_UNLINK (fd_cwd, filename, x);
968
969           /* unlink failed with some other error code.  report it.  */
970           error (0, errno, _("cannot remove %s"),
971                  quote (full_filename (filename)));
972           return RM_ERROR;
973         }
974
975       if (! x->recursive)
976         {
977           error (0, EISDIR, _("cannot remove directory %s"),
978                  quote (full_filename (filename)));
979           return RM_ERROR;
980         }
981
982       if (is_empty_directory == T_YES)
983         {
984           DO_RMDIR (fd_cwd, filename, x);
985           /* Don't diagnose any failure here.
986              It'll be detected when the caller tries another way.  */
987         }
988     }
989
990   return RM_NONEMPTY_DIR;
991 }
992
993 /* Given FD_CWD, the file descriptor for an open directory,
994    open its subdirectory F (F is already `known' to be a directory,
995    so if it is no longer one, someone is playing games), return a DIR*
996    pointer for F, and put F's `stat' data in *SUBDIR_SB.
997    Upon failure give a diagnostic and return NULL.
998    If PREV_ERRNO is nonzero, it is the errno value from a preceding failed
999    unlink- or rmdir-like system call -- use that value instead of ENOTDIR
1000    if an opened file turns out not to be a directory.  This is important
1001    when the preceding non-dir-unlink failed due to e.g., EPERM or EACCES.
1002    The caller must use a nonnnull CWD_ERRNO the first
1003    time this function is called for each command-line-specified directory.
1004    If CWD_ERRNO is not null, set *CWD_ERRNO to the appropriate error number
1005    if this function fails to restore the initial working directory.
1006    If it is null, report an error and exit if the working directory
1007    isn't restored.  */
1008 static DIR *
1009 fd_to_subdirp (int fd_cwd, char const *f,
1010                struct rm_options const *x, int prev_errno,
1011                struct stat *subdir_sb, Dirstack_state *ds,
1012                int *cwd_errno ATTRIBUTE_UNUSED)
1013 {
1014   int open_flags = O_RDONLY | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK;
1015   int fd_sub = openat_permissive (fd_cwd, f, open_flags, 0, cwd_errno);
1016
1017   /* Record dev/ino of F.  We may compare them against saved values
1018      to thwart any attempt to subvert the traversal.  They are also used
1019      to detect directory cycles.  */
1020   if (fd_sub < 0 || fstat (fd_sub, subdir_sb) != 0)
1021     {
1022       if (0 <= fd_sub)
1023         close_preserve_errno (fd_sub);
1024       return NULL;
1025     }
1026
1027   if (! S_ISDIR (subdir_sb->st_mode))
1028     {
1029       errno = prev_errno ? prev_errno : ENOTDIR;
1030       close_preserve_errno (fd_sub);
1031       return NULL;
1032     }
1033
1034   DIR *subdir_dirp = fdopendir (fd_sub);
1035   if (subdir_dirp == NULL)
1036     {
1037       close_preserve_errno (fd_sub);
1038       return NULL;
1039     }
1040
1041   return subdir_dirp;
1042 }
1043
1044 /* Remove entries in the directory open on DIRP
1045    Upon finding a directory that is both non-empty and that can be chdir'd
1046    into, return RM_OK and set *SUBDIR and fill in SUBDIR_SB, where
1047    SUBDIR is the malloc'd name of the subdirectory if the chdir succeeded,
1048    NULL otherwise (e.g., if opendir failed or if there was no subdirectory).
1049    Likewise, SUBDIR_SB is the result of calling lstat on SUBDIR.
1050    Return RM_OK if all entries are removed.  Return RM_ERROR if any
1051    entry cannot be removed.  Otherwise, return RM_USER_DECLINED if
1052    the user declines to remove at least one entry.  Remove as much as
1053    possible, continuing even if we fail to remove some entries.  */
1054 static enum RM_status
1055 remove_cwd_entries (DIR **dirp,
1056                     Dirstack_state *ds, char **subdir, struct stat *subdir_sb,
1057                     struct rm_options const *x)
1058 {
1059   struct AD_ent *top = AD_stack_top (ds);
1060   enum RM_status status = top->status;
1061   size_t n_unlinked_since_opendir_or_last_rewind = 0;
1062
1063   assert (VALID_STATUS (status));
1064   *subdir = NULL;
1065
1066   while (1)
1067     {
1068       struct dirent const *dp;
1069       enum RM_status tmp_status;
1070       const char *f;
1071
1072       /* Set errno to zero so we can distinguish between a readdir failure
1073          and when readdir simply finds that there are no more entries.  */
1074       errno = 0;
1075       dp = readdir_ignoring_dot_and_dotdot (*dirp);
1076       if (dp == NULL)
1077         {
1078           if (errno)
1079             {
1080               /* fall through */
1081             }
1082           else if (CONSECUTIVE_READDIR_UNLINK_THRESHOLD
1083                    < n_unlinked_since_opendir_or_last_rewind)
1084             {
1085               /* Call rewinddir if we've called unlink or rmdir so many times
1086                  (since the opendir or the previous rewinddir) that this
1087                  NULL-return may be the symptom of a buggy readdir.  */
1088               rewinddir (*dirp);
1089               n_unlinked_since_opendir_or_last_rewind = 0;
1090               continue;
1091             }
1092           break;
1093         }
1094
1095       f = dp->d_name;
1096
1097       /* Skip files we've already tried/failed to remove.  */
1098       if ( ! AD_is_removable (ds, f))
1099         continue;
1100
1101       /* Pass dp->d_type info to remove_entry so the non-glibc
1102          case can decide whether to use unlink or chdir.
1103          Systems without the d_type member will have to endure
1104          the performance hit of first calling lstat F. */
1105       tmp_status = remove_entry (dirfd (*dirp), ds, f, x, dp);
1106       switch (tmp_status)
1107         {
1108         case RM_OK:
1109           /* Count how many files we've unlinked since the initial
1110              opendir or the last rewinddir.  On buggy systems, if you
1111              remove too many, readdir returns NULL even though there
1112              remain unprocessed directory entries.  */
1113           ++n_unlinked_since_opendir_or_last_rewind;
1114           break;
1115
1116         case RM_ERROR:
1117         case RM_USER_DECLINED:
1118           AD_mark_as_unremovable (ds, f);
1119           UPDATE_STATUS (status, tmp_status);
1120           break;
1121
1122         case RM_NONEMPTY_DIR:
1123           {
1124             DIR *subdir_dirp = fd_to_subdirp (dirfd (*dirp), f,
1125                                               x, errno, subdir_sb, ds, NULL);
1126             if (subdir_dirp == NULL)
1127               {
1128                 /* CAUTION: this test and diagnostic are identical to
1129                    those following the other use of fd_to_subdirp.  */
1130                 if (errno != ENOENT || !x->ignore_missing_files)
1131                   error (0, errno,
1132                          _("cannot remove %s"), quote (full_filename (f)));
1133                 AD_mark_as_unremovable (ds, f);
1134                 status = RM_ERROR;
1135                 break;
1136               }
1137
1138             if (cycle_check (&ds->cycle_check_state, subdir_sb))
1139               {
1140                 error (0, 0, _("\
1141 WARNING: Circular directory structure.\n\
1142 This almost certainly means that you have a corrupted file system.\n\
1143 NOTIFY YOUR SYSTEM MANAGER.\n\
1144 The following directory is part of the cycle:\n  %s\n"),
1145                        quote (full_filename (".")));
1146                 longjmp (ds->current_arg_jumpbuf, 1);
1147               }
1148
1149             *subdir = xstrdup (f);
1150             if (CLOSEDIR (*dirp) != 0)
1151               {
1152                 error (0, 0, _("failed to close directory %s"),
1153                        quote (full_filename (".")));
1154                 status = RM_ERROR;
1155               }
1156             *dirp = subdir_dirp;
1157
1158             break;
1159           }
1160         }
1161
1162       /* Record status for this directory.  */
1163       UPDATE_STATUS (top->status, status);
1164
1165       if (*subdir)
1166         break;
1167     }
1168
1169   /* Ensure that *dirp is not NULL and that its file descriptor is valid.  */
1170   assert (*dirp != NULL);
1171   assert (0 <= fcntl (dirfd (*dirp), F_GETFD));
1172
1173   return status;
1174 }
1175
1176 /* Do this after each call to AD_push or AD_push_initial.
1177    Because the status = RM_OK bit is too remove-specific to
1178    go into the general-purpose AD_* package.  */
1179 #define AD_INIT_OTHER_MEMBERS()                 \
1180   do                                            \
1181     {                                           \
1182       AD_stack_top(ds)->status = RM_OK;         \
1183     }                                           \
1184   while (0)
1185
1186 /*  Remove the hierarchy rooted at DIR.
1187     Do that by changing into DIR, then removing its contents, then
1188     returning to the original working directory and removing DIR itself.
1189     Don't use recursion.  Be careful when using chdir ".." that we
1190     return to the same directory from which we came, if necessary.
1191     Return an RM_status value to indicate success or failure.  */
1192
1193 static enum RM_status
1194 remove_dir (int fd_cwd, Dirstack_state *ds, char const *dir,
1195             struct rm_options const *x, int *cwd_errno)
1196 {
1197   enum RM_status status;
1198   struct stat dir_sb;
1199
1200   /* There is a race condition in that an attacker could replace the nonempty
1201      directory, DIR, with a symlink between the preceding call to rmdir
1202      (unlinkat, in our caller) and fd_to_subdirp's openat call.  But on most
1203      systems, even those without openat, this isn't a problem, since we ensure
1204      that opening a symlink will fail, when that is possible.  Otherwise,
1205      fd_to_subdirp's fstat, along with the `fstat' and the dev/ino
1206      comparison in AD_push ensure that we detect it and fail.  */
1207
1208   DIR *dirp = fd_to_subdirp (fd_cwd, dir, x, 0, &dir_sb, ds, cwd_errno);
1209
1210   if (dirp == NULL)
1211     {
1212       int saved_errno = errno;
1213       if (errno == EACCES)
1214         {
1215           /* If fd_to_subdirp fails due to permissions, then try to
1216              remove DIR via rmdir, in case it's just an empty directory.  */
1217           if (rmdir (dir) == 0)
1218             return RM_OK;
1219
1220           errno = saved_errno;
1221         }
1222
1223       /* CAUTION: this test and diagnostic are identical to those
1224          following the other use of fd_to_subdirp.  */
1225       if (errno != ENOENT || !x->ignore_missing_files)
1226         error (0, errno,
1227                _("cannot remove %s"), quote (full_filename (dir)));
1228
1229       return RM_ERROR;
1230     }
1231
1232   if (ROOT_DEV_INO_CHECK (x->root_dev_ino, &dir_sb))
1233     {
1234       ROOT_DEV_INO_WARN (full_filename (dir));
1235       status = RM_ERROR;
1236       goto closedir_and_return;
1237     }
1238
1239   AD_push (dirfd (dirp), ds, dir, &dir_sb);
1240   AD_INIT_OTHER_MEMBERS ();
1241
1242   status = RM_OK;
1243
1244   while (1)
1245     {
1246       char *subdir = NULL;
1247       struct stat subdir_sb;
1248       enum RM_status tmp_status;
1249
1250       tmp_status = remove_cwd_entries (&dirp, ds, &subdir, &subdir_sb, x);
1251
1252       if (tmp_status != RM_OK)
1253         {
1254           UPDATE_STATUS (status, tmp_status);
1255           AD_mark_current_as_unremovable (ds);
1256         }
1257       if (subdir)
1258         {
1259           AD_push (dirfd (dirp), ds, subdir, &subdir_sb);
1260           AD_INIT_OTHER_MEMBERS ();
1261
1262           free (subdir);
1263           continue;
1264         }
1265
1266       /* Execution reaches this point when we've removed the last
1267          removable entry from the current directory.  */
1268       {
1269         /* The name of the directory that we have just processed,
1270            nominally removing all of its contents.  */
1271         char *empty_dir;
1272
1273         AD_pop_and_chdir (&dirp, ds, &empty_dir);
1274         int fd = (dirp != NULL ? dirfd (dirp) : AT_FDCWD);
1275         assert (dirp != NULL || AD_stack_height (ds) == 1);
1276
1277         /* Try to remove EMPTY_DIR only if remove_cwd_entries succeeded.  */
1278         if (tmp_status == RM_OK)
1279           {
1280             /* This does a little more work than necessary when it actually
1281                prompts the user.  E.g., we already know that D is a directory
1282                and that it's almost certainly empty, yet we lstat it.
1283                But that's no big deal since we're interactive.  */
1284             Ternary is_dir;
1285             Ternary is_empty;
1286             enum RM_status s = prompt (fd, ds, empty_dir, x,
1287                                        PA_REMOVE_DIR, &is_dir, &is_empty);
1288
1289             if (s != RM_OK)
1290               {
1291                 free (empty_dir);
1292                 status = s;
1293                 goto closedir_and_return;
1294               }
1295
1296             if (unlinkat (fd, empty_dir, AT_REMOVEDIR) == 0)
1297               {
1298                 if (x->verbose)
1299                   printf (_("removed directory: %s\n"),
1300                           quote (full_filename (empty_dir)));
1301               }
1302             else
1303               {
1304                 error (0, errno, _("cannot remove directory %s"),
1305                        quote (full_filename (empty_dir)));
1306                 AD_mark_as_unremovable (ds, empty_dir);
1307                 status = RM_ERROR;
1308                 UPDATE_STATUS (AD_stack_top(ds)->status, status);
1309               }
1310           }
1311
1312         free (empty_dir);
1313
1314         if (AD_stack_height (ds) == 1)
1315           break;
1316       }
1317     }
1318
1319   /* If the first/final hash table of unremovable entries was used,
1320      free it here.  */
1321   AD_stack_pop (ds);
1322
1323  closedir_and_return:;
1324   if (dirp != NULL && CLOSEDIR (dirp) != 0)
1325     {
1326       error (0, 0, _("failed to close directory %s"),
1327              quote (full_filename (".")));
1328       status = RM_ERROR;
1329     }
1330
1331   return status;
1332 }
1333
1334 /* Remove the file or directory specified by FILENAME.
1335    Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.  */
1336
1337 static enum RM_status
1338 rm_1 (Dirstack_state *ds, char const *filename,
1339       struct rm_options const *x, int *cwd_errno)
1340 {
1341   char const *base = last_component (filename);
1342   if (DOT_OR_DOTDOT (base))
1343     {
1344       error (0, 0, _("cannot remove `.' or `..'"));
1345       return RM_ERROR;
1346     }
1347
1348   AD_push_initial (ds);
1349   AD_INIT_OTHER_MEMBERS ();
1350
1351   int fd_cwd = AT_FDCWD;
1352   enum RM_status status = remove_entry (fd_cwd, ds, filename, x, NULL);
1353   if (status == RM_NONEMPTY_DIR)
1354     {
1355       /* In the event that remove_dir->remove_cwd_entries detects
1356          a directory cycle, arrange to fail, give up on this FILE, but
1357          continue on with any other arguments.  */
1358       if (setjmp (ds->current_arg_jumpbuf))
1359         status = RM_ERROR;
1360       else
1361         status = remove_dir (fd_cwd, ds, filename, x, cwd_errno);
1362     }
1363
1364   ds_clear (ds);
1365
1366   return status;
1367 }
1368
1369 /* Remove all files and/or directories specified by N_FILES and FILE.
1370    Apply the options in X.  */
1371 extern enum RM_status
1372 rm (size_t n_files, char const *const *file, struct rm_options const *x)
1373 {
1374   enum RM_status status = RM_OK;
1375   Dirstack_state *ds = ds_init ();
1376   int cwd_errno = 0;
1377   size_t i;
1378
1379   for (i = 0; i < n_files; i++)
1380     {
1381       if (cwd_errno && IS_RELATIVE_FILE_NAME (file[i]))
1382         {
1383           error (0, 0, _("cannot remove relative-named %s"), quote (file[i]));
1384           status = RM_ERROR;
1385           continue;
1386         }
1387
1388       cycle_check_init (&ds->cycle_check_state);
1389       enum RM_status s = rm_1 (ds, file[i], x, &cwd_errno);
1390       assert (VALID_STATUS (s));
1391       UPDATE_STATUS (status, s);
1392     }
1393
1394   if (x->require_restore_cwd && cwd_errno)
1395     {
1396       error (0, cwd_errno,
1397              _("cannot restore current working directory"));
1398       status = RM_ERROR;
1399     }
1400
1401   ds_free (ds);
1402
1403   return status;
1404 }