maint: use more readable operator: "||" rather than "|"
[coreutils.git] / src / remove.c
blobb62c5d000478f0da18d4027ca7050134d8ce02c9
1 /* remove.c -- core functions for removing files and directories
2 Copyright (C) 1988, 1990-1991, 1994-2010 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Extracted from rm.c and librarified, then rewritten twice by Jim Meyering. */
19 #include <config.h>
20 #include <stdio.h>
21 #include <sys/types.h>
22 #include <assert.h>
24 #include "system.h"
25 #include "error.h"
26 #include "euidaccess-stat.h"
27 #include "file-type.h"
28 #include "hash.h"
29 #include "hash-pjw.h"
30 #include "obstack.h"
31 #include "quote.h"
32 #include "remove.h"
33 #include "root-dev-ino.h"
34 #include "write-any-file.h"
35 #include "xfts.h"
36 #include "yesno.h"
38 enum Ternary
40 T_UNKNOWN = 2,
41 T_NO,
42 T_YES
44 typedef enum Ternary Ternary;
46 /* The prompt function may be called twice for a given directory.
47 The first time, we ask whether to descend into it, and the
48 second time, we ask whether to remove it. */
49 enum Prompt_action
51 PA_DESCEND_INTO_DIR = 2,
52 PA_REMOVE_DIR
55 /* D_TYPE(D) is the type of directory entry D if known, DT_UNKNOWN
56 otherwise. */
57 #if ! HAVE_STRUCT_DIRENT_D_TYPE
58 /* Any int values will do here, so long as they're distinct.
59 Undef any existing macros out of the way. */
60 # undef DT_UNKNOWN
61 # undef DT_DIR
62 # undef DT_LNK
63 # define DT_UNKNOWN 0
64 # define DT_DIR 1
65 # define DT_LNK 2
66 #endif
68 /* Like fstatat, but cache the result. If ST->st_size is -1, the
69 status has not been gotten yet. If less than -1, fstatat failed
70 with errno == ST->st_ino. Otherwise, the status has already
71 been gotten, so return 0. */
72 static int
73 cache_fstatat (int fd, char const *file, struct stat *st, int flag)
75 if (st->st_size == -1 && fstatat (fd, file, st, flag) != 0)
77 st->st_size = -2;
78 st->st_ino = errno;
80 if (0 <= st->st_size)
81 return 0;
82 errno = (int) st->st_ino;
83 return -1;
86 /* Initialize a fstatat cache *ST. Return ST for convenience. */
87 static inline struct stat *
88 cache_stat_init (struct stat *st)
90 st->st_size = -1;
91 return st;
94 /* Return true if *ST has been statted. */
95 static inline bool
96 cache_statted (struct stat *st)
98 return (st->st_size != -1);
101 /* Return true if *ST has been statted successfully. */
102 static inline bool
103 cache_stat_ok (struct stat *st)
105 return (0 <= st->st_size);
108 /* Return 1 if FILE is an unwritable non-symlink,
109 0 if it is writable or some other type of file,
110 -1 and set errno if there is some problem in determining the answer.
111 Use FULL_NAME only if necessary.
112 Set *BUF to the file status.
113 This is to avoid calling euidaccess when FILE is a symlink. */
114 static int
115 write_protected_non_symlink (int fd_cwd,
116 char const *file,
117 char const *full_name,
118 struct stat *buf)
120 if (can_write_any_file ())
121 return 0;
122 if (cache_fstatat (fd_cwd, file, buf, AT_SYMLINK_NOFOLLOW) != 0)
123 return -1;
124 if (S_ISLNK (buf->st_mode))
125 return 0;
126 /* Here, we know FILE is not a symbolic link. */
128 /* In order to be reentrant -- i.e., to avoid changing the working
129 directory, and at the same time to be able to deal with alternate
130 access control mechanisms (ACLs, xattr-style attributes) and
131 arbitrarily deep trees -- we need a function like eaccessat, i.e.,
132 like Solaris' eaccess, but fd-relative, in the spirit of openat. */
134 /* In the absence of a native eaccessat function, here are some of
135 the implementation choices [#4 and #5 were suggested by Paul Eggert]:
136 1) call openat with O_WRONLY|O_NOCTTY
137 Disadvantage: may create the file and doesn't work for directory,
138 may mistakenly report `unwritable' for EROFS or ACLs even though
139 perm bits say the file is writable.
141 2) fake eaccessat (save_cwd, fchdir, call euidaccess, restore_cwd)
142 Disadvantage: changes working directory (not reentrant) and can't
143 work if save_cwd fails.
145 3) if (euidaccess (full_name, W_OK) == 0)
146 Disadvantage: doesn't work if full_name is too long.
147 Inefficient for very deep trees (O(Depth^2)).
149 4) If the full pathname is sufficiently short (say, less than
150 PATH_MAX or 8192 bytes, whichever is shorter):
151 use method (3) (i.e., euidaccess (full_name, W_OK));
152 Otherwise: vfork, fchdir in the child, run euidaccess in the
153 child, then the child exits with a status that tells the parent
154 whether euidaccess succeeded.
156 This avoids the O(N**2) algorithm of method (3), and it also avoids
157 the failure-due-to-too-long-file-names of method (3), but it's fast
158 in the normal shallow case. It also avoids the lack-of-reentrancy
159 and the save_cwd problems.
160 Disadvantage; it uses a process slot for very-long file names,
161 and would be very slow for hierarchies with many such files.
163 5) If the full file name is sufficiently short (say, less than
164 PATH_MAX or 8192 bytes, whichever is shorter):
165 use method (3) (i.e., euidaccess (full_name, W_OK));
166 Otherwise: look just at the file bits. Perhaps issue a warning
167 the first time this occurs.
169 This is like (4), except for the "Otherwise" case where it isn't as
170 "perfect" as (4) but is considerably faster. It conforms to current
171 POSIX, and is uniformly better than what Solaris and FreeBSD do (they
172 mess up with long file names). */
175 /* This implements #1: on decent systems, either faccessat is
176 native or /proc/self/fd allows us to skip a chdir. */
177 if (!openat_needs_fchdir ()
178 && faccessat (fd_cwd, file, W_OK, AT_EACCESS) == 0)
179 return 0;
181 /* This implements #5: */
182 size_t file_name_len = strlen (full_name);
184 if (MIN (PATH_MAX, 8192) <= file_name_len)
185 return ! euidaccess_stat (buf, W_OK);
186 if (euidaccess (full_name, W_OK) == 0)
187 return 0;
188 if (errno == EACCES)
190 errno = 0;
191 return 1;
194 /* Perhaps some other process has removed the file, or perhaps this
195 is a buggy NFS client. */
196 return -1;
200 /* Prompt whether to remove FILENAME (ent->, if required via a combination of
201 the options specified by X and/or file attributes. If the file may
202 be removed, return RM_OK. If the user declines to remove the file,
203 return RM_USER_DECLINED. If not ignoring missing files and we
204 cannot lstat FILENAME, then return RM_ERROR.
206 IS_DIR is true if ENT designates a directory, false otherwise.
208 Depending on MODE, ask whether to `descend into' or to `remove' the
209 directory FILENAME. MODE is ignored when FILENAME is not a directory.
210 Set *IS_EMPTY_P to T_YES if FILENAME is an empty directory, and it is
211 appropriate to try to remove it with rmdir (e.g. recursive mode).
212 Don't even try to set *IS_EMPTY_P when MODE == PA_REMOVE_DIR. */
213 static enum RM_status
214 prompt (FTS const *fts, FTSENT const *ent, bool is_dir,
215 struct rm_options const *x, enum Prompt_action mode,
216 Ternary *is_empty_p)
218 int fd_cwd = fts->fts_cwd_fd;
219 char const *full_name = ent->fts_path;
220 char const *filename = ent->fts_accpath;
221 if (is_empty_p)
222 *is_empty_p = T_UNKNOWN;
224 struct stat st;
225 struct stat *sbuf = &st;
226 cache_stat_init (sbuf);
228 int dirent_type = is_dir ? DT_DIR : DT_UNKNOWN;
229 int write_protected = 0;
231 /* When nonzero, this indicates that we failed to remove a child entry,
232 either because the user declined an interactive prompt, or due to
233 some other failure, like permissions. */
234 if (ent->fts_number)
235 return RM_USER_DECLINED;
237 if (x->interactive == RMI_NEVER)
238 return RM_OK;
240 int wp_errno = 0;
241 if (!x->ignore_missing_files
242 && ((x->interactive == RMI_ALWAYS) || x->stdin_tty)
243 && dirent_type != DT_LNK)
245 write_protected = write_protected_non_symlink (fd_cwd, filename,
246 full_name, sbuf);
247 wp_errno = errno;
250 if (write_protected || x->interactive == RMI_ALWAYS)
252 if (0 <= write_protected && dirent_type == DT_UNKNOWN)
254 if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) == 0)
256 if (S_ISLNK (sbuf->st_mode))
257 dirent_type = DT_LNK;
258 else if (S_ISDIR (sbuf->st_mode))
259 dirent_type = DT_DIR;
260 /* Otherwise it doesn't matter, so leave it DT_UNKNOWN. */
262 else
264 /* This happens, e.g., with `rm '''. */
265 write_protected = -1;
266 wp_errno = errno;
270 if (0 <= write_protected)
271 switch (dirent_type)
273 case DT_LNK:
274 /* Using permissions doesn't make sense for symlinks. */
275 if (x->interactive != RMI_ALWAYS)
276 return RM_OK;
277 break;
279 case DT_DIR:
280 if (!x->recursive)
282 write_protected = -1;
283 wp_errno = EISDIR;
285 break;
288 char const *quoted_name = quote (full_name);
290 if (write_protected < 0)
292 error (0, wp_errno, _("cannot remove %s"), quoted_name);
293 return RM_ERROR;
296 bool is_empty;
297 if (is_empty_p)
299 is_empty = is_empty_dir (fd_cwd, filename);
300 *is_empty_p = is_empty ? T_YES : T_NO;
302 else
303 is_empty = false;
305 /* Issue the prompt. */
306 if (dirent_type == DT_DIR
307 && mode == PA_DESCEND_INTO_DIR
308 && !is_empty)
309 fprintf (stderr,
310 (write_protected
311 ? _("%s: descend into write-protected directory %s? ")
312 : _("%s: descend into directory %s? ")),
313 program_name, quoted_name);
314 else
316 if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) != 0)
318 error (0, errno, _("cannot remove %s"), quoted_name);
319 return RM_ERROR;
322 fprintf (stderr,
323 (write_protected
324 /* TRANSLATORS: You may find it more convenient to
325 translate "%s: remove %s (write-protected) %s? "
326 instead. It should avoid grammatical problems
327 with the output of file_type. */
328 ? _("%s: remove write-protected %s %s? ")
329 : _("%s: remove %s %s? ")),
330 program_name, file_type (sbuf), quoted_name);
333 if (!yesno ())
334 return RM_USER_DECLINED;
336 return RM_OK;
339 /* Return true if FILENAME is a directory (and not a symlink to a directory).
340 Otherwise, including the case in which lstat fails, return false.
341 *ST is FILENAME's tstatus.
342 Do not modify errno. */
343 static inline bool
344 is_dir_lstat (int fd_cwd, char const *filename, struct stat *st)
346 int saved_errno = errno;
347 bool is_dir =
348 (cache_fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW) == 0
349 && S_ISDIR (st->st_mode));
350 errno = saved_errno;
351 return is_dir;
354 /* Return true if FILENAME is a non-directory.
355 Otherwise, including the case in which lstat fails, return false.
356 *ST is FILENAME's tstatus.
357 Do not modify errno. */
358 static inline bool
359 is_nondir_lstat (int fd_cwd, char const *filename, struct stat *st)
361 int saved_errno = errno;
362 bool is_non_dir =
363 (cache_fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW) == 0
364 && !S_ISDIR (st->st_mode));
365 errno = saved_errno;
366 return is_non_dir;
369 /* When a function like unlink, rmdir, or fstatat fails with an errno
370 value of ERRNUM, return true if the specified file system object
371 is guaranteed not to exist; otherwise, return false. */
372 static inline bool
373 nonexistent_file_errno (int errnum)
375 /* Do not include ELOOP here, since the specified file may indeed
376 exist, but be (in)accessible only via too long a symlink chain.
377 Likewise for ENAMETOOLONG, since rm -f ./././.../foo may fail
378 if the "..." part expands to a long enough sequence of "./"s,
379 even though ./foo does indeed exist. */
381 switch (errnum)
383 case ENOENT:
384 case ENOTDIR:
385 return true;
386 default:
387 return false;
391 /* Encapsulate the test for whether the errno value, ERRNUM, is ignorable. */
392 static inline bool
393 ignorable_missing (struct rm_options const *x, int errnum)
395 return x->ignore_missing_files && nonexistent_file_errno (errnum);
398 /* Tell fts not to traverse into the hierarchy at ENT. */
399 static void
400 fts_skip_tree (FTS *fts, FTSENT *ent)
402 fts_set (fts, ent, FTS_SKIP);
403 /* Ensure that we do not process ENT a second time. */
404 ent = fts_read (fts);
407 /* Upon unlink failure, or when the user declines to remove ENT, mark
408 each of its ancestor directories, so that we know not to prompt for
409 its removal. */
410 static void
411 mark_ancestor_dirs (FTSENT *ent)
413 FTSENT *p;
414 for (p = ent->fts_parent; FTS_ROOTLEVEL <= p->fts_level; p = p->fts_parent)
416 if (p->fts_number)
417 break;
418 p->fts_number = 1;
422 /* Remove the file system object specified by ENT. IS_DIR specifies
423 whether it is expected to be a directory or non-directory.
424 Return RM_OK upon success, else RM_ERROR. */
425 static enum RM_status
426 excise (FTS *fts, FTSENT *ent, struct rm_options const *x, bool is_dir)
428 int flag = is_dir ? AT_REMOVEDIR : 0;
429 if (unlinkat (fts->fts_cwd_fd, ent->fts_accpath, flag) == 0)
431 if (x->verbose)
433 printf ((is_dir
434 ? _("removed directory: %s\n")
435 : _("removed %s\n")), quote (ent->fts_path));
437 return RM_OK;
440 /* The unlinkat from kernels like linux-2.6.32 reports EROFS even for
441 nonexistent files. When the file is indeed missing, map that to ENOENT,
442 so that rm -f ignores it, as required. Even without -f, this is useful
443 because it makes rm print the more precise diagnostic. */
444 if (errno == EROFS)
446 struct stat st;
447 if ( ! (lstatat (fts->fts_cwd_fd, ent->fts_accpath, &st)
448 && errno == ENOENT))
449 errno = EROFS;
452 if (ignorable_missing (x, errno))
453 return RM_OK;
455 /* When failing to rmdir an unreadable directory, the typical
456 errno value is EISDIR, but that is not as useful to the user
457 as the errno value from the failed open (probably EPERM).
458 Use the earlier, more descriptive errno value. */
459 if (ent->fts_info == FTS_DNR)
460 errno = ent->fts_errno;
461 error (0, errno, _("cannot remove %s"), quote (ent->fts_path));
462 mark_ancestor_dirs (ent);
463 return RM_ERROR;
466 /* This function is called once for every file system object that fts
467 encounters. fts performs a depth-first traversal.
468 A directory is usually processed twice, first with fts_info == FTS_D,
469 and later, after all of its entries have been processed, with FTS_DP.
470 Return RM_ERROR upon error, RM_USER_DECLINED for a negative response
471 to an interactive prompt, and otherwise, RM_OK. */
472 static enum RM_status
473 rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x)
475 switch (ent->fts_info)
477 case FTS_D: /* preorder directory */
478 if (! x->recursive)
480 /* This is the first (pre-order) encounter with a directory.
481 Not recursive, so arrange to skip contents. */
482 error (0, EISDIR, _("cannot remove %s"), quote (ent->fts_path));
483 mark_ancestor_dirs (ent);
484 fts_skip_tree (fts, ent);
485 return RM_ERROR;
488 /* Perform checks that can apply only for command-line arguments. */
489 if (ent->fts_level == FTS_ROOTLEVEL)
491 if (strip_trailing_slashes (ent->fts_path))
492 ent->fts_pathlen = strlen (ent->fts_path);
494 /* If the basename of a command line argument is "." or "..",
495 diagnose it and do nothing more with that argument. */
496 if (dot_or_dotdot (last_component (ent->fts_accpath)))
498 error (0, 0, _("cannot remove directory: %s"),
499 quote (ent->fts_path));
500 fts_skip_tree (fts, ent);
501 return RM_ERROR;
504 /* If a command line argument resolves to "/" (and --preserve-root
505 is in effect -- default) diagnose and skip it. */
506 if (ROOT_DEV_INO_CHECK (x->root_dev_ino, ent->fts_statp))
508 ROOT_DEV_INO_WARN (ent->fts_path);
509 fts_skip_tree (fts, ent);
510 return RM_ERROR;
515 Ternary is_empty_directory;
516 enum RM_status s = prompt (fts, ent, true /*is_dir*/, x,
517 PA_DESCEND_INTO_DIR, &is_empty_directory);
519 if (s == RM_OK && is_empty_directory == T_YES)
521 /* When we know (from prompt when in interactive mode)
522 that this is an empty directory, don't prompt twice. */
523 s = excise (fts, ent, x, true);
524 fts_skip_tree (fts, ent);
527 if (s != RM_OK)
529 mark_ancestor_dirs (ent);
530 fts_skip_tree (fts, ent);
533 return s;
536 case FTS_F: /* regular file */
537 case FTS_NS: /* stat(2) failed */
538 case FTS_SL: /* symbolic link */
539 case FTS_SLNONE: /* symbolic link without target */
540 case FTS_DP: /* postorder directory */
541 case FTS_DNR: /* unreadable directory */
542 case FTS_NSOK: /* e.g., dangling symlink */
543 case FTS_DEFAULT: /* none of the above */
545 /* With --one-file-system, do not attempt to remove a mount point.
546 fts' FTS_XDEV ensures that we don't process any entries under
547 the mount point. */
548 if (ent->fts_info == FTS_DP
549 && x->one_file_system
550 && FTS_ROOTLEVEL < ent->fts_level
551 && ent->fts_statp->st_dev != fts->fts_dev)
553 mark_ancestor_dirs (ent);
554 error (0, 0, _("skipping %s, since it's on a different device"),
555 quote (ent->fts_path));
556 return RM_ERROR;
559 bool is_dir = ent->fts_info == FTS_DP || ent->fts_info == FTS_DNR;
560 enum RM_status s = prompt (fts, ent, is_dir, x, PA_REMOVE_DIR, NULL);
561 if (s != RM_OK)
562 return s;
563 return excise (fts, ent, x, is_dir);
566 case FTS_DC: /* directory that causes cycles */
567 emit_cycle_warning (ent->fts_path);
568 fts_skip_tree (fts, ent);
569 return RM_ERROR;
571 case FTS_ERR:
572 /* Various failures, from opendir to ENOMEM, to failure to "return"
573 to preceding directory, can provoke this. */
574 error (0, ent->fts_errno, _("traversal failed: %s"),
575 quote (ent->fts_path));
576 fts_skip_tree (fts, ent);
577 return RM_ERROR;
579 default:
580 error (0, 0, _("unexpected failure: fts_info=%d: %s\n"
581 "please report to %s"),
582 ent->fts_info,
583 quote (ent->fts_path),
584 PACKAGE_BUGREPORT);
585 abort ();
589 /* Remove FILEs, honoring options specified via X.
590 Return RM_OK if successful. */
591 enum RM_status
592 rm (char *const *file, struct rm_options const *x)
594 enum RM_status rm_status = RM_OK;
596 if (*file)
598 int bit_flags = (FTS_CWDFD
599 | FTS_NOSTAT
600 | FTS_PHYSICAL);
602 if (x->one_file_system)
603 bit_flags |= FTS_XDEV;
605 FTS *fts = xfts_open (file, bit_flags, NULL);
607 while (1)
609 FTSENT *ent;
611 ent = fts_read (fts);
612 if (ent == NULL)
614 if (errno != 0)
616 error (0, errno, _("fts_read failed"));
617 rm_status = RM_ERROR;
619 break;
622 enum RM_status s = rm_fts (fts, ent, x);
624 assert (VALID_STATUS (s));
625 UPDATE_STATUS (rm_status, s);
628 if (fts_close (fts) != 0)
630 error (0, errno, _("fts_close failed"));
631 rm_status = RM_ERROR;
635 return rm_status;