bootstrap: resynchronize from gnulib
[coreutils.git] / src / remove.c
blobb6cfc8e99919cebdd898b39a89f761390b59a889
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 ()
175 && faccessat (fd_cwd, file, W_OK, AT_EACCESS) == 0)
176 return 0;
178 /* This implements #5: */
179 size_t file_name_len = strlen (full_name);
181 if (MIN (PATH_MAX, 8192) <= file_name_len)
182 return ! euidaccess_stat (buf, W_OK);
183 if (euidaccess (full_name, W_OK) == 0)
184 return 0;
185 if (errno == EACCES)
187 errno = 0;
188 return 1;
191 /* Perhaps some other process has removed the file, or perhaps this
192 is a buggy NFS client. */
193 return -1;
197 /* Prompt whether to remove FILENAME (ent->, if required via a combination of
198 the options specified by X and/or file attributes. If the file may
199 be removed, return RM_OK. If the user declines to remove the file,
200 return RM_USER_DECLINED. If not ignoring missing files and we
201 cannot lstat FILENAME, then return RM_ERROR.
203 IS_DIR is true if ENT designates a directory, false otherwise.
205 Depending on MODE, ask whether to `descend into' or to `remove' the
206 directory FILENAME. MODE is ignored when FILENAME is not a directory.
207 Set *IS_EMPTY_P to T_YES if FILENAME is an empty directory, and it is
208 appropriate to try to remove it with rmdir (e.g. recursive mode).
209 Don't even try to set *IS_EMPTY_P when MODE == PA_REMOVE_DIR. */
210 static enum RM_status
211 prompt (FTS const *fts, FTSENT const *ent, bool is_dir,
212 struct rm_options const *x, enum Prompt_action mode,
213 Ternary *is_empty_p)
215 int fd_cwd = fts->fts_cwd_fd;
216 char const *full_name = ent->fts_path;
217 char const *filename = ent->fts_accpath;
218 if (is_empty_p)
219 *is_empty_p = T_UNKNOWN;
221 struct stat st;
222 struct stat *sbuf = &st;
223 cache_stat_init (sbuf);
225 int dirent_type = is_dir ? DT_DIR : DT_UNKNOWN;
226 int write_protected = 0;
228 /* When nonzero, this indicates that we failed to remove a child entry,
229 either because the user declined an interactive prompt, or due to
230 some other failure, like permissions. */
231 if (ent->fts_number)
232 return RM_USER_DECLINED;
234 if (x->interactive == RMI_NEVER)
235 return RM_OK;
237 int wp_errno = 0;
238 if (!x->ignore_missing_files
239 && ((x->interactive == RMI_ALWAYS) || x->stdin_tty)
240 && dirent_type != DT_LNK)
242 write_protected = write_protected_non_symlink (fd_cwd, filename,
243 full_name, sbuf);
244 wp_errno = errno;
247 if (write_protected || x->interactive == RMI_ALWAYS)
249 if (0 <= write_protected && dirent_type == DT_UNKNOWN)
251 if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) == 0)
253 if (S_ISLNK (sbuf->st_mode))
254 dirent_type = DT_LNK;
255 else if (S_ISDIR (sbuf->st_mode))
256 dirent_type = DT_DIR;
257 /* Otherwise it doesn't matter, so leave it DT_UNKNOWN. */
259 else
261 /* This happens, e.g., with `rm '''. */
262 write_protected = -1;
263 wp_errno = errno;
267 if (0 <= write_protected)
268 switch (dirent_type)
270 case DT_LNK:
271 /* Using permissions doesn't make sense for symlinks. */
272 if (x->interactive != RMI_ALWAYS)
273 return RM_OK;
274 break;
276 case DT_DIR:
277 if (!x->recursive)
279 write_protected = -1;
280 wp_errno = EISDIR;
282 break;
285 char const *quoted_name = quote (full_name);
287 if (write_protected < 0)
289 error (0, wp_errno, _("cannot remove %s"), quoted_name);
290 return RM_ERROR;
293 bool is_empty;
294 if (is_empty_p)
296 is_empty = is_empty_dir (fd_cwd, filename);
297 *is_empty_p = is_empty ? T_YES : T_NO;
299 else
300 is_empty = false;
302 /* Issue the prompt. */
303 if (dirent_type == DT_DIR
304 && mode == PA_DESCEND_INTO_DIR
305 && !is_empty)
306 fprintf (stderr,
307 (write_protected
308 ? _("%s: descend into write-protected directory %s? ")
309 : _("%s: descend into directory %s? ")),
310 program_name, quoted_name);
311 else
313 if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) != 0)
315 error (0, errno, _("cannot remove %s"), quoted_name);
316 return RM_ERROR;
319 fprintf (stderr,
320 (write_protected
321 /* TRANSLATORS: You may find it more convenient to
322 translate "%s: remove %s (write-protected) %s? "
323 instead. It should avoid grammatical problems
324 with the output of file_type. */
325 ? _("%s: remove write-protected %s %s? ")
326 : _("%s: remove %s %s? ")),
327 program_name, file_type (sbuf), quoted_name);
330 if (!yesno ())
331 return RM_USER_DECLINED;
333 return RM_OK;
336 /* Return true if FILENAME is a directory (and not a symlink to a directory).
337 Otherwise, including the case in which lstat fails, return false.
338 *ST is FILENAME's tstatus.
339 Do not modify errno. */
340 static inline bool
341 is_dir_lstat (int fd_cwd, char const *filename, struct stat *st)
343 int saved_errno = errno;
344 bool is_dir =
345 (cache_fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW) == 0
346 && S_ISDIR (st->st_mode));
347 errno = saved_errno;
348 return is_dir;
351 /* Return true if FILENAME is a non-directory.
352 Otherwise, including the case in which lstat fails, return false.
353 *ST is FILENAME's tstatus.
354 Do not modify errno. */
355 static inline bool
356 is_nondir_lstat (int fd_cwd, char const *filename, struct stat *st)
358 int saved_errno = errno;
359 bool is_non_dir =
360 (cache_fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW) == 0
361 && !S_ISDIR (st->st_mode));
362 errno = saved_errno;
363 return is_non_dir;
366 /* When a function like unlink, rmdir, or fstatat fails with an errno
367 value of ERRNUM, return true if the specified file system object
368 is guaranteed not to exist; otherwise, return false. */
369 static inline bool
370 nonexistent_file_errno (int errnum)
372 /* Do not include ELOOP here, since the specified file may indeed
373 exist, but be (in)accessible only via too long a symlink chain.
374 Likewise for ENAMETOOLONG, since rm -f ./././.../foo may fail
375 if the "..." part expands to a long enough sequence of "./"s,
376 even though ./foo does indeed exist. */
378 switch (errnum)
380 case ENOENT:
381 case ENOTDIR:
382 return true;
383 default:
384 return false;
388 /* Encapsulate the test for whether the errno value, ERRNUM, is ignorable. */
389 static inline bool
390 ignorable_missing (struct rm_options const *x, int errnum)
392 return x->ignore_missing_files && nonexistent_file_errno (errnum);
395 /* Tell fts not to traverse into the hierarchy at ENT. */
396 static void
397 fts_skip_tree (FTS *fts, FTSENT *ent)
399 fts_set (fts, ent, FTS_SKIP);
400 /* Ensure that we do not process ENT a second time. */
401 ent = fts_read (fts);
404 /* Upon unlink failure, or when the user declines to remove ENT, mark
405 each of its ancestor directories, so that we know not to prompt for
406 its removal. */
407 static void
408 mark_ancestor_dirs (FTSENT *ent)
410 FTSENT *p;
411 for (p = ent->fts_parent; FTS_ROOTLEVEL <= p->fts_level; p = p->fts_parent)
413 if (p->fts_number)
414 break;
415 p->fts_number = 1;
419 /* Remove the file system object specified by ENT. IS_DIR specifies
420 whether it is expected to be a directory or non-directory.
421 Return RM_OK upon success, else RM_ERROR. */
422 static enum RM_status
423 excise (FTS *fts, FTSENT *ent, struct rm_options const *x, bool is_dir)
425 int flag = is_dir ? AT_REMOVEDIR : 0;
426 if (unlinkat (fts->fts_cwd_fd, ent->fts_accpath, flag) == 0)
428 if (x->verbose)
430 printf ((is_dir
431 ? _("removed directory: %s\n")
432 : _("removed %s\n")), quote (ent->fts_path));
434 return RM_OK;
437 /* The unlinkat from kernels like linux-2.6.32 reports EROFS even for
438 nonexistent files. When the file is indeed missing, map that to ENOENT,
439 so that rm -f ignores it, as required. Even without -f, this is useful
440 because it makes rm print the more precise diagnostic. */
441 if (errno == EROFS)
443 struct stat st;
444 if ( ! (lstatat (fts->fts_cwd_fd, ent->fts_accpath, &st)
445 && errno == ENOENT))
446 errno = EROFS;
449 if (ignorable_missing (x, errno))
450 return RM_OK;
452 /* When failing to rmdir an unreadable directory, the typical
453 errno value is EISDIR, but that is not as useful to the user
454 as the errno value from the failed open (probably EPERM).
455 Use the earlier, more descriptive errno value. */
456 if (ent->fts_info == FTS_DNR)
457 errno = ent->fts_errno;
458 error (0, errno, _("cannot remove %s"), quote (ent->fts_path));
459 mark_ancestor_dirs (ent);
460 return RM_ERROR;
463 /* This function is called once for every file system object that fts
464 encounters. fts performs a depth-first traversal.
465 A directory is usually processed twice, first with fts_info == FTS_D,
466 and later, after all of its entries have been processed, with FTS_DP.
467 Return RM_ERROR upon error, RM_USER_DECLINED for a negative response
468 to an interactive prompt, and otherwise, RM_OK. */
469 static enum RM_status
470 rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x)
472 switch (ent->fts_info)
474 case FTS_D: /* preorder directory */
475 if (! x->recursive)
477 /* This is the first (pre-order) encounter with a directory.
478 Not recursive, so arrange to skip contents. */
479 error (0, EISDIR, _("cannot remove %s"), quote (ent->fts_path));
480 mark_ancestor_dirs (ent);
481 fts_skip_tree (fts, ent);
482 return RM_ERROR;
485 /* Perform checks that can apply only for command-line arguments. */
486 if (ent->fts_level == FTS_ROOTLEVEL)
488 if (strip_trailing_slashes (ent->fts_path))
489 ent->fts_pathlen = strlen (ent->fts_path);
491 /* If the basename of a command line argument is "." or "..",
492 diagnose it and do nothing more with that argument. */
493 if (dot_or_dotdot (last_component (ent->fts_accpath)))
495 error (0, 0, _("cannot remove directory: %s"),
496 quote (ent->fts_path));
497 fts_skip_tree (fts, ent);
498 return RM_ERROR;
501 /* If a command line argument resolves to "/" (and --preserve-root
502 is in effect -- default) diagnose and skip it. */
503 if (ROOT_DEV_INO_CHECK (x->root_dev_ino, ent->fts_statp))
505 ROOT_DEV_INO_WARN (ent->fts_path);
506 fts_skip_tree (fts, ent);
507 return RM_ERROR;
512 Ternary is_empty_directory;
513 enum RM_status s = prompt (fts, ent, true /*is_dir*/, x,
514 PA_DESCEND_INTO_DIR, &is_empty_directory);
516 if (s == RM_OK && is_empty_directory == T_YES)
518 /* When we know (from prompt when in interactive mode)
519 that this is an empty directory, don't prompt twice. */
520 s = excise (fts, ent, x, true);
521 fts_skip_tree (fts, ent);
524 if (s != RM_OK)
526 mark_ancestor_dirs (ent);
527 fts_skip_tree (fts, ent);
530 return s;
533 case FTS_F: /* regular file */
534 case FTS_NS: /* stat(2) failed */
535 case FTS_SL: /* symbolic link */
536 case FTS_SLNONE: /* symbolic link without target */
537 case FTS_DP: /* postorder directory */
538 case FTS_DNR: /* unreadable directory */
539 case FTS_NSOK: /* e.g., dangling symlink */
540 case FTS_DEFAULT: /* none of the above */
542 /* With --one-file-system, do not attempt to remove a mount point.
543 fts' FTS_XDEV ensures that we don't process any entries under
544 the mount point. */
545 if (ent->fts_info == FTS_DP
546 && x->one_file_system
547 && FTS_ROOTLEVEL < ent->fts_level
548 && ent->fts_statp->st_dev != fts->fts_dev)
550 mark_ancestor_dirs (ent);
551 error (0, 0, _("skipping %s, since it's on a different device"),
552 quote (ent->fts_path));
553 return RM_ERROR;
556 bool is_dir = ent->fts_info == FTS_DP || ent->fts_info == FTS_DNR;
557 enum RM_status s = prompt (fts, ent, is_dir, x, PA_REMOVE_DIR, NULL);
558 if (s != RM_OK)
559 return s;
560 return excise (fts, ent, x, is_dir);
563 case FTS_DC: /* directory that causes cycles */
564 emit_cycle_warning (ent->fts_path);
565 fts_skip_tree (fts, ent);
566 return RM_ERROR;
568 case FTS_ERR:
569 /* Various failures, from opendir to ENOMEM, to failure to "return"
570 to preceding directory, can provoke this. */
571 error (0, ent->fts_errno, _("traversal failed: %s"),
572 quote (ent->fts_path));
573 fts_skip_tree (fts, ent);
574 return RM_ERROR;
576 default:
577 error (0, 0, _("unexpected failure: fts_info=%d: %s\n"
578 "please report to %s"),
579 ent->fts_info,
580 quote (ent->fts_path),
581 PACKAGE_BUGREPORT);
582 abort ();
586 /* Remove FILEs, honoring options specified via X.
587 Return RM_OK if successful. */
588 enum RM_status
589 rm (char *const *file, struct rm_options const *x)
591 enum RM_status rm_status = RM_OK;
593 if (*file)
595 int bit_flags = (FTS_CWDFD
596 | FTS_NOSTAT
597 | FTS_PHYSICAL);
599 if (x->one_file_system)
600 bit_flags |= FTS_XDEV;
602 FTS *fts = xfts_open (file, bit_flags, NULL);
604 while (1)
606 FTSENT *ent;
608 ent = fts_read (fts);
609 if (ent == NULL)
611 if (errno != 0)
613 error (0, errno, _("fts_read failed"));
614 rm_status = RM_ERROR;
616 break;
619 enum RM_status s = rm_fts (fts, ent, x);
621 assert (VALID_STATUS (s));
622 UPDATE_STATUS (rm_status, s);
625 if (fts_close (fts) != 0)
627 error (0, errno, _("fts_close failed"));
628 rm_status = RM_ERROR;
632 return rm_status;