maint: update a couple of NEWS items for the pending release
[coreutils/ericb.git] / src / remove.c
blobd0b2dae2f479f9e4e8f969d349c153b095a7e7d3
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 "quote.h"
29 #include "remove.h"
30 #include "root-dev-ino.h"
31 #include "write-any-file.h"
32 #include "xfts.h"
33 #include "yesno.h"
35 enum Ternary
37 T_UNKNOWN = 2,
38 T_NO,
39 T_YES
41 typedef enum Ternary Ternary;
43 /* The prompt function may be called twice for a given directory.
44 The first time, we ask whether to descend into it, and the
45 second time, we ask whether to remove it. */
46 enum Prompt_action
48 PA_DESCEND_INTO_DIR = 2,
49 PA_REMOVE_DIR
52 /* D_TYPE(D) is the type of directory entry D if known, DT_UNKNOWN
53 otherwise. */
54 #if ! HAVE_STRUCT_DIRENT_D_TYPE
55 /* Any int values will do here, so long as they're distinct.
56 Undef any existing macros out of the way. */
57 # undef DT_UNKNOWN
58 # undef DT_DIR
59 # undef DT_LNK
60 # define DT_UNKNOWN 0
61 # define DT_DIR 1
62 # define DT_LNK 2
63 #endif
65 /* Like fstatat, but cache the result. If ST->st_size is -1, the
66 status has not been gotten yet. If less than -1, fstatat failed
67 with errno == ST->st_ino. Otherwise, the status has already
68 been gotten, so return 0. */
69 static int
70 cache_fstatat (int fd, char const *file, struct stat *st, int flag)
72 if (st->st_size == -1 && fstatat (fd, file, st, flag) != 0)
74 st->st_size = -2;
75 st->st_ino = errno;
77 if (0 <= st->st_size)
78 return 0;
79 errno = (int) st->st_ino;
80 return -1;
83 /* Initialize a fstatat cache *ST. Return ST for convenience. */
84 static inline struct stat *
85 cache_stat_init (struct stat *st)
87 st->st_size = -1;
88 return st;
91 /* Return true if *ST has been statted. */
92 static inline bool
93 cache_statted (struct stat *st)
95 return (st->st_size != -1);
98 /* Return true if *ST has been statted successfully. */
99 static inline bool
100 cache_stat_ok (struct stat *st)
102 return (0 <= st->st_size);
105 /* Return 1 if FILE is an unwritable non-symlink,
106 0 if it is writable or some other type of file,
107 -1 and set errno if there is some problem in determining the answer.
108 Use FULL_NAME only if necessary.
109 Set *BUF to the file status.
110 This is to avoid calling euidaccess when FILE is a symlink. */
111 static int
112 write_protected_non_symlink (int fd_cwd,
113 char const *file,
114 char const *full_name,
115 struct stat *buf)
117 if (can_write_any_file ())
118 return 0;
119 if (cache_fstatat (fd_cwd, file, buf, AT_SYMLINK_NOFOLLOW) != 0)
120 return -1;
121 if (S_ISLNK (buf->st_mode))
122 return 0;
123 /* Here, we know FILE is not a symbolic link. */
125 /* In order to be reentrant -- i.e., to avoid changing the working
126 directory, and at the same time to be able to deal with alternate
127 access control mechanisms (ACLs, xattr-style attributes) and
128 arbitrarily deep trees -- we need a function like eaccessat, i.e.,
129 like Solaris' eaccess, but fd-relative, in the spirit of openat. */
131 /* In the absence of a native eaccessat function, here are some of
132 the implementation choices [#4 and #5 were suggested by Paul Eggert]:
133 1) call openat with O_WRONLY|O_NOCTTY
134 Disadvantage: may create the file and doesn't work for directory,
135 may mistakenly report `unwritable' for EROFS or ACLs even though
136 perm bits say the file is writable.
138 2) fake eaccessat (save_cwd, fchdir, call euidaccess, restore_cwd)
139 Disadvantage: changes working directory (not reentrant) and can't
140 work if save_cwd fails.
142 3) if (euidaccess (full_name, W_OK) == 0)
143 Disadvantage: doesn't work if full_name is too long.
144 Inefficient for very deep trees (O(Depth^2)).
146 4) If the full pathname is sufficiently short (say, less than
147 PATH_MAX or 8192 bytes, whichever is shorter):
148 use method (3) (i.e., euidaccess (full_name, W_OK));
149 Otherwise: vfork, fchdir in the child, run euidaccess in the
150 child, then the child exits with a status that tells the parent
151 whether euidaccess succeeded.
153 This avoids the O(N**2) algorithm of method (3), and it also avoids
154 the failure-due-to-too-long-file-names of method (3), but it's fast
155 in the normal shallow case. It also avoids the lack-of-reentrancy
156 and the save_cwd problems.
157 Disadvantage; it uses a process slot for very-long file names,
158 and would be very slow for hierarchies with many such files.
160 5) If the full file name is sufficiently short (say, less than
161 PATH_MAX or 8192 bytes, whichever is shorter):
162 use method (3) (i.e., euidaccess (full_name, W_OK));
163 Otherwise: look just at the file bits. Perhaps issue a warning
164 the first time this occurs.
166 This is like (4), except for the "Otherwise" case where it isn't as
167 "perfect" as (4) but is considerably faster. It conforms to current
168 POSIX, and is uniformly better than what Solaris and FreeBSD do (they
169 mess up with long file names). */
172 /* This implements #1: on decent systems, either faccessat is
173 native or /proc/self/fd allows us to skip a chdir. */
174 if (!openat_needs_fchdir ())
176 if (faccessat (fd_cwd, file, W_OK, AT_EACCESS) == 0)
177 return 0;
179 return errno == EACCES ? 1 : -1;
182 /* This implements #5: */
183 size_t file_name_len = strlen (full_name);
185 if (MIN (PATH_MAX, 8192) <= file_name_len)
186 return ! euidaccess_stat (buf, W_OK);
187 if (euidaccess (full_name, W_OK) == 0)
188 return 0;
189 if (errno == EACCES)
191 errno = 0;
192 return 1;
195 /* Perhaps some other process has removed the file, or perhaps this
196 is a buggy NFS client. */
197 return -1;
201 /* Prompt whether to remove FILENAME (ent->, if required via a combination of
202 the options specified by X and/or file attributes. If the file may
203 be removed, return RM_OK. If the user declines to remove the file,
204 return RM_USER_DECLINED. If not ignoring missing files and we
205 cannot lstat FILENAME, then return RM_ERROR.
207 IS_DIR is true if ENT designates a directory, false otherwise.
209 Depending on MODE, ask whether to `descend into' or to `remove' the
210 directory FILENAME. MODE is ignored when FILENAME is not a directory.
211 Set *IS_EMPTY_P to T_YES if FILENAME is an empty directory, and it is
212 appropriate to try to remove it with rmdir (e.g. recursive mode).
213 Don't even try to set *IS_EMPTY_P when MODE == PA_REMOVE_DIR. */
214 static enum RM_status
215 prompt (FTS const *fts, FTSENT const *ent, bool is_dir,
216 struct rm_options const *x, enum Prompt_action mode,
217 Ternary *is_empty_p)
219 int fd_cwd = fts->fts_cwd_fd;
220 char const *full_name = ent->fts_path;
221 char const *filename = ent->fts_accpath;
222 if (is_empty_p)
223 *is_empty_p = T_UNKNOWN;
225 struct stat st;
226 struct stat *sbuf = &st;
227 cache_stat_init (sbuf);
229 int dirent_type = is_dir ? DT_DIR : DT_UNKNOWN;
230 int write_protected = 0;
232 /* When nonzero, this indicates that we failed to remove a child entry,
233 either because the user declined an interactive prompt, or due to
234 some other failure, like permissions. */
235 if (ent->fts_number)
236 return RM_USER_DECLINED;
238 if (x->interactive == RMI_NEVER)
239 return RM_OK;
241 int wp_errno = 0;
242 if (!x->ignore_missing_files
243 && ((x->interactive == RMI_ALWAYS) || x->stdin_tty)
244 && dirent_type != DT_LNK)
246 write_protected = write_protected_non_symlink (fd_cwd, filename,
247 full_name, sbuf);
248 wp_errno = errno;
251 if (write_protected || x->interactive == RMI_ALWAYS)
253 if (0 <= write_protected && dirent_type == DT_UNKNOWN)
255 if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) == 0)
257 if (S_ISLNK (sbuf->st_mode))
258 dirent_type = DT_LNK;
259 else if (S_ISDIR (sbuf->st_mode))
260 dirent_type = DT_DIR;
261 /* Otherwise it doesn't matter, so leave it DT_UNKNOWN. */
263 else
265 /* This happens, e.g., with `rm '''. */
266 write_protected = -1;
267 wp_errno = errno;
271 if (0 <= write_protected)
272 switch (dirent_type)
274 case DT_LNK:
275 /* Using permissions doesn't make sense for symlinks. */
276 if (x->interactive != RMI_ALWAYS)
277 return RM_OK;
278 break;
280 case DT_DIR:
281 if (!x->recursive)
283 write_protected = -1;
284 wp_errno = EISDIR;
286 break;
289 char const *quoted_name = quote (full_name);
291 if (write_protected < 0)
293 error (0, wp_errno, _("cannot remove %s"), quoted_name);
294 return RM_ERROR;
297 bool is_empty;
298 if (is_empty_p)
300 is_empty = is_empty_dir (fd_cwd, filename);
301 *is_empty_p = is_empty ? T_YES : T_NO;
303 else
304 is_empty = false;
306 /* Issue the prompt. */
307 if (dirent_type == DT_DIR
308 && mode == PA_DESCEND_INTO_DIR
309 && !is_empty)
310 fprintf (stderr,
311 (write_protected
312 ? _("%s: descend into write-protected directory %s? ")
313 : _("%s: descend into directory %s? ")),
314 program_name, quoted_name);
315 else
317 if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) != 0)
319 error (0, errno, _("cannot remove %s"), quoted_name);
320 return RM_ERROR;
323 fprintf (stderr,
324 (write_protected
325 /* TRANSLATORS: You may find it more convenient to
326 translate "%s: remove %s (write-protected) %s? "
327 instead. It should avoid grammatical problems
328 with the output of file_type. */
329 ? _("%s: remove write-protected %s %s? ")
330 : _("%s: remove %s %s? ")),
331 program_name, file_type (sbuf), quoted_name);
334 if (!yesno ())
335 return RM_USER_DECLINED;
337 return RM_OK;
340 /* Return true if FILENAME is a directory (and not a symlink to a directory).
341 Otherwise, including the case in which lstat fails, return false.
342 *ST is FILENAME's tstatus.
343 Do not modify errno. */
344 static inline bool
345 is_dir_lstat (int fd_cwd, char const *filename, struct stat *st)
347 int saved_errno = errno;
348 bool is_dir =
349 (cache_fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW) == 0
350 && S_ISDIR (st->st_mode));
351 errno = saved_errno;
352 return is_dir;
355 /* Return true if FILENAME is a non-directory.
356 Otherwise, including the case in which lstat fails, return false.
357 *ST is FILENAME's tstatus.
358 Do not modify errno. */
359 static inline bool
360 is_nondir_lstat (int fd_cwd, char const *filename, struct stat *st)
362 int saved_errno = errno;
363 bool is_non_dir =
364 (cache_fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW) == 0
365 && !S_ISDIR (st->st_mode));
366 errno = saved_errno;
367 return is_non_dir;
370 /* When a function like unlink, rmdir, or fstatat fails with an errno
371 value of ERRNUM, return true if the specified file system object
372 is guaranteed not to exist; otherwise, return false. */
373 static inline bool
374 nonexistent_file_errno (int errnum)
376 /* Do not include ELOOP here, since the specified file may indeed
377 exist, but be (in)accessible only via too long a symlink chain.
378 Likewise for ENAMETOOLONG, since rm -f ./././.../foo may fail
379 if the "..." part expands to a long enough sequence of "./"s,
380 even though ./foo does indeed exist. */
382 switch (errnum)
384 case ENOENT:
385 case ENOTDIR:
386 return true;
387 default:
388 return false;
392 /* Encapsulate the test for whether the errno value, ERRNUM, is ignorable. */
393 static inline bool
394 ignorable_missing (struct rm_options const *x, int errnum)
396 return x->ignore_missing_files && nonexistent_file_errno (errnum);
399 /* Tell fts not to traverse into the hierarchy at ENT. */
400 static void
401 fts_skip_tree (FTS *fts, FTSENT *ent)
403 fts_set (fts, ent, FTS_SKIP);
404 /* Ensure that we do not process ENT a second time. */
405 ent = fts_read (fts);
408 /* Upon unlink failure, or when the user declines to remove ENT, mark
409 each of its ancestor directories, so that we know not to prompt for
410 its removal. */
411 static void
412 mark_ancestor_dirs (FTSENT *ent)
414 FTSENT *p;
415 for (p = ent->fts_parent; FTS_ROOTLEVEL <= p->fts_level; p = p->fts_parent)
417 if (p->fts_number)
418 break;
419 p->fts_number = 1;
423 /* Remove the file system object specified by ENT. IS_DIR specifies
424 whether it is expected to be a directory or non-directory.
425 Return RM_OK upon success, else RM_ERROR. */
426 static enum RM_status
427 excise (FTS *fts, FTSENT *ent, struct rm_options const *x, bool is_dir)
429 int flag = is_dir ? AT_REMOVEDIR : 0;
430 if (unlinkat (fts->fts_cwd_fd, ent->fts_accpath, flag) == 0)
432 if (x->verbose)
434 printf ((is_dir
435 ? _("removed directory: %s\n")
436 : _("removed %s\n")), quote (ent->fts_path));
438 return RM_OK;
441 /* The unlinkat from kernels like linux-2.6.32 reports EROFS even for
442 nonexistent files. When the file is indeed missing, map that to ENOENT,
443 so that rm -f ignores it, as required. Even without -f, this is useful
444 because it makes rm print the more precise diagnostic. */
445 if (errno == EROFS)
447 struct stat st;
448 if ( ! (lstatat (fts->fts_cwd_fd, ent->fts_accpath, &st)
449 && errno == ENOENT))
450 errno = EROFS;
453 if (ignorable_missing (x, errno))
454 return RM_OK;
456 /* When failing to rmdir an unreadable directory, the typical
457 errno value is EISDIR, but that is not as useful to the user
458 as the errno value from the failed open (probably EPERM).
459 Use the earlier, more descriptive errno value. */
460 if (ent->fts_info == FTS_DNR)
461 errno = ent->fts_errno;
462 error (0, errno, _("cannot remove %s"), quote (ent->fts_path));
463 mark_ancestor_dirs (ent);
464 return RM_ERROR;
467 /* This function is called once for every file system object that fts
468 encounters. fts performs a depth-first traversal.
469 A directory is usually processed twice, first with fts_info == FTS_D,
470 and later, after all of its entries have been processed, with FTS_DP.
471 Return RM_ERROR upon error, RM_USER_DECLINED for a negative response
472 to an interactive prompt, and otherwise, RM_OK. */
473 static enum RM_status
474 rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x)
476 switch (ent->fts_info)
478 case FTS_D: /* preorder directory */
479 if (! x->recursive)
481 /* This is the first (pre-order) encounter with a directory.
482 Not recursive, so arrange to skip contents. */
483 error (0, EISDIR, _("cannot remove %s"), quote (ent->fts_path));
484 mark_ancestor_dirs (ent);
485 fts_skip_tree (fts, ent);
486 return RM_ERROR;
489 /* Perform checks that can apply only for command-line arguments. */
490 if (ent->fts_level == FTS_ROOTLEVEL)
492 if (strip_trailing_slashes (ent->fts_path))
493 ent->fts_pathlen = strlen (ent->fts_path);
495 /* If the basename of a command line argument is "." or "..",
496 diagnose it and do nothing more with that argument. */
497 if (dot_or_dotdot (last_component (ent->fts_accpath)))
499 error (0, 0, _("cannot remove directory: %s"),
500 quote (ent->fts_path));
501 fts_skip_tree (fts, ent);
502 return RM_ERROR;
505 /* If a command line argument resolves to "/" (and --preserve-root
506 is in effect -- default) diagnose and skip it. */
507 if (ROOT_DEV_INO_CHECK (x->root_dev_ino, ent->fts_statp))
509 ROOT_DEV_INO_WARN (ent->fts_path);
510 fts_skip_tree (fts, ent);
511 return RM_ERROR;
516 Ternary is_empty_directory;
517 enum RM_status s = prompt (fts, ent, true /*is_dir*/, x,
518 PA_DESCEND_INTO_DIR, &is_empty_directory);
520 if (s == RM_OK && is_empty_directory == T_YES)
522 /* When we know (from prompt when in interactive mode)
523 that this is an empty directory, don't prompt twice. */
524 s = excise (fts, ent, x, true);
525 fts_skip_tree (fts, ent);
528 if (s != RM_OK)
530 mark_ancestor_dirs (ent);
531 fts_skip_tree (fts, ent);
534 return s;
537 case FTS_F: /* regular file */
538 case FTS_NS: /* stat(2) failed */
539 case FTS_SL: /* symbolic link */
540 case FTS_SLNONE: /* symbolic link without target */
541 case FTS_DP: /* postorder directory */
542 case FTS_DNR: /* unreadable directory */
543 case FTS_NSOK: /* e.g., dangling symlink */
544 case FTS_DEFAULT: /* none of the above */
546 /* With --one-file-system, do not attempt to remove a mount point.
547 fts' FTS_XDEV ensures that we don't process any entries under
548 the mount point. */
549 if (ent->fts_info == FTS_DP
550 && x->one_file_system
551 && FTS_ROOTLEVEL < ent->fts_level
552 && ent->fts_statp->st_dev != fts->fts_dev)
554 mark_ancestor_dirs (ent);
555 error (0, 0, _("skipping %s, since it's on a different device"),
556 quote (ent->fts_path));
557 return RM_ERROR;
560 bool is_dir = ent->fts_info == FTS_DP || ent->fts_info == FTS_DNR;
561 enum RM_status s = prompt (fts, ent, is_dir, x, PA_REMOVE_DIR, NULL);
562 if (s != RM_OK)
563 return s;
564 return excise (fts, ent, x, is_dir);
567 case FTS_DC: /* directory that causes cycles */
568 emit_cycle_warning (ent->fts_path);
569 fts_skip_tree (fts, ent);
570 return RM_ERROR;
572 case FTS_ERR:
573 /* Various failures, from opendir to ENOMEM, to failure to "return"
574 to preceding directory, can provoke this. */
575 error (0, ent->fts_errno, _("traversal failed: %s"),
576 quote (ent->fts_path));
577 fts_skip_tree (fts, ent);
578 return RM_ERROR;
580 default:
581 error (0, 0, _("unexpected failure: fts_info=%d: %s\n"
582 "please report to %s"),
583 ent->fts_info,
584 quote (ent->fts_path),
585 PACKAGE_BUGREPORT);
586 abort ();
590 /* Remove FILEs, honoring options specified via X.
591 Return RM_OK if successful. */
592 enum RM_status
593 rm (char *const *file, struct rm_options const *x)
595 enum RM_status rm_status = RM_OK;
597 if (*file)
599 int bit_flags = (FTS_CWDFD
600 | FTS_NOSTAT
601 | FTS_PHYSICAL);
603 if (x->one_file_system)
604 bit_flags |= FTS_XDEV;
606 FTS *fts = xfts_open (file, bit_flags, NULL);
608 while (1)
610 FTSENT *ent;
612 ent = fts_read (fts);
613 if (ent == NULL)
615 if (errno != 0)
617 error (0, errno, _("fts_read failed"));
618 rm_status = RM_ERROR;
620 break;
623 enum RM_status s = rm_fts (fts, ent, x);
625 assert (VALID_STATUS (s));
626 UPDATE_STATUS (rm_status, s);
629 if (fts_close (fts) != 0)
631 error (0, errno, _("fts_close failed"));
632 rm_status = RM_ERROR;
636 return rm_status;